Tag v1.4.0.


git-svn-id: https://svn.apache.org/repos/asf/apr/apr-util/tags/1.4.0@1210733 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES b/CHANGES
index 37981a9..fa3316d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,16 @@
                                                      -*- coding: utf-8 -*-
 Changes with APR-util 1.4.0
 
+  *) apr_ldap_init: Pass secure=1 to ldapssl_init() with Solaris LDAP SDK.
+     PR: 42682 [Stefan Fritsch]
+
+  *) apr_memcache_server_create: Fix possible segfault. PR 51064.
+     [Michajlo Matijkiw <michajlo_matijkiw comcast com>]
+
+  *) apr_thread_pool: Fix thread unsafe pool usage. [Stefan Fritsch]
+
   *) Do not include apr.h and apr_errno.h from system search path in
-     apu_errno.h. PR 46487 [Rainer Jung <rainer.jung kippdata.de>]
+     apu_errno.h. PR 46487 [Rainer Jung]
 
   *) Add optional dbm, openssl and nss subpackages to the RPM spec file.
      [Graham Leggett]
@@ -22,8 +30,9 @@
      access to basic crypto using the native crypto libraries present on
      each platform.  [Graham Leggett]
 
-  *) Add DTrace Probes to Hooks, making it easier to inspect APR Hook based
-     applications with DTrace. [Theo Schlossnagle <jesus omniti.com>]
+  *) Add trace probes to hooks, making it easier to inspect APR Hook based
+     applications with DTrace or other such mechanisms.
+     [Theo Schlossnagle <jesus omniti.com>, generalized by Jeff Trawick]
 
   *) Implement resource list when threads are unavailable. PR 24325
      [Bojan Smojver]
diff --git a/NOTICE b/NOTICE
index c1dab46..aaf9cd0 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Portable Runtime Utility Library
-Copyright (c) 2009 The Apache Software Foundation.
+Copyright (c) 2011 The Apache Software Foundation.
 
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/NWGNUmakefile b/NWGNUmakefile
index f6d079e..42a4212 100644
--- a/NWGNUmakefile
+++ b/NWGNUmakefile
@@ -24,7 +24,7 @@
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # Make sure all needed macro's are defined
@@ -37,11 +37,11 @@
 XINCDIRS	+= \
 			$(APR)/include \
 			$(APR)/include/arch/NetWare \
-			$(APRUTIL)/include \
-			$(APRUTIL)/uri \
-			$(APRUTIL)/dbm/sdbm \
-			$(APRUTIL)/include/private \
-			$(APRUTIL)/xml/expat/lib \
+			$(APU)/include \
+			$(APU)/uri \
+			$(APU)/dbm/sdbm \
+			$(APU)/include/private \
+			$(APUXML)/expat/lib \
 			$(LDAPSDK)/inc \
 			$(EOLIST)
 
@@ -129,7 +129,7 @@
 NLM_THREAD_NAME	=
 #
 # If this is specified, it will override VERSION value in
-# $(APR_WORK)\build\NWGNUenvironment.inc
+# $(APR_WORK)/build/NWGNUenvironment.inc
 #
 NLM_VERSION	=
 
@@ -179,7 +179,7 @@
 # If there is an LIB target, put it here
 #
 TARGET_lib = \
-	$(OBJDIR)/aprutil.lib \
+	$(OBJDIR)/apulib.lib \
 	$(EOLIST)
 
 #
@@ -249,6 +249,7 @@
 	$(OBJDIR)/apr_buckets_refcount.o \
 	$(OBJDIR)/apr_buckets_simple.o \
 	$(OBJDIR)/apr_buckets_socket.o \
+	$(OBJDIR)/apr_crypto.o \
 	$(OBJDIR)/apr_date.o \
 	$(OBJDIR)/apr_dbm.o \
 	$(OBJDIR)/apr_dbd.o \
@@ -285,7 +286,7 @@
 
 #
 # Updated this target to create necessary directories and copy files to the
-# correct place.  (See $(APR_WORK)\build\NWGNUhead.inc for examples)
+# correct place.  (See $(APR_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
 
@@ -300,6 +301,6 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
diff --git a/README b/README
index 39d1890..3a68569 100644
--- a/README
+++ b/README
@@ -98,6 +98,12 @@
 The following provides more details on the included cryptographic
 software:
 
+  APR-Util provides an abstract interface for symmetrical cryptographic
+  functions that make use of a general-purpose encryption library,
+  such as OpenSSL, NSS, or the operating system's platform-specific
+  facilities. This interface is known as the apr_crypto interface,
+  with implementation beneath the /crypto directory.
+
   APR-Util provides an abstract interface for SSL encrypted LDAP (ldaps
   and STARTTLS style) connections, which can be powered by OpenLDAP, 
   Netscape LDAP SDK, Mozilla LDAP SDK, or other platform specific ldap
diff --git a/STATUS b/STATUS
index c7f7c38..6ff7788 100644
--- a/STATUS
+++ b/STATUS
@@ -2,9 +2,18 @@
 Last modified at [$Date$]
 
 Releases:
-    2.0.0     : in development on trunk/
-    1.4.0     : in development on branches/1.4.x/
-    1.3.1     : in maintenance on branches/1.3.x/
+    2.0.0     : None/EOL - merged into apr/trunk/
+    1.5.0     : in development on branches/1.5.x/
+    1.4.0     : tagged December 6, 2011
+    1.3.9     : released August 5, 2009
+    1.3.8     : released July 6, 2009
+    1.3.7     : released June 5, 2009
+    1.3.6     : not released
+    1.3.5     : not released
+    1.3.4     : released August 15, 2008
+    1.3.3     : not released
+    1.3.2     : released June 23, 2008
+    1.3.1     : not released
     1.3.0     : released June 3, 2008
     1.2.12    : released November 25, 2007
     1.2.11    : not released
diff --git a/apu-config.in b/apu-config.in
index 2b663b4..e181e44 100644
--- a/apu-config.in
+++ b/apu-config.in
@@ -86,7 +86,7 @@
 if test "$location" = "installed"; then
     LA_FILE="$libdir/lib${APRUTIL_LIBNAME}.la"
 
-    LIBS=`echo "$LIBS" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g" -e "s $prefix/lib/libexpat.la -lexpat g"`
+    LIBS=`echo "$LIBS" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g" -e "s $prefix/libexpat.la -lexpat g"`
     LDFLAGS=`echo "$LDFLAGS" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g"`
     INCLUDES=`echo "$INCLUDES" | sed -e "s $APU_BUILD_DIR/xml/expat $prefix g" -e "s -I$prefix/lib  g"`
 else
diff --git a/buckets/apr_brigade.c b/buckets/apr_brigade.c
index 77adeff..3fd7e46 100644
--- a/buckets/apr_brigade.c
+++ b/buckets/apr_brigade.c
@@ -331,7 +331,18 @@
             return APR_SUCCESS;
         }
         APR_BUCKET_REMOVE(e);
-        APR_BRIGADE_INSERT_TAIL(bbOut, e);
+        if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) {
+            APR_BRIGADE_INSERT_TAIL(bbOut, e);
+        }
+        else {
+            if (len > 0) {
+                rv = apr_brigade_write(bbOut, NULL, NULL, str, len);
+                if (rv != APR_SUCCESS) {
+                    return rv;
+                }
+            }
+            apr_bucket_destroy(e);
+        }
         readbytes += len;
         /* We didn't find an APR_ASCII_LF within the maximum line length. */
         if (readbytes >= maxbytes) {
diff --git a/buckets/apr_buckets_file.c b/buckets/apr_buckets_file.c
index 214b53d..0644cd8 100644
--- a/buckets/apr_buckets_file.c
+++ b/buckets/apr_buckets_file.c
@@ -93,14 +93,14 @@
 #endif
 
 #if APR_HAS_THREADS && !APR_HAS_XTHREAD_FILES
-    if ((flags = apr_file_flags_get(f)) & APR_XTHREAD) {
+    if ((flags = apr_file_flags_get(f)) & APR_FOPEN_XTHREAD) {
         /* this file descriptor is shared across multiple threads and
          * this OS doesn't support that natively, so as a workaround
          * we must reopen the file into a->readpool */
         const char *fname;
         apr_file_name_get(&fname, f);
 
-        rv = apr_file_open(&f, fname, (flags & ~APR_XTHREAD), 0, a->readpool);
+        rv = apr_file_open(&f, fname, (flags & ~APR_FOPEN_XTHREAD), 0, a->readpool);
         if (rv != APR_SUCCESS)
             return rv;
 
diff --git a/build.conf b/build.conf
index 226aabe..98696bd 100644
--- a/build.conf
+++ b/build.conf
@@ -93,8 +93,8 @@
 target = dbm/apr_dbm_ndbm.la
 
 [ldap]
-paths = ldap/apr_ldap_init.c \
-        ldap/apr_ldap_option.c \
+paths = ldap/apr_ldap_init.c
+        ldap/apr_ldap_option.c
         ldap/apr_ldap_rebind.c
 target = ldap/apr_ldap.la
 
diff --git a/build/apu-conf.m4 b/build/apu-conf.m4
index d1bad6d..8fc3da1 100644
--- a/build/apu-conf.m4
+++ b/build/apu-conf.m4
@@ -164,9 +164,9 @@
   dnl we are working with the bundled version of the software.
   bundled_subdir="xml/expat"
   APR_SUBDIR_CONFIG($bundled_subdir, [--prefix=$prefix --exec-prefix=$exec_prefix --libdir=$libdir --includedir=$includedir --bindir=$bindir])
-  APR_ADDTO(APRUTIL_INCLUDES, [-I$top_builddir/$bundled_subdir/lib])
+  APR_ADDTO(APRUTIL_INCLUDES, [-I$abs_srcdir/$bundled_subdir/lib])
   APR_ADDTO(LDFLAGS, [-L$top_builddir/$bundled_subdir/lib])
-  apu_expat_libs="$top_builddir/$bundled_subdir/lib/libexpat.la"
+  apu_expat_libs="$top_builddir/$bundled_subdir/libexpat.la"
 fi
 
 APR_ADDTO(APRUTIL_EXPORT_LIBS, [$apu_expat_libs])
@@ -391,9 +391,7 @@
     #include <ldap.h>
     #endif
     ], [
-    int tmp = ldap_set_rebind_proc((LDAP *)0, (LDAP_REBIND_PROC *)0, (void *)0);
-    /* use tmp to suppress the warning */
-    tmp=0;
+    ldap_set_rebind_proc((LDAP *)0, (LDAP_REBIND_PROC *)0, (void *)0);
     ], ac_cv_ldap_set_rebind_proc_style=three, ac_cv_ldap_set_rebind_proc_style=two))
 
     if test "$ac_cv_ldap_set_rebind_proc_style" = "three"; then
diff --git a/build/crypto.m4 b/build/crypto.m4
index 71c55f8..e9a65c9 100644
--- a/build/crypto.m4
+++ b/build/crypto.m4
@@ -163,7 +163,7 @@
       apu_have_nss=0
     elif test "x$withval" != "x"; then
 
-      nss_CPPFLAGS="-I$withval/include -I$withval/../public"
+      nss_CPPFLAGS="-I$withval/include/nss -I$withval/include/nss3 -I$withval/include/nspr -I$withval/include/nspr4 -I$withval/include -I$withval/../public"
       nss_LDFLAGS="-L$withval/lib "
 
       APR_ADDTO(CPPFLAGS, [$nss_CPPFLAGS])
diff --git a/build/dbd.m4 b/build/dbd.m4
index bb0e424..d418d8b 100644
--- a/build/dbd.m4
+++ b/build/dbd.m4
@@ -505,8 +505,14 @@
         odbc_LDFLAGS="-L`$ODBC_CONFIG --lib-prefix`"
         odbc_LIBS="`$ODBC_CONFIG --libs`"
       else
-        odbc_CPPFLAGS="-I$withval/include"
-        odbc_LDFLAGS="-L$withval/lib "
+        if test -f "$withval" && test -x "$withval"; then 
+          odbc_CPPFLAGS="-I`$withval --include-prefix`"
+          odbc_LDFLAGS="-L`$withval --lib-prefix`"
+          odbc_LIBS="`$withval --libs`"
+        else
+          odbc_CPPFLAGS="-I$withval/include"
+          odbc_LDFLAGS="-L$withval/lib "
+        fi
       fi
 
       APR_ADDTO(CPPFLAGS, [$odbc_CPPFLAGS])
diff --git a/build/dbm.m4 b/build/dbm.m4
index b9eed8c..1b229f4 100644
--- a/build/dbm.m4
+++ b/build/dbm.m4
@@ -112,7 +112,7 @@
         changequote([,])
         unset $cache_id
         AC_CHECK_HEADER([$bdb_header], [
-          if test "$1" = "3" -o "$1" = "4"; then
+          if test "$1" = "3" -o "$1" = "4" -o "$1" = "5"; then
             # We generate a separate cache variable for each prefix and libname
             # we search under.  That way, we avoid caching information that
             # changes if the user runs `configure' with a different set of
@@ -541,6 +541,44 @@
     apu_db_version=4
   fi
 ])
+dnl
+dnl APU_CHECK_DB50: is DB5.0 present?
+dnl
+dnl if present: sets apu_db_header, apu_db_lib, and apu_db_version
+dnl
+AC_DEFUN([APU_CHECK_DB50], [
+  places=$1
+  if test -z "$places"; then
+    places="std /usr/local/BerkeleyDB.5.0 /boot/home/config"
+  fi
+  APU_CHECK_BERKELEY_DB("5", "0", "-1",
+    "$places",
+    "db50/db.h db5/db.h db.h",
+    "db-5.0 db5-5.0 db50 db5 db"
+  )
+  if test "$apu_have_db" = "1"; then
+    apu_db_version=5
+  fi
+])
+dnl
+dnl APU_CHECK_DB51: is DB5.1 present?
+dnl
+dnl if present: sets apu_db_header, apu_db_lib, and apu_db_version
+dnl
+AC_DEFUN([APU_CHECK_DB51], [
+  places=$1
+  if test -z "$places"; then
+    places="std /usr/local/BerkeleyDB.5.1 /boot/home/config"
+  fi
+  APU_CHECK_BERKELEY_DB("5", "1", "-1",
+    "$places",
+    "db51/db.h db5/db.h db.h",
+    "db-5.1 db5-5.1 db51 db5 db"
+  )
+  if test "$apu_have_db" = "1"; then
+    apu_db_version=5
+  fi
+])
 
 AC_DEFUN([APU_CHECK_DB], [
   requested=$1
@@ -631,6 +669,18 @@
       AC_MSG_ERROR(Berkeley db4 not found)
     fi
     ;;
+  db50)
+    APU_CHECK_DB50("$check_places")
+    if test "$apu_db_version" != "5"; then
+      AC_MSG_ERROR(Berkeley db5 not found)
+    fi
+    ;;
+  db51)
+    APU_CHECK_DB51("$check_places")
+    if test "$apu_db_version" != "5"; then
+      AC_MSG_ERROR(Berkeley db5 not found)
+    fi
+    ;;
   default)
     APU_CHECK_DB_ALL("$check_places")
     ;;
@@ -638,36 +688,42 @@
 ])
 
 dnl
-dnl APU_CHECK_DB_ALL: Try all Berkeley DB versions, from 4.8 to 1.
+dnl APU_CHECK_DB_ALL: Try all Berkeley DB versions, from 5.1 to 1.
 dnl
 AC_DEFUN([APU_CHECK_DB_ALL], [
   all_places=$1
  
-  APU_CHECK_DB48("$all_places")
-  if test "$apu_db_version" != "4"; then
-    APU_CHECK_DB47("$all_places")
-    if test "$apu_db_version" != "4"; then
-      APU_CHECK_DB46("$all_places")
+  APU_CHECK_DB51("$all_places")
+  if test "$apu_db_version" != "5"; then
+    APU_CHECK_DB50("$all_places")
+    if test "$apu_db_version" != "5"; then
+      APU_CHECK_DB48("$all_places")
       if test "$apu_db_version" != "4"; then
-        APU_CHECK_DB45("$all_places")
+        APU_CHECK_DB47("$all_places")
         if test "$apu_db_version" != "4"; then
-          APU_CHECK_DB44("$all_places")
+          APU_CHECK_DB46("$all_places")
           if test "$apu_db_version" != "4"; then
-            APU_CHECK_DB43("$all_places")
+            APU_CHECK_DB45("$all_places")
             if test "$apu_db_version" != "4"; then
-              APU_CHECK_DB42("$all_places")
+              APU_CHECK_DB44("$all_places")
               if test "$apu_db_version" != "4"; then
-                APU_CHECK_DB41("$all_places")
+                APU_CHECK_DB43("$all_places")
                 if test "$apu_db_version" != "4"; then
-                  APU_CHECK_DB4("$all_places")
+                  APU_CHECK_DB42("$all_places")
                   if test "$apu_db_version" != "4"; then
-                    APU_CHECK_DB3("$all_places")
-                    if test "$apu_db_version" != "3"; then
-                      APU_CHECK_DB2("$all_places")
-                      if test "$apu_db_version" != "2"; then
-                        APU_CHECK_DB1("$all_places")
-                        if test "$apu_db_version" != "1"; then
-                          APU_CHECK_DB185("$all_places")
+                    APU_CHECK_DB41("$all_places")
+                    if test "$apu_db_version" != "4"; then
+                      APU_CHECK_DB4("$all_places")
+                      if test "$apu_db_version" != "4"; then
+                        APU_CHECK_DB3("$all_places")
+                        if test "$apu_db_version" != "3"; then
+                          APU_CHECK_DB2("$all_places")
+                          if test "$apu_db_version" != "2"; then
+                            APU_CHECK_DB1("$all_places")
+                            if test "$apu_db_version" != "1"; then
+                              APU_CHECK_DB185("$all_places")
+                            fi
+                          fi
                         fi
                       fi
                     fi
@@ -707,11 +763,11 @@
   apu_db_version=0
 
   AC_ARG_WITH(dbm, [APR_HELP_STRING([--with-dbm=DBM], [choose the DBM type to use.
-      DBM={sdbm,gdbm,ndbm,db,db1,db185,db2,db3,db4,db41,db42,db43,db44,db45,db46,db47,db48}])],
+      DBM={sdbm,gdbm,ndbm,db,db1,db185,db2,db3,db4,db41,db42,db43,db44,db45,db46,db47,db48,db50,db51}])],
   [
     if test "$withval" = "yes"; then
       AC_MSG_ERROR([--with-dbm needs to specify a DBM type to use.
-        One of: sdbm, gdbm, ndbm, db, db1, db185, db2, db3, db4, db41, db42, db43, db44, db45, db46, db47, db48])
+        One of: sdbm, gdbm, ndbm, db, db1, db185, db2, db3, db4, db41, db42, db43, db44, db45, db46, db47, db48, db50, db51])
     fi
     requested="$withval"
   ], [
@@ -914,6 +970,14 @@
       apu_use_db=1
       apu_default_dbm=db4
       ;;
+    db50)
+      apu_use_db=1
+      apu_default_dbm=db5
+      ;;
+    db51)
+      apu_use_db=1
+      apu_default_dbm=db5
+      ;;
     default)
       dnl ### use more sophisticated DBMs for the default?
       apu_default_dbm="sdbm (default)"
@@ -921,7 +985,7 @@
       ;;
     *)
       AC_MSG_ERROR([--with-dbm=$look_for is an unknown DBM type.
-        Use one of: sdbm, gdbm, ndbm, db, db1, db185, db2, db3, db4, db41, db42, db43, db44, db45, db46, db47, db48])
+        Use one of: sdbm, gdbm, ndbm, db, db1, db185, db2, db3, db4, db41, db42, db43, db44, db45, db46, db47, db48, db50, db51])
       ;;
   esac
 
diff --git a/build/find_apu.m4 b/build/find_apu.m4
index dfa4e0e..7937e00 100644
--- a/build/find_apu.m4
+++ b/build/find_apu.m4
@@ -185,7 +185,7 @@
     fi
     dnl if we have not found anything yet and have bundled source, use that
     if test "$apu_found" = "no" && test -d "$1"; then
-      apu_temp_abs_srcdir="`cd $1 && pwd`"
+      apu_temp_abs_srcdir="`cd \"$1\" && pwd`"
       apu_found="reconfig"
       apu_bundled_major="`sed -n '/#define.*APU_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apu_version.h\"`"
       case $apu_bundled_major in
diff --git a/build/nw_apu_export.inc b/build/nw_apu_export.inc
index 218ecd9..e883b1c 100644
--- a/build/nw_apu_export.inc
+++ b/build/nw_apu_export.inc
@@ -12,9 +12,11 @@
 #include "apr_anylock.h"
 #include "apr_base64.h"
 #include "apr_buckets.h"
+#include "apr_crypto.h"
 #include "apr_date.h"
 #include "apr_dbd.h"
 #include "apr_dbm.h"
+#include "apr_dbm_private.h"
 #include "apr_hooks.h"
 #include "apr_ldap.h"
 #include "apr_ldap_init.h"
diff --git a/build/rpm/apr-util.spec.in b/build/rpm/apr-util.spec.in
index 2da91ba..bc6be9a 100644
--- a/build/rpm/apr-util.spec.in
+++ b/build/rpm/apr-util.spec.in
@@ -10,8 +10,8 @@
 URL: http://apr.apache.org/
 Source0: http://www.apache.org/dist/apr/%{name}-%{version}.tar.bz2
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
-BuildPrereq: autoconf, libtool, doxygen, apr-devel >= 1.3.0
-BuildPrereq: expat-devel
+BuildRequires: autoconf, libtool, doxygen, apr-devel >= 1.4.0
+BuildRequires: expat-devel, libuuid-devel
 
 %description
 The mission of the Apache Portable Runtime (APR) is to provide a
diff --git a/buildconf b/buildconf
index cb4ae46..5d6536f 100755
--- a/buildconf
+++ b/buildconf
@@ -17,6 +17,11 @@
 #
 #
 
+if [ "$1" = "--verbose" -o "$1" = "-v" ]; then
+    verbose="--verbose"
+    shift
+fi
+
 # Default place to look for apr source.  Can be overridden with 
 #   --with-apr=[directory]
 apr_src_dir=../apr
@@ -67,11 +72,11 @@
 # Generate the autoconf header (include/apu_config.h) and ./configure
 #
 echo "Creating include/private/apu_config.h ..."
-${AUTOHEADER:-autoheader}
+${AUTOHEADER:-autoheader} $verbose
 
 echo "Creating configure ..."
 ### do some work to toss config.cache?
-if ${AUTOCONF:-autoconf}; then
+if ${AUTOCONF:-autoconf} $verbose; then
   :
 else
   echo "autoconf failed"
@@ -82,14 +87,14 @@
 # Generate build-outputs.mk for the build system
 #
 echo "Generating 'make' outputs ..."
-$apr_src_dir/build/gen-build.py make
+$apr_src_dir/build/gen-build.py $verbose make
 
 #
 # If Expat has been bundled, then go and configure the thing
 #
 if [ -f xml/expat/buildconf.sh ]; then
   echo "Invoking xml/expat/buildconf.sh ..."
-  (cd xml/expat; ./buildconf.sh)
+  (cd xml/expat; ./buildconf.sh $verbose)
 fi
 
 # Remove autoconf cache again
diff --git a/configure.in b/configure.in
index c8d3a74..3aff513 100644
--- a/configure.in
+++ b/configure.in
@@ -2,7 +2,7 @@
 dnl Process this file with autoconf to produce a configure script
 dnl
 
-AC_PREREQ(2.50)
+AC_PREREQ(2.59)
 AC_INIT(export_vars.sh.in)
 
 AC_CONFIG_HEADER(include/private/apu_config.h)
@@ -165,22 +165,6 @@
 APU_FIND_EXPAT
 APU_FIND_ICONV
 
-AC_CHECK_HEADERS( \
-sys/sdt.h
-)
-
-AC_ARG_ENABLE(dtrace,APR_HELP_STRING(--enable-dtrace, Enable DTrace probes),
-[
-  enable_dtrace=$enableval
-],
-[
-  enable_dtrace=no
-])
-
-if test $enable_dtrace = "yes" -a "$ac_cv_header_sys_sdt_h" = "yes"; then
-    APR_ADDTO(CPPFLAGS, -DAPR_DTRACE_PROVIDER)
-fi
-
 dnl Enable DSO build; must be last:
 APU_CHECK_UTIL_DSO
 
diff --git a/crypto/apr_crypto.c b/crypto/apr_crypto.c
index ef84310..2ca391a 100644
--- a/crypto/apr_crypto.c
+++ b/crypto/apr_crypto.c
@@ -19,7 +19,6 @@
 
 #include "apu_config.h"
 #include "apu.h"
-
 #include "apr_pools.h"
 #include "apr_dso.h"
 #include "apr_strings.h"
@@ -40,6 +39,34 @@
 
 #define CLEANUP_CAST (apr_status_t (*)(void*))
 
+#define APR_TYPEDEF_STRUCT(type, incompletion) \
+struct type { \
+   incompletion \
+   void *unk[]; \
+};
+
+APR_TYPEDEF_STRUCT(apr_crypto_t,
+    apr_pool_t *pool;
+    apr_crypto_driver_t *provider;
+)
+
+APR_TYPEDEF_STRUCT(apr_crypto_key_t,
+    apr_pool_t *pool;
+    apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
+)
+
+APR_TYPEDEF_STRUCT(apr_crypto_block_t,
+    apr_pool_t *pool;
+    apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
+)
+
+typedef struct apr_crypto_clear_t {
+    void *buffer;
+    apr_size_t size;
+} apr_crypto_clear_t;
+
 #if !APU_DSO_BUILD
 #define DRIVER_LOAD(name,driver,pool,params) \
     {   \
@@ -51,7 +78,8 @@
     }
 #endif
 
-static apr_status_t apr_crypto_term(void *ptr) {
+static apr_status_t apr_crypto_term(void *ptr)
+{
     /* set drivers to NULL so init can work again */
     drivers = NULL;
 
@@ -61,8 +89,8 @@
     return APR_SUCCESS;
 }
 
-APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool,
-        const apr_array_header_t *params) {
+APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool)
+{
     apr_status_t ret = APR_SUCCESS;
     apr_pool_t *parent;
 
@@ -101,9 +129,35 @@
     return ret;
 }
 
-APU_DECLARE(apr_status_t) apr_crypto_get_driver(apr_pool_t *pool, const char *name,
-        const apr_crypto_driver_t **driver, const apr_array_header_t *params,
-        const apu_err_t **result) {
+static apr_status_t crypto_clear(void *ptr)
+{
+    apr_crypto_clear_t *clear = (apr_crypto_clear_t *)ptr;
+
+    memset(clear->buffer, 0, clear->size);
+    clear->buffer = NULL;
+    clear->size = 0;
+
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool,
+        void *buffer, apr_size_t size)
+{
+    apr_crypto_clear_t *clear = apr_palloc(pool, sizeof(apr_crypto_clear_t));
+
+    clear->buffer = buffer;
+    clear->size = size;
+
+    apr_pool_cleanup_register(pool, clear, crypto_clear,
+            apr_pool_cleanup_null);
+
+    return APR_SUCCESS;
+}
+
+APU_DECLARE(apr_status_t) apr_crypto_get_driver(
+        const apr_crypto_driver_t **driver, const char *name,
+        const char *params, const apu_err_t **result, apr_pool_t *pool)
+{
 #if APU_DSO_BUILD
     char modname[32];
     char symname[34];
@@ -121,7 +175,7 @@
 #endif
     *driver = apr_hash_get(drivers, name, APR_HASH_KEY_STRING);
     if (*driver) {
-#if APU_DSO_BUILD
+#if APU_DSO_BUILD 
         apu_dso_mutex_unlock();
 #endif
         return APR_SUCCESS;
@@ -138,7 +192,8 @@
     apr_snprintf(modname, sizeof(modname),
             "apr_crypto_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".dll", name);
 #else
-    apr_snprintf(modname, sizeof(modname), "apr_crypto_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".so", name);
+    apr_snprintf(modname, sizeof(modname),
+            "apr_crypto_%s-" APU_STRINGIFY(APU_MAJOR_VERSION) ".so", name);
 #endif
     apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name);
     rv = apu_dso_load(&dso, &symbol, modname, symname, pool);
@@ -181,36 +236,75 @@
 /**
  * @brief Return the name of the driver.
  *
- * @param pool - pool to register any shutdown cleanups, etc
- * @return APR_SUCCESS for success.
+ * @param driver - The driver in use.
+ * @return The name of the driver.
  */
-APU_DECLARE(const char *)apr_crypto_driver_name (const apr_crypto_driver_t *driver)
+APU_DECLARE(const char *)apr_crypto_driver_name (
+        const apr_crypto_driver_t *driver)
 {
     return driver->name;
 }
 
 /**
- * @brief Get the result of a previous operation on this context.
- * @param pool - process pool
- * @param params - array of key parameters
- * @param factory - factory pointer will be written here
+ * @brief Get the result of the last operation on a context. If the result
+ *        is NULL, the operation was successful.
+ * @param result - the result structure
+ * @param f - context pointer
+ * @return APR_SUCCESS for success
  */
-APU_DECLARE(apr_status_t) apr_crypto_error(const apr_crypto_t *f,
-        const apu_err_t **result) {
-    *result = f->result;
-    return APR_SUCCESS;
+APU_DECLARE(apr_status_t) apr_crypto_error(const apu_err_t **result,
+        const apr_crypto_t *f)
+{
+    return f->provider->error(result, f);
 }
 
 /**
- * @brief Create a general encryption context
+ * @brief Create a context for supporting encryption. Keys, certificates,
+ *        algorithms and other parameters will be set per context. More than
+ *        one context can be created at one time. A cleanup will be automatically
+ *        registered with the given pool to guarantee a graceful shutdown.
+ * @param f - context pointer will be written here
  * @param driver - driver to use
- * @param pool - process pool
  * @param params - array of key parameters
- * @param factory - factory pointer will be written here
+ * @param pool - process pool
+ * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
+ * if the engine cannot be initialised.
+ * @remarks NSS: currently no params are supported.
+ * @remarks OpenSSL: the params can have "engine" as a key, followed by an equal
+ *  sign and a value.
  */
-APU_DECLARE(apr_status_t) apr_crypto_factory(const apr_crypto_driver_t *driver,
-        apr_pool_t *pool, const apr_array_header_t *params, apr_crypto_t **f) {
-    return driver->factory(pool, params, f);
+APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f,
+        const apr_crypto_driver_t *driver, const char *params, apr_pool_t *pool)
+{
+    return driver->make(f, driver, params, pool);
+}
+
+/**
+ * @brief Get a hash table of key types, keyed by the name of the type against
+ * an integer pointer constant.
+ *
+ * @param types - hashtable of key types keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
+        const apr_crypto_t *f)
+{
+    return f->provider->get_block_key_types(types, f);
+}
+
+/**
+ * @brief Get a hash table of key modes, keyed by the name of the mode against
+ * an integer pointer constant.
+ *
+ * @param modes - hashtable of key modes keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
+        const apr_crypto_t *f)
+{
+    return f->provider->get_block_key_modes(modes, f);
 }
 
 /**
@@ -222,9 +316,9 @@
  *        operations.
  * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
  *       *key is not NULL, *key must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The context to use.
+ * @param key The key returned, see note.
+ * @param ivSize The size of the initialisation vector will be returned, based
+ *               on whether an IV is relevant for this type of crypto.
  * @param pass The passphrase to use.
  * @param passLen The passphrase length in bytes
  * @param salt The salt to use.
@@ -232,49 +326,47 @@
  * @param type 3DES_192, AES_128, AES_192, AES_256.
  * @param mode Electronic Code Book / Cipher Block Chaining.
  * @param doPad Pad if necessary.
- * @param key The key returned, see note.
- * @param ivSize The size of the initialisation vector will be returned, based
- *               on whether an IV is relevant for this type of crypto.
+ * @param iterations Number of iterations to use in algorithm
+ * @param f The context to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
  *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
  *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
  *         not known. APR_EPADDING if padding was requested but is not supported.
  *         APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_passphrase(const apr_crypto_driver_t *driver,
-        apr_pool_t *p, const apr_crypto_t *f, const char *pass,
-        apr_size_t passLen, const unsigned char * salt, apr_size_t saltLen,
+APU_DECLARE(apr_status_t) apr_crypto_passphrase(apr_crypto_key_t **key,
+        apr_size_t *ivSize, const char *pass, apr_size_t passLen,
+        const unsigned char * salt, apr_size_t saltLen,
         const apr_crypto_block_key_type_e type,
         const apr_crypto_block_key_mode_e mode, const int doPad,
-        const int iterations, apr_crypto_key_t **key, apr_size_t *ivSize) {
-    return driver->passphrase(p, f, pass, passLen, salt, saltLen, type, mode,
-            doPad, iterations, key, ivSize);
+        const int iterations, const apr_crypto_t *f, apr_pool_t *p)
+{
+    return f->provider->passphrase(key, ivSize, pass, passLen, salt, saltLen,
+            type, mode, doPad, iterations, f, p);
 }
 
 /**
  * @brief Initialise a context for encrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure to use.
+ * @param ctx The block context returned, see note.
  * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
  *           an IV will be created at random, in space allocated from the pool.
  *           If the buffer pointed to is not NULL, the IV in the buffer will be
  *           used.
- * @param ctx The block context returned, see note.
+ * @param key The key structure to use.
  * @param blockSize The block size of the cipher.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
 APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_init(
-        const apr_crypto_driver_t *driver, apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char **iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize) {
-    return driver->block_encrypt_init(p, f, key, iv, ctx, blockSize);
+        apr_crypto_block_t **ctx, const unsigned char **iv,
+        const apr_crypto_key_t *key, apr_size_t *blockSize, apr_pool_t *p)
+{
+    return key->provider->block_encrypt_init(ctx, iv, key, blockSize, p);
 }
 
 /**
@@ -286,21 +378,20 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_encrypt(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen) {
-    return driver->block_encrypt(ctx, out, outlen, in, inlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_encrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx)
+{
+    return ctx->provider->block_encrypt(out, outlen, in, inlen, ctx);
 }
 
 /**
@@ -311,44 +402,40 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_encrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_finish(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen) {
-    return driver->block_encrypt_finish(ctx, out, outlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx)
+{
+    return ctx->provider->block_encrypt_finish(out, outlen, ctx);
 }
 
 /**
  * @brief Initialise a context for decrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure to use.
- * @param iv Optional initialisation vector.
  * @param ctx The block context returned, see note.
  * @param blockSize The block size of the cipher.
+ * @param iv Optional initialisation vector.
+ * @param key The key structure to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
 APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_init(
-        const apr_crypto_driver_t *driver, apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char *iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize) {
-    return driver->block_decrypt_init(p, f, key, iv, ctx, blockSize);
+        apr_crypto_block_t **ctx, apr_size_t *blockSize,
+        const unsigned char *iv, const apr_crypto_key_t *key, apr_pool_t *p)
+{
+    return key->provider->block_decrypt_init(ctx, blockSize, iv, key, p);
 }
 
 /**
@@ -360,21 +447,20 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_decrypt(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen) {
-    return driver->block_decrypt(ctx, out, outlen, in, inlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_decrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx)
+{
+    return ctx->provider->block_decrypt(out, outlen, in, inlen, ctx);
 }
 
 /**
@@ -385,57 +471,53 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_decrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_finish(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen) {
-    return driver->block_decrypt_finish(ctx, out, outlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx)
+{
+    return ctx->provider->block_decrypt_finish(out, outlen, ctx);
 }
 
 /**
  * @brief Clean encryption / decryption context.
  * @note After cleanup, a context is free to be reused if necessary.
- * @param driver - driver to use
  * @param ctx The block context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_cleanup(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx) {
-    return driver->block_cleanup(ctx);
+APU_DECLARE(apr_status_t) apr_crypto_block_cleanup(apr_crypto_block_t *ctx)
+{
+    return ctx->provider->block_cleanup(ctx);
 }
 
 /**
- * @brief Clean encryption / decryption factory.
- * @note After cleanup, a factory is free to be reused if necessary.
- * @param driver - driver to use
- * @param f The factory to use.
+ * @brief Clean encryption / decryption context.
+ * @note After cleanup, a context is free to be reused if necessary.
+ * @param f The context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_cleanup(const apr_crypto_driver_t *driver,
-        apr_crypto_t *f) {
-    return driver->cleanup(f);
+APU_DECLARE(apr_status_t) apr_crypto_cleanup(apr_crypto_t *f)
+{
+    return f->provider->cleanup(f);
 }
 
 /**
  * @brief Shutdown the crypto library.
  * @note After shutdown, it is expected that the init function can be called again.
  * @param driver - driver to use
- * @param p The pool to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_shutdown(const apr_crypto_driver_t *driver,
-        apr_pool_t *p) {
-    return driver->shutdown(p);
+APU_DECLARE(apr_status_t) apr_crypto_shutdown(const apr_crypto_driver_t *driver)
+{
+    return driver->shutdown();
 }
 
 #endif /* APU_HAVE_CRYPTO */
diff --git a/crypto/apr_crypto_nss.c b/crypto/apr_crypto_nss.c
index 89ba127..d594542 100644
--- a/crypto/apr_crypto_nss.c
+++ b/crypto/apr_crypto_nss.c
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
+#include "apr_lib.h"
 #include "apu.h"
-
 #include "apu_config.h"
 #include "apu_errno.h"
 
@@ -46,10 +46,23 @@
 #include <pk11pub.h>
 #endif
 
+struct apr_crypto_t {
+    apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    apu_err_t *result;
+    apr_array_header_t *keys;
+    apr_crypto_config_t *config;
+    apr_hash_t *types;
+    apr_hash_t *modes;
+};
+
 struct apr_crypto_config_t {
 };
 
 struct apr_crypto_key_t {
+    apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
     CK_MECHANISM_TYPE cipherMech;
     SECOidTag cipherOid;
     PK11SymKey *symKey;
@@ -57,20 +70,38 @@
 };
 
 struct apr_crypto_block_t {
-    const apr_crypto_t *factory;
     apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
     PK11Context *ctx;
     apr_crypto_key_t *key;
     int blockSize;
 };
 
+static int key_3des_192 = APR_KEY_3DES_192;
+static int key_aes_128 = APR_KEY_AES_128;
+static int key_aes_192 = APR_KEY_AES_192;
+static int key_aes_256 = APR_KEY_AES_256;
+
+static int mode_ecb = APR_MODE_ECB;
+static int mode_cbc = APR_MODE_CBC;
+
+/**
+ * Fetch the most recent error from this driver.
+ */
+static apr_status_t crypto_error(const apu_err_t **result,
+        const apr_crypto_t *f)
+{
+    *result = f->result;
+    return APR_SUCCESS;
+}
 
 /**
  * Shutdown the crypto library and release resources.
  *
  * It is safe to shut down twice.
  */
-static apr_status_t crypto_shutdown(apr_pool_t *pool)
+static apr_status_t crypto_shutdown(void)
 {
     if (NSS_IsInitialized()) {
         SECStatus s = NSS_Shutdown();
@@ -83,51 +114,89 @@
 
 static apr_status_t crypto_shutdown_helper(void *data)
 {
-    apr_pool_t *pool = (apr_pool_t *) data;
-    return crypto_shutdown(pool);
+    return crypto_shutdown();
 }
 
 /**
  * Initialise the crypto library and perform one time initialisation.
  */
-static apr_status_t crypto_init(apr_pool_t *pool, const apr_array_header_t *params, int *rc)
+static apr_status_t crypto_init(apr_pool_t *pool, const char *params, int *rc)
 {
     SECStatus s;
     const char *dir = NULL;
     const char *keyPrefix = NULL;
     const char *certPrefix = NULL;
     const char *secmod = NULL;
+    int noinit = 0;
     PRUint32 flags = 0;
-    struct apr_crypto_param_t *ents = params ? (struct apr_crypto_param_t *)params->elts : NULL;
-    int i = 0;
+
+    struct {
+        const char *field;
+        const char *value;
+        int set;
+    } fields[] = {
+        { "dir", NULL, 0 },
+        { "key3", NULL, 0 },
+        { "cert7", NULL, 0 },
+        { "secmod", NULL, 0 },
+        { "noinit", NULL, 0 },
+        { NULL, NULL, 0 }
+    };
+    const char *ptr;
+    size_t klen;
+    char **elts = NULL;
+    char *elt;
+    int i = 0, j;
+    apr_status_t status;
+
+    if (params) {
+        if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
+            return status;
+        }
+        while ((elt = elts[i])) {
+            ptr = strchr(elt, '=');
+            if (ptr) {
+                for (klen = ptr - elt; klen && apr_isspace(elt[klen - 1]); --klen)
+                    ;
+                ptr++;
+            }
+            else {
+                for (klen = strlen(elt); klen && apr_isspace(elt[klen - 1]); --klen)
+                    ;
+            }
+            elt[klen] = 0;
+
+            for (j = 0; fields[j].field != NULL; ++j) {
+                if (klen && !strcasecmp(fields[j].field, elt)) {
+                    fields[j].set = 1;
+                    if (ptr) {
+                        fields[j].value = ptr;
+                    }
+                    break;
+                }
+            }
+
+            i++;
+        }
+        dir = fields[0].value;
+        keyPrefix = fields[1].value;
+        certPrefix = fields[2].value;
+        secmod = fields[3].value;
+        noinit = fields[4].set;
+    }
+
+    /* if we've been asked to bypass, do so here */
+    if (noinit) {
+        return APR_SUCCESS;
+    }
 
     /* sanity check - we can only initialise NSS once */
     if (NSS_IsInitialized()) {
         return APR_EREINIT;
     }
 
-    apr_pool_cleanup_register(pool, pool,
-                              crypto_shutdown_helper,
-                              apr_pool_cleanup_null);
-
-    for (i = 0; params && i < params->nelts; i++) {
-        switch (ents[i].type) {
-        case APR_CRYPTO_CA_TYPE_DIR:
-            dir = ents[i].path;
-            break;
-        case APR_CRYPTO_CERT_TYPE_KEY3_DB:
-            keyPrefix = ents[i].path;
-            break;
-        case APR_CRYPTO_CA_TYPE_CERT7_DB:
-            certPrefix = ents[i].path;
-            break;
-        case APR_CRYPTO_CA_TYPE_SECMOD:
-            secmod = ents[i].path;
-            break;
-        default:
-            return APR_EINIT;
-        }
-    }
+    apr_pool_cleanup_register(pool, pool, crypto_shutdown_helper,
+            apr_pool_cleanup_null);
 
     if (keyPrefix || certPrefix || secmod) {
         s = NSS_Initialize(dir, certPrefix, keyPrefix, secmod, flags);
@@ -152,8 +221,7 @@
 /**
  * @brief Clean encryption / decryption context.
  * @note After cleanup, a context is free to be reused if necessary.
- * @param driver - driver to use
- * @param ctx The block context to use.
+ * @param f The context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
 static apr_status_t crypto_block_cleanup(apr_crypto_block_t *block)
@@ -175,10 +243,9 @@
 }
 
 /**
- * @brief Clean encryption / decryption factory.
- * @note After cleanup, a factory is free to be reused if necessary.
- * @param driver - driver to use
- * @param f The factory to use.
+ * @brief Clean encryption / decryption context.
+ * @note After cleanup, a context is free to be reused if necessary.
+ * @param f The context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
 static apr_status_t crypto_cleanup(apr_crypto_t *f)
@@ -206,28 +273,27 @@
  *        algorithms and other parameters will be set per context. More than
  *        one context can be created at one time. A cleanup will be automatically
  *        registered with the given pool to guarantee a graceful shutdown.
- * @param driver - driver to use
+ * @param f - context pointer will be written here
+ * @param provider - provider to use
+ * @param params - parameter string
  * @param pool - process pool
- * @param params - array of key parameters
- * @param factory - factory pointer will be written here
  * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
  * if the engine cannot be initialised.
  */
-static apr_status_t crypto_factory(apr_pool_t *pool,
-                                   const apr_array_header_t *params,
-                                   apr_crypto_t **factory)
+static apr_status_t crypto_make(apr_crypto_t **ff,
+        const apr_crypto_driver_t *provider, const char *params,
+        apr_pool_t *pool)
 {
     apr_crypto_config_t *config = NULL;
-    /* struct apr_crypto_param_t *ents = params ? (struct apr_crypto_param_t *)params->elts : NULL; */
-    /* int i = 0; */
     apr_crypto_t *f;
 
     f = apr_pcalloc(pool, sizeof(apr_crypto_t));
     if (!f) {
         return APR_ENOMEM;
     }
-    *factory = f;
+    *ff = f;
     f->pool = pool;
+    f->provider = provider;
     config = f->config = apr_pcalloc(pool, sizeof(apr_crypto_config_t));
     if (!config) {
         return APR_ENOMEM;
@@ -236,31 +302,62 @@
     if (!f->result) {
         return APR_ENOMEM;
     }
-    f->keys = apr_array_make(pool,
-                             10, sizeof(apr_crypto_key_t));
+    f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t));
 
-    apr_pool_cleanup_register(pool, f,
-                              crypto_cleanup_helper,
-                              apr_pool_cleanup_null);
-
-    /*
-    for (i = 0; params && i < params->nelts; i++) {
-        switch (ents[i].type) {
-        default:
-            f->result->rc = -1;
-            f->result->reason = "The NSS module currently supports "
-                "no per factory initialisation parameters at this time, but "
-                "may do in future.";
-            return APR_EINIT;
-        }
+    f->types = apr_hash_make(pool);
+    if (!f->types) {
+        return APR_ENOMEM;
     }
-    */
+    apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192));
+    apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128));
+    apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192));
+    apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256));
+
+    f->modes = apr_hash_make(pool);
+    if (!f->modes) {
+        return APR_ENOMEM;
+    }
+    apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb));
+    apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc));
+
+    apr_pool_cleanup_register(pool, f, crypto_cleanup_helper,
+            apr_pool_cleanup_null);
 
     return APR_SUCCESS;
 
 }
 
 /**
+ * @brief Get a hash table of key types, keyed by the name of the type against
+ * an integer pointer constant.
+ *
+ * @param types - hashtable of key types keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+static apr_status_t crypto_get_block_key_types(apr_hash_t **types,
+        const apr_crypto_t *f)
+{
+    *types = f->types;
+    return APR_SUCCESS;
+}
+
+/**
+ * @brief Get a hash table of key modes, keyed by the name of the mode against
+ * an integer pointer constant.
+ *
+ * @param modes - hashtable of key modes keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes,
+        const apr_crypto_t *f)
+{
+    *modes = f->modes;
+    return APR_SUCCESS;
+}
+
+/**
  * @brief Create a key from the given passphrase. By default, the PBKDF2
  *        algorithm is used to generate the key from the passphrase. It is expected
  *        that the same pass phrase will generate the same key, regardless of the
@@ -269,9 +366,9 @@
  *        operations.
  * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
  *       *key is not NULL, *key must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The context to use.
+ * @param key The key returned, see note.
+ * @param ivSize The size of the initialisation vector will be returned, based
+ *               on whether an IV is relevant for this type of crypto.
  * @param pass The passphrase to use.
  * @param passLen The passphrase length in bytes
  * @param salt The salt to use.
@@ -279,27 +376,20 @@
  * @param type 3DES_192, AES_128, AES_192, AES_256.
  * @param mode Electronic Code Book / Cipher Block Chaining.
  * @param doPad Pad if necessary.
- * @param key The key returned, see note.
- * @param ivSize The size of the initialisation vector will be returned, based
- *               on whether an IV is relevant for this type of crypto.
+ * @param iterations Iteration count
+ * @param f The context to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
  *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
  *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
  *         not known. APR_EPADDING if padding was requested but is not supported.
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_passphrase(apr_pool_t *p,
-                                      const apr_crypto_t *f,
-                                      const char *pass,
-                                      apr_size_t passLen,
-                                      const unsigned char * salt,
-                                      apr_size_t saltLen,
-                                      const apr_crypto_block_key_type_e type,
-                                      const apr_crypto_block_key_mode_e mode,
-                                      const int doPad,
-                                      const int iterations,
-                                      apr_crypto_key_t **k,
-                                      apr_size_t *ivSize)
+static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize,
+        const char *pass, apr_size_t passLen, const unsigned char * salt,
+        apr_size_t saltLen, const apr_crypto_block_key_type_e type,
+        const apr_crypto_block_key_mode_e mode, const int doPad,
+        const int iterations, const apr_crypto_t *f, apr_pool_t *p)
 {
     apr_status_t rv = APR_SUCCESS;
     PK11SlotInfo * slot;
@@ -316,36 +406,39 @@
         return APR_ENOMEM;
     }
 
+    key->f = f;
+    key->provider = f->provider;
+
     /* decide on what cipher mechanism we will be using */
     switch (type) {
 
-    case (KEY_3DES_192) :
-        if (MODE_CBC == mode) {
+    case (APR_KEY_3DES_192):
+        if (APR_MODE_CBC == mode) {
             key->cipherOid = SEC_OID_DES_EDE3_CBC;
         }
-        else if (MODE_ECB == mode) {
+        else if (APR_MODE_ECB == mode) {
             return APR_ENOCIPHER;
             /* No OID for CKM_DES3_ECB; */
         }
         break;
-    case (KEY_AES_128) :
-        if (MODE_CBC == mode) {
+    case (APR_KEY_AES_128):
+        if (APR_MODE_CBC == mode) {
             key->cipherOid = SEC_OID_AES_128_CBC;
         }
         else {
             key->cipherOid = SEC_OID_AES_128_ECB;
         }
         break;
-    case (KEY_AES_192) :
-        if (MODE_CBC == mode) {
+    case (APR_KEY_AES_192):
+        if (APR_MODE_CBC == mode) {
             key->cipherOid = SEC_OID_AES_192_CBC;
         }
         else {
             key->cipherOid = SEC_OID_AES_192_ECB;
         }
         break;
-    case (KEY_AES_256) :
-        if (MODE_CBC == mode) {
+    case (APR_KEY_AES_256):
+        if (APR_MODE_CBC == mode) {
             key->cipherOid = SEC_OID_AES_256_CBC;
         }
         else {
@@ -365,25 +458,28 @@
     if (doPad) {
         CK_MECHANISM_TYPE paddedMech;
         paddedMech = PK11_GetPadMechanism(key->cipherMech);
-        if (CKM_INVALID_MECHANISM == paddedMech || key->cipherMech == paddedMech) {
+        if (CKM_INVALID_MECHANISM == paddedMech || key->cipherMech
+                == paddedMech) {
             return APR_EPADDING;
         }
         key->cipherMech = paddedMech;
     }
 
     /* Turn the raw passphrase and salt into SECItems */
-    passItem.data = (unsigned char*)pass;
+    passItem.data = (unsigned char*) pass;
     passItem.len = passLen;
-    saltItem.data = (unsigned char*)salt;
+    saltItem.data = (unsigned char*) salt;
     saltItem.len = saltLen;
 
     /* generate the key */
     /* pbeAlg and cipherAlg are the same. NSS decides the keylength. */
-    algid = PK11_CreatePBEV2AlgorithmID(key->cipherOid, key->cipherOid, SEC_OID_HMAC_SHA1, 0, iterations, &saltItem);
+    algid = PK11_CreatePBEV2AlgorithmID(key->cipherOid, key->cipherOid,
+            SEC_OID_HMAC_SHA1, 0, iterations, &saltItem);
     if (algid) {
         slot = PK11_GetBestSlot(key->cipherMech, wincx);
         if (slot) {
-            key->symKey = PK11_PBEKeyGen(slot, algid, &passItem, PR_FALSE, wincx);
+            key->symKey = PK11_PBEKeyGen(slot, algid, &passItem, PR_FALSE,
+                    wincx);
             PK11_FreeSlot(slot);
         }
         SECOID_DestroyAlgorithmID(algid, PR_TRUE);
@@ -411,25 +507,21 @@
  * @brief Initialise a context for encrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure.
+ * @param ctx The block context returned, see note.
  * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
  *           an IV will be created at random, in space allocated from the pool.
  *           If the buffer pointed to is not NULL, the IV in the buffer will be
  *           used.
- * @param ctx The block context returned, see note.
+ * @param key The key structure.
  * @param blockSize The block size of the cipher.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_encrypt_init(apr_pool_t *p,
-                                              const apr_crypto_t *f,
-                                              const apr_crypto_key_t *key,
-                                              const unsigned char **iv,
-                                              apr_crypto_block_t **ctx,
-                                              apr_size_t *blockSize)
+static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx,
+        const unsigned char **iv, const apr_crypto_key_t *key,
+        apr_size_t *blockSize, apr_pool_t *p)
 {
     PRErrorCode perr;
     SECItem * secParam;
@@ -442,30 +534,32 @@
     if (!block) {
         return APR_ENOMEM;
     }
-    block->factory = f;
+    block->f = key->f;
     block->pool = p;
+    block->provider = key->provider;
 
-    apr_pool_cleanup_register(p, block,
-                              crypto_block_cleanup_helper,
-                              apr_pool_cleanup_null);
+    apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
+            apr_pool_cleanup_null);
 
     if (key->ivSize) {
         if (iv == NULL) {
             return APR_ENOIV;
         }
         if (*iv == NULL) {
+            SECStatus s;
             usedIv = apr_pcalloc(p, key->ivSize);
             if (!usedIv) {
                 return APR_ENOMEM;
             }
-            SECStatus s = PK11_GenerateRandom(usedIv, key->ivSize);
+            apr_crypto_clear(p, usedIv, key->ivSize);
+            s = PK11_GenerateRandom(usedIv, key->ivSize);
             if (s != SECSuccess) {
                 return APR_ENOIV;
             }
             *iv = usedIv;
         }
         else {
-             usedIv = (unsigned char *)*iv;
+            usedIv = (unsigned char *) *iv;
         }
         ivItem.data = usedIv;
         ivItem.len = key->ivSize;
@@ -475,18 +569,19 @@
         secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
     }
     block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
-    block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_ENCRYPT, key->symKey, secParam);
+    block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_ENCRYPT,
+            key->symKey, secParam);
 
     /* did an error occur? */
     perr = PORT_GetError();
     if (perr || !block->ctx) {
-        f->result->rc = perr;
-        f->result->msg = PR_ErrorToName(perr);
+        key->f->result->rc = perr;
+        key->f->result->msg = PR_ErrorToName(perr);
         return APR_EINIT;
     }
 
     if (blockSize) {
-    *blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
+        *blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
     }
 
     return APR_SUCCESS;
@@ -502,24 +597,23 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-static apr_status_t crypto_block_encrypt(apr_crypto_block_t *block,
-                                         unsigned char **out,
-                                         apr_size_t *outlen,
-                                         const unsigned char *in,
-                                         apr_size_t inlen)
+static apr_status_t crypto_block_encrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *block)
 {
 
     unsigned char *buffer;
     int outl = (int) *outlen;
+    SECStatus s;
     if (!out) {
         *outlen = inlen + block->blockSize;
         return APR_SUCCESS;
@@ -529,15 +623,17 @@
         if (!buffer) {
             return APR_ENOMEM;
         }
+        apr_crypto_clear(block->pool, buffer, inlen + block->blockSize);
         *out = buffer;
     }
 
-    SECStatus s = PK11_CipherOp(block->ctx, *out, &outl, inlen, (unsigned char*)in, inlen);
+    s = PK11_CipherOp(block->ctx, *out, &outl, inlen, (unsigned char*) in,
+            inlen);
     if (s != SECSuccess) {
         PRErrorCode perr = PORT_GetError();
         if (perr) {
-            block->factory->result->rc = perr;
-            block->factory->result->msg = PR_ErrorToName(perr);
+            block->f->result->rc = perr;
+            block->f->result->msg = PR_ErrorToName(perr);
         }
         return APR_ECRYPT;
     }
@@ -555,19 +651,18 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_encrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_encrypt_finish(apr_crypto_block_t *block,
-                                                unsigned char *out,
-                                                apr_size_t *outlen)
+static apr_status_t crypto_block_encrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *block)
 {
 
     apr_status_t rv = APR_SUCCESS;
@@ -579,8 +674,8 @@
     if (s != SECSuccess) {
         PRErrorCode perr = PORT_GetError();
         if (perr) {
-            block->factory->result->rc = perr;
-            block->factory->result->msg = PR_ErrorToName(perr);
+            block->f->result->rc = perr;
+            block->f->result->msg = PR_ErrorToName(perr);
         }
         rv = APR_ECRYPT;
     }
@@ -594,25 +689,20 @@
  * @brief Initialise a context for decrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure.
- * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
- *           an IV will be created at random, in space allocated from the pool.
- *           If the buffer pointed to is not NULL, the IV in the buffer will be
- *           used.
  * @param ctx The block context returned, see note.
  * @param blockSize The block size of the cipher.
+ * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
+ *           an IV will be created at random, in space allocated from the pool.
+ *           If the buffer is not NULL, the IV in the buffer will be used.
+ * @param key The key structure.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_decrypt_init(apr_pool_t *p,
-                                              const apr_crypto_t *f,
-                                              const apr_crypto_key_t *key,
-                                              const unsigned char *iv,
-                                              apr_crypto_block_t **ctx,
-                                              apr_size_t *blockSize)
+static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx,
+        apr_size_t *blockSize, const unsigned char *iv,
+        const apr_crypto_key_t *key, apr_pool_t *p)
 {
     PRErrorCode perr;
     SECItem * secParam;
@@ -623,19 +713,19 @@
     if (!block) {
         return APR_ENOMEM;
     }
-    block->factory = f;
+    block->f = key->f;
     block->pool = p;
+    block->provider = key->provider;
 
-    apr_pool_cleanup_register(p, block,
-                              crypto_block_cleanup_helper,
-                              apr_pool_cleanup_null);
+    apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
+            apr_pool_cleanup_null);
 
     if (key->ivSize) {
         SECItem ivItem;
         if (iv == NULL) {
             return APR_ENOIV; /* Cannot initialise without an IV */
         }
-        ivItem.data = (unsigned char*)iv;
+        ivItem.data = (unsigned char*) iv;
         ivItem.len = key->ivSize;
         secParam = PK11_ParamFromIV(key->cipherMech, &ivItem);
     }
@@ -643,13 +733,14 @@
         secParam = PK11_GenerateNewParam(key->cipherMech, key->symKey);
     }
     block->blockSize = PK11_GetBlockSize(key->cipherMech, secParam);
-    block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_DECRYPT, key->symKey, secParam);
+    block->ctx = PK11_CreateContextBySymKey(key->cipherMech, CKA_DECRYPT,
+            key->symKey, secParam);
 
     /* did an error occur? */
     perr = PORT_GetError();
     if (perr || !block->ctx) {
-        f->result->rc = perr;
-        f->result->msg = PR_ErrorToName(perr);
+        key->f->result->rc = perr;
+        key->f->result->msg = PR_ErrorToName(perr);
         return APR_EINIT;
     }
 
@@ -666,28 +757,27 @@
  * @note The number of bytes written will be written to outlen. If
  *       out is NULL, outlen will contain the maximum size of the
  *       buffer needed to hold the data, including any data
- *       generated by apr_crypto_block_final below. If *out points
+ *       generated by apr_crypto_block_decrypt_finish below. If *out points
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-static apr_status_t crypto_block_decrypt(apr_crypto_block_t *block,
-                                         unsigned char **out,
-                                         apr_size_t *outlen,
-                                         const unsigned char *in,
-                                         apr_size_t inlen)
+static apr_status_t crypto_block_decrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *block)
 {
 
     unsigned char *buffer;
     int outl = (int) *outlen;
+    SECStatus s;
     if (!out) {
         *outlen = inlen + block->blockSize;
         return APR_SUCCESS;
@@ -697,15 +787,17 @@
         if (!buffer) {
             return APR_ENOMEM;
         }
+        apr_crypto_clear(block->pool, buffer, inlen + block->blockSize);
         *out = buffer;
     }
 
-    SECStatus s = PK11_CipherOp(block->ctx, *out, &outl, inlen, (unsigned char*)in, inlen);
+    s = PK11_CipherOp(block->ctx, *out, &outl, inlen, (unsigned char*) in,
+            inlen);
     if (s != SECSuccess) {
         PRErrorCode perr = PORT_GetError();
         if (perr) {
-            block->factory->result->rc = perr;
-            block->factory->result->msg = PR_ErrorToName(perr);
+            block->f->result->rc = perr;
+            block->f->result->msg = PR_ErrorToName(perr);
         }
         return APR_ECRYPT;
     }
@@ -716,26 +808,25 @@
 }
 
 /**
- * @brief Encrypt final data block, write it to out.
+ * @brief Decrypt final data block, write it to out.
  * @note If necessary the final block will be written out after being
  *       padded. Typically the final block will be written to the
- *       same buffer used by apr_evp_crypt, offset by the number of
- *       bytes returned as actually written by the apr_evp_crypt()
- *       call. After this call, the context is cleaned and can be
- *       reused by apr_env_encrypt_init() or apr_env_decrypt_init().
- * @param ctx The block context to use.
+ *       same buffer used by apr_crypto_block_decrypt, offset by the
+ *       number of bytes returned as actually written by the
+ *       apr_crypto_block_decrypt() call. After this call, the context
+ *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_decrypt_finish(apr_crypto_block_t *block,
-                                                unsigned char *out,
-                                                apr_size_t *outlen)
+static apr_status_t crypto_block_decrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *block)
 {
 
     apr_status_t rv = APR_SUCCESS;
@@ -747,8 +838,8 @@
     if (s != SECSuccess) {
         PRErrorCode perr = PORT_GetError();
         if (perr) {
-            block->factory->result->rc = perr;
-            block->factory->result->msg = PR_ErrorToName(perr);
+            block->f->result->rc = perr;
+            block->f->result->msg = PR_ErrorToName(perr);
         }
         rv = APR_ECRYPT;
     }
@@ -759,22 +850,15 @@
 }
 
 /**
- * OpenSSL module.
+ * NSS module.
  */
 APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_nss_driver = {
-    "nss",
-    crypto_init,
-    crypto_factory,
-    crypto_passphrase,
-    crypto_block_encrypt_init,
-    crypto_block_encrypt,
-    crypto_block_encrypt_finish,
-    crypto_block_decrypt_init,
-    crypto_block_decrypt,
-    crypto_block_decrypt_finish,
-    crypto_block_cleanup,
-    crypto_cleanup,
-    crypto_shutdown
+    "nss", crypto_init, crypto_make, crypto_get_block_key_types,
+    crypto_get_block_key_modes, crypto_passphrase,
+    crypto_block_encrypt_init, crypto_block_encrypt,
+    crypto_block_encrypt_finish, crypto_block_decrypt_init,
+    crypto_block_decrypt, crypto_block_decrypt_finish,
+    crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error
 };
 
 #endif
diff --git a/crypto/apr_crypto_openssl.c b/crypto/apr_crypto_openssl.c
index a9dda90..97e6008 100644
--- a/crypto/apr_crypto_openssl.c
+++ b/crypto/apr_crypto_openssl.c
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
+#include "apr_lib.h"
 #include "apu.h"
-
-#include "apu_config.h"
 #include "apu_errno.h"
 
 #include <ctype.h>
@@ -36,11 +35,24 @@
 
 #define LOG_PREFIX "apr_crypto_openssl: "
 
+struct apr_crypto_t {
+    apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    apu_err_t *result;
+    apr_array_header_t *keys;
+    apr_crypto_config_t *config;
+    apr_hash_t *types;
+    apr_hash_t *modes;
+};
+
 struct apr_crypto_config_t {
     ENGINE *engine;
 };
 
 struct apr_crypto_key_t {
+    apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
     const EVP_CIPHER * cipher;
     unsigned char *key;
     int keyLen;
@@ -49,8 +61,9 @@
 };
 
 struct apr_crypto_block_t {
-    const apr_crypto_t *factory;
     apr_pool_t *pool;
+    const apr_crypto_driver_t *provider;
+    const apr_crypto_t *f;
     EVP_CIPHER_CTX cipherCtx;
     int initialised;
     int ivSize;
@@ -58,26 +71,45 @@
     int doPad;
 };
 
+static int key_3des_192 = APR_KEY_3DES_192;
+static int key_aes_128 = APR_KEY_AES_128;
+static int key_aes_192 = APR_KEY_AES_192;
+static int key_aes_256 = APR_KEY_AES_256;
+
+static int mode_ecb = APR_MODE_ECB;
+static int mode_cbc = APR_MODE_CBC;
+
+/**
+ * Fetch the most recent error from this driver.
+ */
+static apr_status_t crypto_error(const apu_err_t **result,
+        const apr_crypto_t *f)
+{
+    *result = f->result;
+    return APR_SUCCESS;
+}
+
 /**
  * Shutdown the crypto library and release resources.
  */
-static apr_status_t crypto_shutdown(apr_pool_t *pool) {
+static apr_status_t crypto_shutdown(void)
+{
     ERR_free_strings();
     EVP_cleanup();
     ENGINE_cleanup();
     return APR_SUCCESS;
 }
 
-static apr_status_t crypto_shutdown_helper(void *data) {
-    apr_pool_t *pool = (apr_pool_t *) data;
-    return crypto_shutdown(pool);
+static apr_status_t crypto_shutdown_helper(void *data)
+{
+    return crypto_shutdown();
 }
 
 /**
  * Initialise the crypto library and perform one time initialisation.
  */
-static apr_status_t crypto_init(apr_pool_t *pool,
-        const apr_array_header_t *params, int *rc) {
+static apr_status_t crypto_init(apr_pool_t *pool, const char *params, int *rc)
+{
     CRYPTO_malloc_init();
     ERR_load_crypto_strings();
     /* SSL_load_error_strings(); */
@@ -94,11 +126,11 @@
 /**
  * @brief Clean encryption / decryption context.
  * @note After cleanup, a context is free to be reused if necessary.
- * @param driver - driver to use
  * @param ctx The block context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx) {
+static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx)
+{
 
     if (ctx->initialised) {
         EVP_CIPHER_CTX_cleanup(&ctx->cipherCtx);
@@ -109,19 +141,20 @@
 
 }
 
-static apr_status_t crypto_block_cleanup_helper(void *data) {
+static apr_status_t crypto_block_cleanup_helper(void *data)
+{
     apr_crypto_block_t *block = (apr_crypto_block_t *) data;
     return crypto_block_cleanup(block);
 }
 
 /**
- * @brief Clean encryption / decryption factory.
- * @note After cleanup, a factory is free to be reused if necessary.
- * @param driver - driver to use
- * @param f The factory to use.
+ * @brief Clean encryption / decryption context.
+ * @note After cleanup, a context is free to be reused if necessary.
+ * @param f The context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-static apr_status_t crypto_cleanup(apr_crypto_t *f) {
+static apr_status_t crypto_cleanup(apr_crypto_t *f)
+{
 
     if (f->config->engine) {
         ENGINE_finish(f->config->engine);
@@ -132,7 +165,8 @@
 
 }
 
-static apr_status_t crypto_cleanup_helper(void *data) {
+static apr_status_t crypto_cleanup_helper(void *data)
+{
     apr_crypto_t *f = (apr_crypto_t *) data;
     return crypto_cleanup(f);
 }
@@ -142,51 +176,118 @@
  *        algorithms and other parameters will be set per context. More than
  *        one context can be created at one time. A cleanup will be automatically
  *        registered with the given pool to guarantee a graceful shutdown.
- * @param driver - driver to use
- * @param pool - process pool
+ * @param f - context pointer will be written here
+ * @param provider - provider to use
  * @param params - array of key parameters
- * @param factory - factory pointer will be written here
+ * @param pool - process pool
  * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
  * if the engine cannot be initialised.
  */
-static apr_status_t crypto_factory(apr_pool_t *pool,
-        const apr_array_header_t *params, apr_crypto_t **factory) {
+static apr_status_t crypto_make(apr_crypto_t **ff,
+        const apr_crypto_driver_t *provider, const char *params,
+        apr_pool_t *pool)
+{
     apr_crypto_config_t *config = NULL;
-    struct apr_crypto_param_t *ents =
-            params ? (struct apr_crypto_param_t *) params->elts : NULL;
-    int i = 0;
     apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t));
+
+    const char *engine = NULL;
+
+    struct {
+        const char *field;
+        const char *value;
+        int set;
+    } fields[] = {
+        { "engine", NULL, 0 },
+        { NULL, NULL, 0 }
+    };
+    const char *ptr;
+    size_t klen;
+    char **elts = NULL;
+    char *elt;
+    int i = 0, j;
+    apr_status_t status;
+
+    if (params) {
+        if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
+            return status;
+        }
+        while ((elt = elts[i])) {
+            ptr = strchr(elt, '=');
+            if (ptr) {
+                for (klen = ptr - elt; klen && apr_isspace(elt[klen - 1]); --klen)
+                    ;
+                ptr++;
+            }
+            else {
+                for (klen = strlen(elt); klen && apr_isspace(elt[klen - 1]); --klen)
+                    ;
+            }
+            elt[klen] = 0;
+
+            for (j = 0; fields[j].field != NULL; ++j) {
+                if (!strcasecmp(fields[j].field, elt)) {
+                    fields[j].set = 1;
+                    if (ptr) {
+                        fields[j].value = ptr;
+                    }
+                    break;
+                }
+            }
+
+            i++;
+        }
+        engine = fields[0].value;
+    }
+
     if (!f) {
         return APR_ENOMEM;
     }
-    *factory = f;
+    *ff = f;
     f->pool = pool;
+    f->provider = provider;
     config = f->config = apr_pcalloc(pool, sizeof(apr_crypto_config_t));
     if (!config) {
         return APR_ENOMEM;
     }
+
     f->result = apr_pcalloc(pool, sizeof(apu_err_t));
     if (!f->result) {
         return APR_ENOMEM;
     }
+
     f->keys = apr_array_make(pool, 10, sizeof(apr_crypto_key_t));
+    if (!f->keys) {
+        return APR_ENOMEM;
+    }
+
+    f->types = apr_hash_make(pool);
+    if (!f->types) {
+        return APR_ENOMEM;
+    }
+    apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_3des_192));
+    apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_aes_128));
+    apr_hash_set(f->types, "aes192", APR_HASH_KEY_STRING, &(key_aes_192));
+    apr_hash_set(f->types, "aes256", APR_HASH_KEY_STRING, &(key_aes_256));
+
+    f->modes = apr_hash_make(pool);
+    if (!f->modes) {
+        return APR_ENOMEM;
+    }
+    apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(mode_ecb));
+    apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(mode_cbc));
 
     apr_pool_cleanup_register(pool, f, crypto_cleanup_helper,
             apr_pool_cleanup_null);
 
-    for (i = 0; params && i < params->nelts; i++) {
-        switch (ents[i].type) {
-        case APR_CRYPTO_ENGINE:
-            config->engine = ENGINE_by_id(ents[i].path);
-            if (!config->engine) {
-                return APR_ENOENGINE;
-            }
-            if (!ENGINE_init(config->engine)) {
-                ENGINE_free(config->engine);
-                config->engine = NULL;
-                return APR_EINITENGINE;
-            }
-            break;
+    if (engine) {
+        config->engine = ENGINE_by_id(engine);
+        if (!config->engine) {
+            return APR_ENOENGINE;
+        }
+        if (!ENGINE_init(config->engine)) {
+            ENGINE_free(config->engine);
+            config->engine = NULL;
+            return APR_EINITENGINE;
         }
     }
 
@@ -195,6 +296,36 @@
 }
 
 /**
+ * @brief Get a hash table of key types, keyed by the name of the type against
+ * an integer pointer constant.
+ *
+ * @param types - hashtable of key types keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+static apr_status_t crypto_get_block_key_types(apr_hash_t **types,
+        const apr_crypto_t *f)
+{
+    *types = f->types;
+    return APR_SUCCESS;
+}
+
+/**
+ * @brief Get a hash table of key modes, keyed by the name of the mode against
+ * an integer pointer constant.
+ *
+ * @param modes - hashtable of key modes keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+static apr_status_t crypto_get_block_key_modes(apr_hash_t **modes,
+        const apr_crypto_t *f)
+{
+    *modes = f->modes;
+    return APR_SUCCESS;
+}
+
+/**
  * @brief Create a key from the given passphrase. By default, the PBKDF2
  *        algorithm is used to generate the key from the passphrase. It is expected
  *        that the same pass phrase will generate the same key, regardless of the
@@ -203,9 +334,9 @@
  *        operations.
  * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
  *       *key is not NULL, *key must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The context to use.
+ * @param key The key returned, see note.
+ * @param ivSize The size of the initialisation vector will be returned, based
+ *               on whether an IV is relevant for this type of crypto.
  * @param pass The passphrase to use.
  * @param passLen The passphrase length in bytes
  * @param salt The salt to use.
@@ -213,20 +344,21 @@
  * @param type 3DES_192, AES_128, AES_192, AES_256.
  * @param mode Electronic Code Book / Cipher Block Chaining.
  * @param doPad Pad if necessary.
- * @param key The key returned, see note.
- * @param ivSize The size of the initialisation vector will be returned, based
- *               on whether an IV is relevant for this type of crypto.
+ * @param iterations Iteration count
+ * @param f The context to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
  *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
  *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
  *         not known. APR_EPADDING if padding was requested but is not supported.
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_passphrase(apr_pool_t *p, const apr_crypto_t *f,
+static apr_status_t crypto_passphrase(apr_crypto_key_t **k, apr_size_t *ivSize,
         const char *pass, apr_size_t passLen, const unsigned char * salt,
         apr_size_t saltLen, const apr_crypto_block_key_type_e type,
         const apr_crypto_block_key_mode_e mode, const int doPad,
-        const int iterations, apr_crypto_key_t **k, apr_size_t *ivSize) {
+        const int iterations, const apr_crypto_t *f, apr_pool_t *p)
+{
     apr_crypto_key_t *key = *k;
 
     if (!key) {
@@ -236,42 +368,49 @@
         return APR_ENOMEM;
     }
 
+    key->f = f;
+    key->provider = f->provider;
+
     /* determine the cipher to be used */
     switch (type) {
 
-    case (KEY_3DES_192):
+    case (APR_KEY_3DES_192):
 
         /* A 3DES key */
-        if (mode == MODE_CBC) {
+        if (mode == APR_MODE_CBC) {
             key->cipher = EVP_des_ede3_cbc();
-        } else {
+        }
+        else {
             key->cipher = EVP_des_ede3_ecb();
         }
         break;
 
-    case (KEY_AES_128):
+    case (APR_KEY_AES_128):
 
-        if (mode == MODE_CBC) {
+        if (mode == APR_MODE_CBC) {
             key->cipher = EVP_aes_128_cbc();
-        } else {
+        }
+        else {
             key->cipher = EVP_aes_128_ecb();
         }
         break;
 
-    case (KEY_AES_192):
+    case (APR_KEY_AES_192):
 
-        if (mode == MODE_CBC) {
+        if (mode == APR_MODE_CBC) {
             key->cipher = EVP_aes_192_cbc();
-        } else {
+        }
+        else {
             key->cipher = EVP_aes_192_ecb();
         }
         break;
 
-    case (KEY_AES_256):
+    case (APR_KEY_AES_256):
 
-        if (mode == MODE_CBC) {
+        if (mode == APR_MODE_CBC) {
             key->cipher = EVP_aes_256_cbc();
-        } else {
+        }
+        else {
             key->cipher = EVP_aes_256_ecb();
         }
         break;
@@ -291,6 +430,7 @@
     if (!key->key) {
         return APR_ENOMEM;
     }
+    apr_crypto_clear(p, key->key, key->keyLen);
 
     /* generate the key */
     if (PKCS5_PBKDF2_HMAC_SHA1(pass, passLen, (unsigned char *) salt, saltLen,
@@ -303,7 +443,7 @@
     /* note: openssl incorrectly returns non zero IV size values for ECB
      * algorithms, so work around this by ignoring the IV size.
      */
-    if (MODE_ECB != mode) {
+    if (APR_MODE_ECB != mode) {
         key->ivSize = EVP_CIPHER_iv_length(key->cipher);
     }
     if (ivSize) {
@@ -317,26 +457,24 @@
  * @brief Initialise a context for encrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param type 3DES_192, AES_128, AES_192, AES_256.
- * @param mode Electronic Code Book / Cipher Block Chaining.
- * @param key The key
- * @param keyLen The key length in bytes
- * @param iv Optional initialisation vector.
- * @param doPad Pad if necessary.
  * @param ctx The block context returned, see note.
+ * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
+ *           an IV will be created at random, in space allocated from the pool.
+ *           If the buffer pointed to is not NULL, the IV in the buffer will be
+ *           used.
+ * @param key The key structure.
  * @param blockSize The block size of the cipher.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_encrypt_init(apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char **iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize) {
+static apr_status_t crypto_block_encrypt_init(apr_crypto_block_t **ctx,
+        const unsigned char **iv, const apr_crypto_key_t *key,
+        apr_size_t *blockSize, apr_pool_t *p)
+{
     unsigned char *usedIv;
-    apr_crypto_config_t *config = f->config;
+    apr_crypto_config_t *config = key->f->config;
     apr_crypto_block_t *block = *ctx;
     if (!block) {
         *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
@@ -344,8 +482,9 @@
     if (!block) {
         return APR_ENOMEM;
     }
-    block->factory = f;
+    block->f = key->f;
     block->pool = p;
+    block->provider = key->provider;
 
     apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
             apr_pool_cleanup_null);
@@ -365,12 +504,14 @@
             if (!usedIv) {
                 return APR_ENOMEM;
             }
+            apr_crypto_clear(p, usedIv, key->ivSize);
             if (!((RAND_status() == 1)
                     && (RAND_bytes(usedIv, key->ivSize) == 1))) {
                 return APR_ENOIV;
             }
             *iv = usedIv;
-        } else {
+        }
+        else {
             usedIv = (unsigned char *) *iv;
         }
     }
@@ -407,18 +548,19 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-static apr_status_t crypto_block_encrypt(apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen) {
+static apr_status_t crypto_block_encrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx)
+{
     int outl = *outlen;
     unsigned char *buffer;
 
@@ -434,6 +576,7 @@
         if (!buffer) {
             return APR_ENOMEM;
         }
+        apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
         *out = buffer;
     }
 
@@ -459,18 +602,19 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_encrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_encrypt_finish(apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen) {
+static apr_status_t crypto_block_encrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx)
+{
     int len = *outlen;
 
     if (EVP_EncryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) {
@@ -486,23 +630,22 @@
  * @brief Initialise a context for decrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure.
+ * @param ctx The block context returned, see note.
+ * @param blockSize The block size of the cipher.
  * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
  *           an IV will be created at random, in space allocated from the pool.
  *           If the buffer is not NULL, the IV in the buffer will be used.
- * @param ctx The block context returned, see note.
- * @param blockSize The block size of the cipher.
+ * @param key The key structure.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_decrypt_init(apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char *iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize) {
-    apr_crypto_config_t *config = f->config;
+static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx,
+        apr_size_t *blockSize, const unsigned char *iv,
+        const apr_crypto_key_t *key, apr_pool_t *p)
+{
+    apr_crypto_config_t *config = key->f->config;
     apr_crypto_block_t *block = *ctx;
     if (!block) {
         *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
@@ -510,8 +653,9 @@
     if (!block) {
         return APR_ENOMEM;
     }
-    block->factory = f;
+    block->f = key->f;
     block->pool = p;
+    block->provider = key->provider;
 
     apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
             apr_pool_cleanup_null);
@@ -555,23 +699,23 @@
  * @note The number of bytes written will be written to outlen. If
  *       out is NULL, outlen will contain the maximum size of the
  *       buffer needed to hold the data, including any data
- *       generated by apr_crypto_block_final below. If *out points
+ *       generated by apr_crypto_block_decrypt_finish below. If *out points
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-static apr_status_t crypto_block_decrypt(apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen) {
-
+static apr_status_t crypto_block_decrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx)
+{
     int outl = *outlen;
     unsigned char *buffer;
 
@@ -587,6 +731,7 @@
         if (!buffer) {
             return APR_ENOMEM;
         }
+        apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
         *out = buffer;
     }
 
@@ -608,22 +753,23 @@
  * @brief Decrypt final data block, write it to out.
  * @note If necessary the final block will be written out after being
  *       padded. Typically the final block will be written to the
- *       same buffer used by apr_evp_crypt, offset by the number of
- *       bytes returned as actually written by the apr_evp_crypt()
- *       call. After this call, the context is cleaned and can be
- *       reused by apr_env_encrypt_init() or apr_env_decrypt_init().
- * @param ctx The block context to use.
+ *       same buffer used by apr_crypto_block_decrypt, offset by the
+ *       number of bytes returned as actually written by the
+ *       apr_crypto_block_decrypt() call. After this call, the context
+ *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-static apr_status_t crypto_block_decrypt_finish(apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen) {
+static apr_status_t crypto_block_decrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx)
+{
 
     int len = *outlen;
 
@@ -640,10 +786,12 @@
  * OpenSSL module.
  */
 APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_openssl_driver = {
-        "openssl", crypto_init, crypto_factory, crypto_passphrase,
-        crypto_block_encrypt_init, crypto_block_encrypt,
-        crypto_block_encrypt_finish, crypto_block_decrypt_init,
-        crypto_block_decrypt, crypto_block_decrypt_finish,
-        crypto_block_cleanup, crypto_cleanup, crypto_shutdown };
+    "openssl", crypto_init, crypto_make, crypto_get_block_key_types,
+    crypto_get_block_key_modes, crypto_passphrase,
+    crypto_block_encrypt_init, crypto_block_encrypt,
+    crypto_block_encrypt_finish, crypto_block_decrypt_init,
+    crypto_block_decrypt, crypto_block_decrypt_finish,
+    crypto_block_cleanup, crypto_cleanup, crypto_shutdown, crypto_error
+};
 
 #endif
diff --git a/dbd/NWGNUdbdfreetds b/dbd/NWGNUdbdfreetds
index 6fe0639..fcac227 100644
--- a/dbd/NWGNUdbdfreetds
+++ b/dbd/NWGNUdbdfreetds
@@ -11,7 +11,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #include $(APR)\build\NWGNUcustom.inc
@@ -38,8 +38,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(FREETDS_INC) \
 			$(EOLIST)
@@ -150,12 +150,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -165,7 +165,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -200,7 +200,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -290,7 +290,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbd/NWGNUdbdmysql b/dbd/NWGNUdbdmysql
index 151eb95..78e865e 100644
--- a/dbd/NWGNUdbdmysql
+++ b/dbd/NWGNUdbdmysql
@@ -11,7 +11,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #include $(APR)\build\NWGNUcustom.inc
@@ -27,8 +27,8 @@
 
 # for now defined here - should finally go into build/NWGNUenvironment.inc
 MYSQL_INC = $(MYSQLSDK)/include
-MYSQL_IMP = $(MYSQLSDK)/lib/libmysql.imp
-MYSQL_LIB = $(MYSQLSDK)/lib/libmysqlclient_r.lib $(MYSQLSDK)/lib/libz.lib
+MYSQL_IMP = libmysql.imp
+MYSQL_LIB = libmysqlclient_r.lib libz.lib
 MYSQL_NLM = libmysql
 
 #
@@ -38,8 +38,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(MYSQL_INC) \
 			$(EOLIST)
@@ -63,13 +63,8 @@
 # These flags will be added to the link.opt file
 #
 XLFLAGS		+= \
-			$(EOLIST)
-
-ifdef LINK_STATIC
-XLFLAGS		+= \
 			-l $(MYSQLSDK)/lib \
 			$(EOLIST)
-endif
 
 #
 # These values will be appended to the correct variables based on the value of
@@ -151,12 +146,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -166,7 +161,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -179,7 +174,7 @@
 # If there is an NLM target, put it here
 #
 TARGET_nlm = \
-	$(OBJDIR)\$(NLM_NAME).nlm \
+	$(OBJDIR)/$(NLM_NAME).nlm \
 	$(EOLIST)
 
 #
@@ -201,7 +196,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -244,7 +239,7 @@
 # Any additional imports go here
 #
 FILES_nlm_Ximports = \
-	@$(APR)/aprlib.imp \
+	@aprlib.imp \
 	@libc.imp \
 	$(EOLIST)
 
@@ -291,7 +286,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbd/NWGNUdbdpgsql b/dbd/NWGNUdbdpgsql
index 8e48529..32ac775 100644
--- a/dbd/NWGNUdbdpgsql
+++ b/dbd/NWGNUdbdpgsql
@@ -11,7 +11,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #include $(APR)\build\NWGNUcustom.inc
@@ -27,8 +27,8 @@
 
 # for now defined here - should finally go into build/NWGNUenvironment.inc
 PGSQL_INC = $(PGSQLSDK)/inc
-PGSQL_IMP = $(PGSQLSDK)/imp/libpq.imp
-PGSQL_LIB = $(PGSQLSDK)/lib/libpq.lib
+PGSQL_IMP = libpq.imp
+PGSQL_LIB = libpq.lib
 PGSQL_NLM = libpq
 
 #
@@ -38,8 +38,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(PGSQL_INC) \
 			$(EOLIST)
@@ -69,6 +69,10 @@
 XLFLAGS		+= \
 			-l $(PGSQLSDK)/lib \
 			$(EOLIST)
+else
+XLFLAGS		+= \
+			-l $(PGSQLSDK)/imp \
+			$(EOLIST)
 endif
 
 #
@@ -151,12 +155,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -166,7 +170,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -179,7 +183,7 @@
 # If there is an NLM target, put it here
 #
 TARGET_nlm = \
-	$(OBJDIR)\$(NLM_NAME).nlm \
+	$(OBJDIR)/$(NLM_NAME).nlm \
 	$(EOLIST)
 
 #
@@ -201,7 +205,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -244,7 +248,7 @@
 # Any additional imports go here
 #
 FILES_nlm_Ximports = \
-	@$(APR)/aprlib.imp \
+	@aprlib.imp \
 	@libc.imp \
 	$(EOLIST)
 
@@ -291,7 +295,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbd/NWGNUdbdsqli2 b/dbd/NWGNUdbdsqli2
index b9dff27..f7288be 100644
--- a/dbd/NWGNUdbdsqli2
+++ b/dbd/NWGNUdbdsqli2
@@ -11,7 +11,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #include $(APR)\build\NWGNUcustom.inc
@@ -38,8 +38,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(SQLITE2_INC) \
 			$(EOLIST)
@@ -150,12 +150,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -165,7 +165,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -200,7 +200,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -290,7 +290,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbd/NWGNUdbdsqli3 b/dbd/NWGNUdbdsqli3
index 7a94858..19a5204 100644
--- a/dbd/NWGNUdbdsqli3
+++ b/dbd/NWGNUdbdsqli3
@@ -11,7 +11,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #include $(APR)\build\NWGNUcustom.inc
@@ -38,8 +38,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(SQLITE3_INC) \
 			$(EOLIST)
@@ -150,12 +150,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -165,7 +165,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -200,7 +200,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -292,7 +292,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbd/NWGNUmakefile b/dbd/NWGNUmakefile
index fb4b9ad..b1e3e53 100644
--- a/dbd/NWGNUmakefile
+++ b/dbd/NWGNUmakefile
@@ -10,7 +10,7 @@
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
@@ -246,7 +246,7 @@
 # correct place.  (See $(AP_WORK)\build\NWGNUhead.inc for examples)
 #
 install :: nlms $(INSTDIRS) FORCE
-	copy $(OBJDIR)\*.nlm $(INSTALLBASE)
+	$(call COPY,$(OBJDIR)/*.nlm,$(INSTALLBASE))
 
 #
 # Any specialized rules here
@@ -257,6 +257,6 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
diff --git a/dbd/apr_dbd_odbc.c b/dbd/apr_dbd_odbc.c
index a393a29..3a97052 100644
--- a/dbd/apr_dbd_odbc.c
+++ b/dbd/apr_dbd_odbc.c
@@ -47,7 +47,7 @@
 #include <odbc/sqlext.h>
 #endif
 
- /* Driver name is "odbc" and the entry point is 'apr_dbd_odbc_driver' 
+/* Driver name is "odbc" and the entry point is 'apr_dbd_odbc_driver' 
  * unless ODBC_DRIVER_NAME is defined and it is linked with another db library which
  * is ODBC source-compatible. e.g. DB2, Informix, TimesTen, mysql.  
  */
@@ -64,11 +64,11 @@
 #define DRIVER_APU_VERSION_MAJOR APU_MAJOR_VERSION
 #define DRIVER_APU_VERSION_MINOR APU_MINOR_VERSION
 
-
 static SQLHANDLE henv = NULL;           /* ODBC ENV handle is process-wide */
 
 /* Use a CHECK_ERROR macro so we can grab the source line numbers
- * for error reports */
+ * for error reports
+ */
 static void check_error(apr_dbd_t *a, const char *step, SQLRETURN rc,
                  SQLSMALLINT type, SQLHANDLE h, int line);
 #define CHECK_ERROR(a,s,r,t,h)  check_error(a,s,r,t,h, __LINE__)
@@ -87,12 +87,15 @@
 #define BINARYMODE 0            /* used for binary (APR 1.3+) mode params */
 
 /* Identify datatypes which are LOBs 
- * - DB2 DRDA driver uses undefined types -98 and -99 for CLOB & BLOB */
+ * - DB2 DRDA driver uses undefined types -98 and -99 for CLOB & BLOB
+ */
 #define IS_LOB(t)  (t == SQL_LONGVARCHAR \
      || t == SQL_LONGVARBINARY || t == SQL_VARBINARY \
      || t == -98 || t == -99)
+
 /* These types are CLOBs 
- * - DB2 DRDA driver uses undefined type -98 for CLOB */
+ * - DB2 DRDA driver uses undefined type -98 for CLOB
+ */
 #define IS_CLOB(t) \
     (t == SQL_LONGVARCHAR || t == -98)
 
@@ -138,7 +141,8 @@
     int *all_data_fetched;      /* flags data as all fetched, for LOBs  */
     void *data;                 /* buffer for all data for one row */
 };
-enum                                /* results column states */
+
+enum                            /* results column states */
 {
     COL_AVAIL,                  /* data may be retrieved with SQLGetData */
     COL_PRESENT,                /* data has been retrieved with SQLGetData */
@@ -147,7 +151,8 @@
     COL_UNAVAIL                 /* column is unavailable because ODBC driver
                                  *  requires that columns be retrieved
                                  *  in ascending order and a higher col 
-                                 *  was accessed */
+                                 *  was accessed
+                                 */
 };
 
 struct apr_dbd_row_t {
@@ -169,7 +174,6 @@
     int nargs;
     int nvals;
     int *types;                 /* array of DBD data types */
-
 };
 
 static void odbc_lob_bucket_destroy(void *data);
@@ -187,7 +191,6 @@
     apr_bucket_shared_copy
 };
 
-
 /* ODBC LOB bucket data */
 typedef struct {
     /** Ref count for shared bucket */
@@ -197,10 +200,9 @@
     SQLSMALLINT type;
 } odbc_bucket;
 
-
 /* SQL datatype mappings to DBD datatypes 
  * These tables must correspond *exactly* to the apr_dbd_type_e enum 
- * in apr_dbd_internal.h 
+ * in apr_dbd.h
  */
 
 /* ODBC "C" types to DBD datatypes  */
@@ -229,6 +231,7 @@
     SQL_LONGVARCHAR,                /* APR_DBD_TYPE_CLOB,       \%pDc */
     SQL_TYPE_NULL                   /* APR_DBD_TYPE_NULL        \%pDn */
 };
+#define NUM_APR_DBD_TYPES (sizeof(sqlCtype) / sizeof(sqlCtype[0]))
 
 /*  ODBC Base types to DBD datatypes */
 static SQLSMALLINT const sqlBaseType[] = {
@@ -285,17 +288,18 @@
 };
 
 /*
-*   local functions
-*/
+ * local functions
+ */
 
 /* close any open results for the connection */
 static apr_status_t odbc_close_results(void *d)
-{   apr_dbd_results_t *dbr = (apr_dbd_results_t *) d;
+{
+    apr_dbd_results_t *dbr = (apr_dbd_results_t *)d;
     SQLRETURN rc = SQL_SUCCESS;
     
     if (dbr && dbr->apr_dbd && dbr->apr_dbd->dbc) {
-    	if (!dbr->isclosed) 
-        	rc = SQLCloseCursor(dbr->stmt);
+    	if (!dbr->isclosed)
+            rc = SQLCloseCursor(dbr->stmt);
     	dbr->isclosed = 1;
     }
     return APR_FROM_SQL_RESULT(rc);
@@ -306,6 +310,7 @@
 {   
     SQLRETURN rc = APR_SUCCESS;
     apr_dbd_prepared_t *statement = s;
+
     /* stmt is closed if connection has already been closed */
     if (statement) {
         SQLHANDLE hstmt = statement->stmt;
@@ -336,7 +341,7 @@
 /* odbc_close re-defined for passing to pool cleanup */
 static apr_status_t odbc_close_cleanup(void *handle)
 {
-    return odbc_close( (apr_dbd_t *) handle);
+    return odbc_close((apr_dbd_t *)handle);
 }
 
 /* close the ODBC environment handle at process termination */
@@ -350,26 +355,29 @@
 }
 
 /* setup the arrays in results for all the returned columns */
-static SQLRETURN odbc_set_result_column(int icol, apr_dbd_results_t * res, 
-                                         SQLHANDLE stmt)
+static SQLRETURN odbc_set_result_column(int icol, apr_dbd_results_t *res, 
+                                        SQLHANDLE stmt)
 {
     SQLRETURN rc;
     int maxsize, textsize, realsize, type, isunsigned = 1;
 
-     /* discover the sql type */
+    /* discover the sql type */
     rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_UNSIGNED, NULL, 0, NULL,
-                         (SQLPOINTER) &isunsigned);
+                         (SQLPOINTER)&isunsigned);
     isunsigned = (isunsigned == SQL_TRUE);
 
     rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_TYPE, NULL, 0, NULL,
-                         (SQLPOINTER) &type);
-    if (!SQL_SUCCEEDED(rc) || type == SQL_UNKNOWN_TYPE)
+                         (SQLPOINTER)&type);
+    if (!SQL_SUCCEEDED(rc) || type == SQL_UNKNOWN_TYPE) {
         /* MANY ODBC v2 datasources only supply CONCISE_TYPE */
         rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_CONCISE_TYPE, NULL,
-                             0, NULL, (SQLPOINTER) &type);
-    if (!SQL_SUCCEEDED(rc))
+                             0, NULL, (SQLPOINTER)&type);
+    }
+
+    if (!SQL_SUCCEEDED(rc)) {
         /* if still unknown make it CHAR */
         type = SQL_C_CHAR;
+    }
 
     switch (type) {
     case SQL_INTEGER:
@@ -405,28 +413,31 @@
 
     /* size if retrieved as text */
     rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0,
-                         NULL, (SQLPOINTER) & textsize);
-     if (!SQL_SUCCEEDED(rc) || textsize < 0)
+                         NULL, (SQLPOINTER)&textsize);
+    if (!SQL_SUCCEEDED(rc) || textsize < 0) {
         textsize = res->apr_dbd->defaultBufferSize;
+    }
     /* for null-term, which sometimes isn't included */
     textsize++;
 
     /* real size */
     rc = SQLColAttribute(stmt, icol + 1, SQL_DESC_OCTET_LENGTH, NULL, 0,
-                         NULL, (SQLPOINTER) & realsize);
-    if (!SQL_SUCCEEDED(rc))
+                         NULL, (SQLPOINTER)&realsize);
+    if (!SQL_SUCCEEDED(rc)) {
         realsize = textsize;
+    }
 
     maxsize = (textsize > realsize) ? textsize : realsize;
-    if ( IS_LOB(type) || maxsize <= 0) {
+    if (IS_LOB(type) || maxsize <= 0) {
         /* LOB types are never bound and have a NULL colptr for binary.
          * Ingore their real (1-2gb) length & use a default - the larger
          * of defaultBufferSize or APR_BUCKET_BUFF_SIZE.
          * If not a LOB, but simply unknown length - always use defaultBufferSize.
          */
         maxsize = res->apr_dbd->defaultBufferSize;
-        if ( IS_LOB(type) && maxsize < APR_BUCKET_BUFF_SIZE )
+        if (IS_LOB(type) && maxsize < APR_BUCKET_BUFF_SIZE) {
             maxsize = APR_BUCKET_BUFF_SIZE;
+        }
 
         res->colptrs[icol] =  NULL;
         res->colstate[icol] = COL_AVAIL;
@@ -440,14 +451,15 @@
             /* we are allowed to call SQLGetData if we need to */
             rc = SQLBindCol(stmt, icol + 1, res->coltypes[icol], 
                             res->colptrs[icol], maxsize, 
-                            &(res->colinds[icol]) );
+                            &(res->colinds[icol]));
             CHECK_ERROR(res->apr_dbd, "SQLBindCol", rc, SQL_HANDLE_STMT,
                         stmt);
             res->colstate[icol] = SQL_SUCCEEDED(rc) ? COL_BOUND : COL_AVAIL;
         }
         else {
             /* this driver won't allow us to call SQLGetData on bound 
-             * columns - so don't bind any */
+             * columns - so don't bind any
+             */
             res->colstate[icol] = COL_AVAIL;
             rc = SQL_SUCCESS;
         }
@@ -456,9 +468,9 @@
 }
 
 /* create and populate an apr_dbd_results_t for a select */
-static SQLRETURN odbc_create_results(apr_dbd_t * handle, SQLHANDLE hstmt,
-                                     apr_pool_t * pool, const int random,
-                                     apr_dbd_results_t ** res)
+static SQLRETURN odbc_create_results(apr_dbd_t *handle, SQLHANDLE hstmt,
+                                     apr_pool_t *pool, const int random,
+                                     apr_dbd_results_t **res)
 {
     SQLRETURN rc;
     SQLSMALLINT ncols;
@@ -473,7 +485,7 @@
     CHECK_ERROR(handle, "SQLNumResultCols", rc, SQL_HANDLE_STMT, hstmt);
     (*res)->ncols = ncols;
 
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         int i;
 
         (*res)->colnames = apr_pcalloc(pool, ncols * sizeof(char *));
@@ -484,16 +496,17 @@
         (*res)->colstate = apr_pcalloc(pool, ncols * sizeof(int));
         (*res)->ncols = ncols;
 
-        for (i = 0 ; i < ncols ; i++)
+        for (i = 0; i < ncols; i++) {
             odbc_set_result_column(i, (*res), hstmt);
         }
+    }
     return rc;
 }
 
 
 /* bind a parameter - input params only, does not support output parameters */
-static SQLRETURN odbc_bind_param(apr_pool_t * pool,
-                                 apr_dbd_prepared_t * statement, const int narg,
+static SQLRETURN odbc_bind_param(apr_pool_t *pool,
+                                 apr_dbd_prepared_t *statement, const int narg,
                                  const SQLSMALLINT type, int *argp,
                                  const void **args, const int textmode)
 {
@@ -516,13 +529,17 @@
     }
     /* bind a non-NULL data value */
     else {
+        if (type < 0 || type >= NUM_APR_DBD_TYPES) {
+            return APR_EGENERAL;
+        }
+
         baseType = sqlBaseType[type];
         cType = sqlCtype[type];
         indicator = NULL;
         /* LOBs */
         if (IS_LOB(cType)) {
-            ptr = (void *) args[*argp];
-            len = (SQLULEN) * (apr_size_t *) args[*argp + 1];
+            ptr = (void *)args[*argp];
+            len = (SQLULEN) * (apr_size_t *)args[*argp + 1];
             cType = (IS_CLOB(cType)) ? SQL_C_CHAR : SQL_C_DEFAULT;
             (*argp) += 4;  /* LOBs consume 4 args (last two are unused) */
         }
@@ -533,48 +550,48 @@
             case SQL_DATE:
             case SQL_TIME:
             case SQL_TIMESTAMP:
-                ptr = (void *) args[*argp];
-                len = (SQLULEN) strlen(ptr);
+                ptr = (void *)args[*argp];
+                len = (SQLULEN)strlen(ptr);
                 break;
             case SQL_TINYINT:
                 ptr = apr_palloc(pool, sizeof(unsigned char));
                 len = sizeof(unsigned char);
-                *(unsigned char *) ptr =
+                *(unsigned char *)ptr =
                     (textmode ?
-                     atoi(args[*argp]) : *(unsigned char *) args[*argp]);
+                     atoi(args[*argp]) : *(unsigned char *)args[*argp]);
                 break;
             case SQL_SMALLINT:
                 ptr = apr_palloc(pool, sizeof(short));
                 len = sizeof(short);
-                *(short *) ptr =
-                    (textmode ? atoi(args[*argp]) : *(short *) args[*argp]);
+                *(short *)ptr =
+                    (textmode ? atoi(args[*argp]) : *(short *)args[*argp]);
                 break;
             case SQL_INTEGER:
                 ptr = apr_palloc(pool, sizeof(int));
                 len = sizeof(int);
-                *(long *) ptr =
-                    (textmode ? atol(args[*argp]) : *(long *) args[*argp]);
+                *(long *)ptr =
+                    (textmode ? atol(args[*argp]) : *(long *)args[*argp]);
                 break;
             case SQL_FLOAT:
                 ptr = apr_palloc(pool, sizeof(float));
                 len = sizeof(float);
-                *(float *) ptr =
+                *(float *)ptr =
                     (textmode ?
-                     (float) atof(args[*argp]) : *(float *) args[*argp]);
+                     (float)atof(args[*argp]) : *(float *)args[*argp]);
                 break;
             case SQL_DOUBLE:
                 ptr = apr_palloc(pool, sizeof(double));
                 len = sizeof(double);
-                *(double *) ptr =
+                *(double *)ptr =
                     (textmode ? atof(args[*argp]) : *(double *)
                      args[*argp]);
                 break;
             case SQL_BIGINT:
                 ptr = apr_palloc(pool, sizeof(apr_int64_t));
                 len = sizeof(apr_int64_t);
-                *(apr_int64_t *) ptr =
+                *(apr_int64_t *)ptr =
                     (textmode ?
-                     apr_atoi64(args[*argp]) : *(apr_int64_t *) args[*argp]);
+                     apr_atoi64(args[*argp]) : *(apr_int64_t *)args[*argp]);
                 break;
             default:
                 return APR_EGENERAL;
@@ -591,8 +608,6 @@
 
 /* LOB / Bucket Brigade functions */
 
-
-
 /* bucket type specific destroy */
 static void odbc_lob_bucket_destroy(void *data)
 {
@@ -605,7 +620,7 @@
 /* set aside a bucket if possible */
 static apr_status_t odbc_lob_bucket_setaside(apr_bucket *e, apr_pool_t *pool)
 {
-    odbc_bucket *bd = (odbc_bucket *) e->data;
+    odbc_bucket *bd = (odbc_bucket *)e->data;
 
     /* Unlikely - but if the row pool is ancestor of this pool then it is OK */
     if (apr_pool_is_ancestor(bd->row->pool, pool))
@@ -621,7 +636,7 @@
     SQLRETURN rc;
     SQLLEN len_indicator;
     SQLSMALLINT type;
-    odbc_bucket *bd = (odbc_bucket *) e->data;
+    odbc_bucket *bd = (odbc_bucket *)e->data;
     apr_bucket *nxt;
     void *buf;
     int bufsize = bd->row->res->apr_dbd->defaultBufferSize;
@@ -633,9 +648,9 @@
 
     /* LOB buffers are always at least APR_BUCKET_BUFF_SIZE, 
      *   but they may be much bigger per the BUFSIZE parameter.
-    */
+     */
     if (bufsize < APR_BUCKET_BUFF_SIZE)
-            bufsize = APR_BUCKET_BUFF_SIZE;
+        bufsize = APR_BUCKET_BUFF_SIZE;
 
     buf = apr_bucket_alloc(bufsize, e->list);
     *str = NULL;
@@ -654,7 +669,7 @@
     if (SQL_SUCCEEDED(rc) || rc == SQL_NO_DATA) {
 
         if (rc == SQL_SUCCESS_WITH_INFO
-            && ( len_indicator == SQL_NO_TOTAL || len_indicator >= bufsize) ) {
+            && (len_indicator == SQL_NO_TOTAL || len_indicator >= bufsize)) {
             /* not the last read = a full buffer. CLOBs have a null terminator */
             *len = bufsize - (IS_CLOB(bd->type) ? 1 : 0 );
 
@@ -666,8 +681,8 @@
              * We try to handle both interpretations.
              */
             *len =  (len_indicator > bufsize 
-                     && len_indicator >= (SQLLEN) e->start)
-                ? (len_indicator - (SQLLEN) e->start) : len_indicator;
+                     && len_indicator >= (SQLLEN)e->start)
+                ? (len_indicator - (SQLLEN)e->start) : len_indicator;
 
             eos = 1;
         }
@@ -706,12 +721,10 @@
     odbc_bucket *bd = apr_bucket_alloc(sizeof(odbc_bucket), list);
     apr_bucket *eos = apr_bucket_eos_create(list);
     
-
     bd->row = row;
     bd->col = col;
     bd->type = type;
 
-
     APR_BUCKET_INIT(b);
     b->type = &odbc_bucket_type;
     b->free = apr_bucket_free;
@@ -726,7 +739,8 @@
 }
 
 /* returns a data pointer for a column,  returns NULL for NULL value,
- * return -1 if data not available */
+ * return -1 if data not available
+ */
 static void *odbc_get(const apr_dbd_row_t *row, const int col, 
                       const SQLSMALLINT sqltype)
 {
@@ -736,11 +750,13 @@
     int options = row->res->apr_dbd->dboptions;
 
     switch (state) {
-    case (COL_UNAVAIL) : return (void *) -1;
-    case (COL_RETRIEVED) :  return NULL;
+    case (COL_UNAVAIL):
+        return (void *)-1;
+    case (COL_RETRIEVED):
+        return NULL;
 
-    case (COL_BOUND) :
-    case (COL_PRESENT) : 
+    case (COL_BOUND):
+    case (COL_PRESENT): 
         if (sqltype == row->res->coltypes[col]) {
             /* same type and we already have the data */
             row->res->colstate[col] = COL_RETRIEVED;
@@ -752,7 +768,8 @@
     /* we need to get the data now */
     if (!(options & SQL_GD_ANY_ORDER)) {
         /* this ODBC driver requires columns to be retrieved in order,
-         * so we attempt to get every prior un-gotten non-LOB column */
+         * so we attempt to get every prior un-gotten non-LOB column
+         */
         int i;
         for (i = 0; i < col; i++) {
             if (row->res->colstate[i] == COL_AVAIL) {
@@ -768,7 +785,7 @@
 
     if ((state == COL_BOUND && !(options & SQL_GD_BOUND)))
         /* this driver won't let us re-get bound columns */
-        return (void *) -1;
+        return (void *)-1;
 
     /* a LOB might not have a buffer allocated yet - so create one */
     if (!row->res->colptrs[col])
@@ -785,12 +802,14 @@
         /* whatever it was originally, it is now this sqltype */
         row->res->coltypes[col] = sqltype;
         /* this allows getting CLOBs in text mode by calling get_entry
-         *   until it returns NULL */
+         *   until it returns NULL
+         */
         row->res->colstate[col] = 
             (rc == SQL_SUCCESS_WITH_INFO) ? COL_AVAIL : COL_RETRIEVED;
         return row->res->colptrs[col];
     }
-    else  return (void *) -1;
+    else
+        return (void *)-1;
 }
 
 /* Parse the parameter string for open */
@@ -800,8 +819,8 @@
                                int *defaultBufferSize, int *nattrs,
                                int **attrs, int **attrvals)
 {
-    char *seps, *last, *name[MAX_PARAMS], *val[MAX_PARAMS];
-    int nparams=0, i, j;
+    char *seps, *last, *next, *name[MAX_PARAMS], *val[MAX_PARAMS];
+    int nparams = 0, i, j;
 
     *attrs = apr_pcalloc(pool, MAX_PARAMS * sizeof(char *));
     *attrvals = apr_pcalloc(pool, MAX_PARAMS * sizeof(int));
@@ -820,42 +839,56 @@
         }
         val[nparams] = apr_strtok(NULL, seps, &last);
         seps = DEFAULTSEPS;
-        name[++nparams] = apr_strtok(NULL, seps, &last);
-    } while ( nparams <= MAX_PARAMS && name[nparams] != NULL);
 
-    for(j=i=0 ; i< nparams ; i++)
-    {   if      (!apr_strnatcasecmp(name[i], "CONNECT"))
-        {   *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
-            *connect=1;
+        ++nparams;
+        next = apr_strtok(NULL, seps, &last);
+        if (!next) {
+            break;
         }
-        else if (!apr_strnatcasecmp(name[i], "DATASOURCE"))
-        {   *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
-            *connect=0;
+        if (nparams >= MAX_PARAMS) {
+            /* too many parameters, no place to store */
+            return APR_EGENERAL;
         }
-        else if (!apr_strnatcasecmp(name[i], "USER"))
+        name[nparams] = next;
+    } while (1);
+
+    for (j = i = 0; i < nparams; i++) {
+        if (!apr_strnatcasecmp(name[i], "CONNECT")) {
+            *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
+            *connect = 1;
+        }
+        else if (!apr_strnatcasecmp(name[i], "DATASOURCE")) {
+            *datasource = (SQLCHAR *)apr_pstrdup(pool, val[i]);
+            *connect = 0;
+        }
+        else if (!apr_strnatcasecmp(name[i], "USER")) {
             *user = (SQLCHAR *)apr_pstrdup(pool, val[i]);
-        else if (!apr_strnatcasecmp(name[i], "PASSWORD"))
+        }
+        else if (!apr_strnatcasecmp(name[i], "PASSWORD")) {
             *password = (SQLCHAR *)apr_pstrdup(pool, val[i]);
-        else if (!apr_strnatcasecmp(name[i], "BUFSIZE"))
+        }
+        else if (!apr_strnatcasecmp(name[i], "BUFSIZE")) {
             *defaultBufferSize = atoi(val[i]);
-        else if (!apr_strnatcasecmp(name[i], "ACCESS"))
-        {   if  (!apr_strnatcasecmp(val[i], "READ_ONLY"))
+        }
+        else if (!apr_strnatcasecmp(name[i], "ACCESS")) {
+            if (!apr_strnatcasecmp(val[i], "READ_ONLY"))
                 (*attrvals)[j] = SQL_MODE_READ_ONLY;
             else if (!apr_strnatcasecmp(val[i], "READ_WRITE"))
                 (*attrvals)[j] = SQL_MODE_READ_WRITE;
-            else return SQL_ERROR;
+            else
+                return SQL_ERROR;
             (*attrs)[j++] = SQL_ATTR_ACCESS_MODE;
         }
-        else if (!apr_strnatcasecmp(name[i], "CTIMEOUT"))
-        {   (*attrvals)[j] = atoi(val[i]);
+        else if (!apr_strnatcasecmp(name[i], "CTIMEOUT")) {
+            (*attrvals)[j] = atoi(val[i]);
             (*attrs)[j++] = SQL_ATTR_LOGIN_TIMEOUT;
         }
-        else if (!apr_strnatcasecmp(name[i], "STIMEOUT"))
-        {   (*attrvals)[j] = atoi(val[i]);
+        else if (!apr_strnatcasecmp(name[i], "STIMEOUT")) {
+            (*attrvals)[j] = atoi(val[i]);
             (*attrs)[j++] = SQL_ATTR_CONNECTION_TIMEOUT;
         }
-        else if (!apr_strnatcasecmp(name[i], "TXMODE"))
-        {   if      (!apr_strnatcasecmp(val[i], "READ_UNCOMMITTED"))
+        else if (!apr_strnatcasecmp(name[i], "TXMODE")) {
+            if (!apr_strnatcasecmp(val[i], "READ_UNCOMMITTED"))
                 (*attrvals)[j] = SQL_TXN_READ_UNCOMMITTED;
             else if (!apr_strnatcasecmp(val[i], "READ_COMMITTED"))
                 (*attrvals)[j] = SQL_TXN_READ_COMMITTED;
@@ -865,10 +898,12 @@
                 (*attrvals)[j] = SQL_TXN_SERIALIZABLE;
             else if (!apr_strnatcasecmp(val[i], "DEFAULT"))
                 continue;
-            else return SQL_ERROR;
+            else
+                return SQL_ERROR;
             (*attrs)[j++] = SQL_ATTR_TXN_ISOLATION;
         }
-        else return SQL_ERROR;
+        else
+            return SQL_ERROR;
     }
     *nattrs = j;
     return (*datasource && *defaultBufferSize) ? APR_SUCCESS : SQL_ERROR;
@@ -882,48 +917,63 @@
     SQLCHAR sqlstate[128];
     SQLINTEGER native;
     SQLSMALLINT reslength;
-    char *res, *p, *end, *logval=NULL;
+    char *res, *p, *end, *logval = NULL;
     int i;
-    apr_status_t r;
 
     /* set info about last error in dbc  - fast return for SQL_SUCCESS  */
     if (rc == SQL_SUCCESS) {
         char successMsg[] = "[dbd_odbc] SQL_SUCCESS ";
+        apr_size_t successMsgLen = sizeof successMsg - 1;
+
         dbc->lasterrorcode = SQL_SUCCESS;
-        strcpy(dbc->lastError, successMsg);
-        strcpy(dbc->lastError+sizeof(successMsg)-1, step);
+        apr_cpystrn(dbc->lastError, successMsg, sizeof dbc->lastError);
+        apr_cpystrn(dbc->lastError + successMsgLen, step,
+                    sizeof dbc->lastError - successMsgLen);
         return;
     }
     switch (rc) {
-        case SQL_INVALID_HANDLE     : { res = "SQL_INVALID_HANDLE"; break; }
-        case SQL_ERROR              : { res = "SQL_ERROR"; break; }   
-        case SQL_SUCCESS_WITH_INFO  : { res = "SQL_SUCCESS_WITH_INFO"; break; }
-        case SQL_STILL_EXECUTING    : { res = "SQL_STILL_EXECUTING"; break; }
-        case SQL_NEED_DATA          : { res = "SQL_NEED_DATA"; break; }
-        case SQL_NO_DATA            : { res = "SQL_NO_DATA"; break; }
-        default                     : { res = "unrecognized SQL return code"; }
+    case SQL_INVALID_HANDLE:
+        res = "SQL_INVALID_HANDLE";
+        break;
+    case SQL_ERROR:
+        res = "SQL_ERROR";
+        break;
+    case SQL_SUCCESS_WITH_INFO:
+        res = "SQL_SUCCESS_WITH_INFO";
+        break;
+    case SQL_STILL_EXECUTING:
+        res = "SQL_STILL_EXECUTING";
+        break;
+    case SQL_NEED_DATA:
+        res = "SQL_NEED_DATA";
+        break;
+    case SQL_NO_DATA:
+        res = "SQL_NO_DATA";
+        break;
+    default:
+        res = "unrecognized SQL return code";
     }
     /* these two returns are expected during normal execution */
     if (rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA 
-        && dbc->can_commit != APR_DBD_TRANSACTION_IGNORE_ERRORS)
-    {
+        && dbc->can_commit != APR_DBD_TRANSACTION_IGNORE_ERRORS) {
         dbc->can_commit = APR_DBD_TRANSACTION_ROLLBACK;
     }
     p = dbc->lastError;
     end = p + sizeof(dbc->lastError);
     dbc->lasterrorcode = rc;
     p += sprintf(p, "[dbd_odbc] %.64s returned %.30s (%d) at %.24s:%d ",
-                 step, res, rc, SOURCE_FILE, line-1);
-    for (i=1, rc=0 ; rc==0 ; i++) {
+                 step, res, rc, SOURCE_FILE, line - 1);
+    for (i = 1, rc = 0; rc == 0; i++) {
         rc = SQLGetDiagRec(type, h, i, sqlstate, &native, buffer, 
                             sizeof(buffer), &reslength);
-        if (SQL_SUCCEEDED(rc) && (p < (end-280))) 
+        if (SQL_SUCCEEDED(rc) && (p < (end - 280))) 
             p += sprintf(p, "%.256s %.20s ", buffer, sqlstate);
     }
-    r = apr_env_get(&logval, "apr_dbd_odbc_log", dbc->pool);
+    apr_env_get(&logval, "apr_dbd_odbc_log", dbc->pool);
     /* if env var was set or call was init/open (no dbname) - log to stderr */
     if (logval || !dbc->dbname ) {
         char timestamp[APR_CTIME_LEN];
+
         apr_file_t *se;
         apr_ctime(timestamp, apr_time_now());
         apr_file_open_stderr(&se, dbc->pool);
@@ -935,14 +985,16 @@
 {
     if (handle->can_commit == APR_DBD_TRANSACTION_ROLLBACK) {
         handle->lasterrorcode = SQL_ERROR;
-        strcpy(handle->lastError, "[dbd_odbc] Rollback pending ");
+        apr_cpystrn(handle->lastError, "[dbd_odbc] Rollback pending ",
+                    sizeof handle->lastError);
         return 1;
     }
     return 0;
 }
+
 /*
-*   public functions per DBD driver API
-*/
+ *   public functions per DBD driver API
+ */
 
 /** init: allow driver to perform once-only initialisation. **/
 static void odbc_init(apr_pool_t *pool)
@@ -970,13 +1022,13 @@
     step = "SQLAllocHandle (SQL_HANDLE_ENV)";
     rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
     apr_pool_cleanup_register(pool, henv, odbc_close_env, apr_pool_cleanup_null);
-    if (SQL_SUCCEEDED(rc))
-    {   step = "SQLSetEnvAttr";
+    if (SQL_SUCCEEDED(rc)) {
+        step = "SQLSetEnvAttr";
         rc = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,
-                          (SQLPOINTER) SQL_OV_ODBC3, 0);
+                          (SQLPOINTER)SQL_OV_ODBC3, 0);
     }
-    else
-    {   apr_dbd_t tmp_dbc;
+    else {
+        apr_dbd_t tmp_dbc;
         SQLHANDLE err_h = henv;
 
         tmp_dbc.pool = pool;
@@ -986,37 +1038,38 @@
 }
 
 /** native_handle: return the native database handle of the underlying db **/
-static void* odbc_native_handle(apr_dbd_t *handle)
-{   return handle->dbc;
+static void *odbc_native_handle(apr_dbd_t *handle)
+{
+    return handle->dbc;
 }
 
 /** open: obtain a database connection from the server rec. **/
 
 /* It would be more efficient to allocate a single statement handle 
-    here - but SQL_ATTR_CURSOR_SCROLLABLE must be set before
-    SQLPrepare, and we don't know whether random-access is
-    specified until SQLExecute so we cannot.
-*/
+ * here - but SQL_ATTR_CURSOR_SCROLLABLE must be set before
+ * SQLPrepare, and we don't know whether random-access is
+ * specified until SQLExecute so we cannot.
+ */
 
-static apr_dbd_t* odbc_open(apr_pool_t *pool, const char *params, const char **error)
+static apr_dbd_t *odbc_open(apr_pool_t *pool, const char *params, const char **error)
 {
-    SQLRETURN   rc;
-    SQLHANDLE   hdbc = NULL;
-    apr_dbd_t   *handle;
+    SQLRETURN rc;
+    SQLHANDLE hdbc = NULL;
+    apr_dbd_t *handle;
     char *err_step;
     int err_htype, i;
-    int defaultBufferSize=DEFAULT_BUFFER_SIZE;
+    int defaultBufferSize = DEFAULT_BUFFER_SIZE;
     SQLHANDLE err_h = NULL;
-    SQLCHAR  *datasource=(SQLCHAR *)"", *user=(SQLCHAR *)"",
-             *password=(SQLCHAR *)"";
-    int nattrs=0, *attrs=NULL, *attrvals=NULL, connect=0;
+    SQLCHAR  *datasource = (SQLCHAR *)"", *user = (SQLCHAR *)"",
+             *password = (SQLCHAR *)"";
+    int nattrs = 0, *attrs = NULL, *attrvals = NULL, connect = 0;
 
-    err_step="SQLAllocHandle (SQL_HANDLE_DBC)";
+    err_step = "SQLAllocHandle (SQL_HANDLE_DBC)";
     err_htype = SQL_HANDLE_ENV;
     err_h = henv;
     rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
     if (SQL_SUCCEEDED(rc)) {
-        err_step="Invalid DBD Parameters - open";
+        err_step = "Invalid DBD Parameters - open";
         err_htype = SQL_HANDLE_DBC;
         err_h = hdbc;
         rc = odbc_parse_params(pool, params, &connect, &datasource, &user,
@@ -1024,32 +1077,33 @@
                                &attrvals);
     }
     if (SQL_SUCCEEDED(rc)) {
-        for (i=0 ; i < nattrs && SQL_SUCCEEDED(rc); i++) {
-            err_step="SQLSetConnectAttr (from DBD Parameters)";
+        for (i = 0; i < nattrs && SQL_SUCCEEDED(rc); i++) {
+            err_step = "SQLSetConnectAttr (from DBD Parameters)";
             err_htype = SQL_HANDLE_DBC;
             err_h = hdbc;
-            rc = SQLSetConnectAttr(hdbc, attrs[i], (SQLPOINTER) attrvals[i], 0);
+            rc = SQLSetConnectAttr(hdbc, attrs[i], (SQLPOINTER)attrvals[i], 0);
         }
     }
     if (SQL_SUCCEEDED(rc)) {
         if (connect) {
             SQLCHAR out[1024];
             SQLSMALLINT outlen;
-            err_step="SQLDriverConnect";
+
+            err_step = "SQLDriverConnect";
             err_htype = SQL_HANDLE_DBC;
             err_h = hdbc;
             rc = SQLDriverConnect(hdbc, NULL, datasource,
-                        (SQLSMALLINT) strlen((char *)datasource),
+                        (SQLSMALLINT)strlen((char *)datasource),
                         out, sizeof(out), &outlen, SQL_DRIVER_NOPROMPT);
         }
         else {
-            err_step="SQLConnect";
+            err_step = "SQLConnect";
             err_htype = SQL_HANDLE_DBC;
             err_h = hdbc;
             rc = SQLConnect(hdbc, datasource,
-                        (SQLSMALLINT) strlen((char *)datasource),
-                        user, (SQLSMALLINT) strlen((char *)user),
-                        password, (SQLSMALLINT) strlen((char *)password));
+                        (SQLSMALLINT)strlen((char *)datasource),
+                        user, (SQLSMALLINT)strlen((char *)user),
+                        password, (SQLSMALLINT)strlen((char *)password));
         }
     }
     if (SQL_SUCCEEDED(rc)) {
@@ -1071,6 +1125,7 @@
     }
     else {
         apr_dbd_t tmp_dbc;
+
         tmp_dbc.pool = pool;
         tmp_dbc.dbname = NULL;
         CHECK_ERROR(&tmp_dbc, err_step, rc, err_htype, err_h);
@@ -1099,9 +1154,8 @@
     return (isDead == SQL_CD_FALSE) ? APR_SUCCESS : APR_EGENERAL;
 }
 
-
 /** set_dbname: select database name.  May be a no-op if not supported. **/
-static int odbc_set_dbname(apr_pool_t* pool, apr_dbd_t *handle,
+static int odbc_set_dbname(apr_pool_t*pool, apr_dbd_t *handle,
                            const char *name)
 {
     if (apr_strnatcmp(name, handle->dbname)) {
@@ -1120,18 +1174,18 @@
 
     if (handle->transaction_mode) {
         rc = SQLSetConnectAttr(handle->dbc, SQL_ATTR_TXN_ISOLATION,
-                               (SQLPOINTER) handle->transaction_mode, 0);
+                               (SQLPOINTER)handle->transaction_mode, 0);
         CHECK_ERROR(handle, "SQLSetConnectAttr (SQL_ATTR_TXN_ISOLATION)", rc,
                     SQL_HANDLE_DBC, handle->dbc);
     }
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         /* turn off autocommit for transactions */
         rc = SQLSetConnectAttr(handle->dbc, SQL_ATTR_AUTOCOMMIT,
                                SQL_AUTOCOMMIT_OFF, 0);
         CHECK_ERROR(handle, "SQLSetConnectAttr (SQL_ATTR_AUTOCOMMIT)", rc,
                     SQL_HANDLE_DBC, handle->dbc);
     }
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         *trans = apr_palloc(pool, sizeof(apr_dbd_transaction_t));
         (*trans)->dbc = handle->dbc;
         (*trans)->apr_dbd = handle;
@@ -1140,7 +1194,6 @@
     return APR_FROM_SQL_RESULT(rc);
 }
 
-
 /** end_transaction: end a transaction **/
 static int odbc_end_transaction(apr_dbd_transaction_t *trans)
 {
@@ -1150,9 +1203,9 @@
 
     rc = SQLEndTran(SQL_HANDLE_DBC, trans->dbc, action);
     CHECK_ERROR(trans->apr_dbd, "SQLEndTran", rc, SQL_HANDLE_DBC, trans->dbc);
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         rc = SQLSetConnectAttr(trans->dbc, SQL_ATTR_AUTOCOMMIT,
-                               (SQLPOINTER) SQL_AUTOCOMMIT_ON, 0);
+                               (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);
         CHECK_ERROR(trans->apr_dbd, "SQLSetConnectAttr (SQL_ATTR_AUTOCOMMIT)",
                     rc, SQL_HANDLE_DBC, trans->dbc);
     }
@@ -1176,14 +1229,14 @@
     if (!SQL_SUCCEEDED(rc))
         return APR_FROM_SQL_RESULT(rc);
 
-    rc = SQLExecDirect(hstmt, (SQLCHAR *) statement, (SQLINTEGER) len);
+    rc = SQLExecDirect(hstmt, (SQLCHAR *)statement, (SQLINTEGER)len);
     CHECK_ERROR(handle, "SQLExecDirect", rc, SQL_HANDLE_STMT, hstmt);
 
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         SQLLEN rowcount;
 
         rc = SQLRowCount(hstmt, &rowcount);
-        *nrows = (int) rowcount;
+        *nrows = (int)rowcount;
         CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT, hstmt);
     }
 
@@ -1210,8 +1263,8 @@
     if (!SQL_SUCCEEDED(rc))
         return APR_FROM_SQL_RESULT(rc);
     /* Prepare an apr_dbd_prepared_t for pool cleanup, even though this
-    *  is not a prepared statement.  We want the same cleanup mechanism.
-    */
+     * is not a prepared statement.  We want the same cleanup mechanism.
+     */
     stmt = apr_pcalloc(pool, sizeof(apr_dbd_prepared_t));
     stmt->apr_dbd = handle;
     stmt->dbc = handle->dbc;
@@ -1219,15 +1272,15 @@
     apr_pool_cleanup_register(pool, stmt, odbc_close_pstmt, apr_pool_cleanup_null);
     if (random) {
         rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_SCROLLABLE,
-                            (SQLPOINTER) SQL_SCROLLABLE, 0);
+                            (SQLPOINTER)SQL_SCROLLABLE, 0);
         CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)", rc,
                     SQL_HANDLE_STMT, hstmt);
     }
-    if SQL_SUCCEEDED(rc) {
-        rc = SQLExecDirect(hstmt, (SQLCHAR *) statement, (SQLINTEGER) len);
+    if (SQL_SUCCEEDED(rc)) {
+        rc = SQLExecDirect(hstmt, (SQLCHAR *)statement, (SQLINTEGER)len);
         CHECK_ERROR(handle, "SQLExecDirect", rc, SQL_HANDLE_STMT, hstmt);
     }
-    if SQL_SUCCEEDED(rc) {
+    if (SQL_SUCCEEDED(rc)) {
         rc = odbc_create_results(handle, hstmt, pool, random, res);
         apr_pool_cleanup_register(pool, *res, 
                                   odbc_close_results, apr_pool_cleanup_null);
@@ -1249,12 +1302,12 @@
 
     rc = SQLRowCount(res->stmt, &nrows);
     CHECK_ERROR(res->apr_dbd, "SQLRowCount", rc, SQL_HANDLE_STMT, res->stmt);
-    return SQL_SUCCEEDED(rc) ? (int) nrows : -1;
+    return SQL_SUCCEEDED(rc) ? (int)nrows : -1;
 }
 
 /** get_row: get a row from a result set **/
-static int odbc_get_row(apr_pool_t * pool, apr_dbd_results_t * res,
-                        apr_dbd_row_t ** row, int rownum)
+static int odbc_get_row(apr_pool_t *pool, apr_dbd_results_t *res,
+                        apr_dbd_row_t **row, int rownum)
 {
     SQLRETURN rc;
     char *fetchtype;
@@ -1268,11 +1321,12 @@
 
     /* mark all the columns as needing SQLGetData unless they are bound  */
     for (c = 0; c < res->ncols; c++) {
-        if (res->colstate[c] != COL_BOUND)
+        if (res->colstate[c] != COL_BOUND) {
             res->colstate[c] = COL_AVAIL;
-            /* some drivers do not null-term zero-len CHAR data */
-            if (res->colptrs[c] )
-                * (char *) res->colptrs[c] = 0; 
+        }
+        /* some drivers do not null-term zero-len CHAR data */
+        if (res->colptrs[c])
+            *(char *)res->colptrs[c] = 0; 
     }
 
     if (res->random && (rownum > 0)) {
@@ -1287,7 +1341,8 @@
     (*row)->stmt = res->stmt;
     if (!SQL_SUCCEEDED(rc) && !res->random) {
         /* early close on any error (usually SQL_NO_DATA) if fetching
-         * sequentially to release resources ASAP */
+         * sequentially to release resources ASAP
+         */
         odbc_close_results(res);
         return -1;
     }
@@ -1295,20 +1350,22 @@
 }
 
 /** datum_get: get a binary entry from a row **/
-static apr_status_t odbc_datum_get(const apr_dbd_row_t * row, int col,
+static apr_status_t odbc_datum_get(const apr_dbd_row_t *row, int col,
                                    apr_dbd_type_e dbdtype, void *data)
 {
     SQLSMALLINT sqltype;
     void *p;
-    int len = sqlSizes[dbdtype];
+    int len;
 
     if (col >= row->res->ncols)
         return APR_EGENERAL;
 
-    if (dbdtype < 0 || dbdtype >= sizeof(sqlCtype)) {
+    if (dbdtype < 0 || dbdtype >= NUM_APR_DBD_TYPES) {
         data = NULL;            /* invalid type */
         return APR_EGENERAL;
     }
+
+    len = sqlSizes[dbdtype];
     sqltype = sqlCtype[dbdtype];
 
     /* must not memcpy a brigade, sentinals are relative to orig loc */
@@ -1316,14 +1373,14 @@
         return odbc_create_bucket(row, col, sqltype, data);
 
     p = odbc_get(row, col, sqltype);
-    if (p == (void *) -1)
+    if (p == (void *)-1)
         return APR_EGENERAL;
 
     if (p == NULL)
         return APR_ENOENT;          /* SQL NULL value */
     
     if (len < 0)
-        strcpy(data, p);
+       *(char**)data = (char *)p;
     else
         memcpy(data, p, len);
     
@@ -1332,7 +1389,7 @@
 }
 
 /** get_entry: get an entry from a row (string data) **/
-static const char *odbc_get_entry(const apr_dbd_row_t * row, int col)
+static const char *odbc_get_entry(const apr_dbd_row_t *row, int col)
 {
     void *p;
 
@@ -1342,47 +1399,48 @@
     p = odbc_get(row, col, SQL_C_CHAR);
 
     /* NULL or invalid (-1) */
-    if (p == NULL || p == (void *) -1)
+    if (p == NULL || p == (void *)-1)
         return p;     
     else
         return apr_pstrdup(row->pool, p);   
 }
 
 /** error: get current error message (if any) **/
-static const char* odbc_error(apr_dbd_t *handle, int errnum)
+static const char *odbc_error(apr_dbd_t *handle, int errnum)
 {   
     return (handle) ? handle->lastError : "[dbd_odbc]No error message available";
 }
 
 /** escape: escape a string so it is safe for use in query/select **/
-static const char* odbc_escape(apr_pool_t *pool, const char *s,
-                        apr_dbd_t *handle)
+static const char *odbc_escape(apr_pool_t *pool, const char *s,
+                               apr_dbd_t *handle)
 {   
     char *newstr, *src, *dst, *sq;
     int qcount;
 
     /* return the original if there are no single-quotes */
     if (!(sq = strchr(s, '\''))) 
-        return (char *) s;
+        return (char *)s;
     /* count the single-quotes and allocate a new buffer */
     for (qcount = 1; (sq = strchr(sq + 1, '\'')); )
         qcount++;
     newstr = apr_palloc(pool, strlen(s) + qcount + 1);
 
     /* move chars, doubling all single-quotes */
-    src = (char *) s;
-    for (dst = newstr ; *src ; src++) {
+    src = (char *)s;
+    for (dst = newstr; *src; src++) {
         if ((*dst++ = *src) == '\'')  
             *dst++ = '\'';
     }
     *dst = 0;
     return newstr;
 }
+
 /** prepare: prepare a statement **/
-static int odbc_prepare(apr_pool_t * pool, apr_dbd_t * handle,
+static int odbc_prepare(apr_pool_t *pool, apr_dbd_t *handle,
                         const char *query, const char *label, int nargs,
-                        int nvals, apr_dbd_type_e * types,
-                        apr_dbd_prepared_t ** statement)
+                        int nvals, apr_dbd_type_e *types,
+                        apr_dbd_prepared_t **statement)
 {
     SQLRETURN rc;
     size_t len = strlen(query);
@@ -1402,15 +1460,15 @@
                               odbc_close_pstmt, apr_pool_cleanup_null);
     CHECK_ERROR(handle, "SQLAllocHandle (STMT)", rc,
                 SQL_HANDLE_DBC, handle->dbc);
-    rc = SQLPrepare((*statement)->stmt, (SQLCHAR *) query, (SQLINTEGER) len);
+    rc = SQLPrepare((*statement)->stmt, (SQLCHAR *)query, (SQLINTEGER)len);
     CHECK_ERROR(handle, "SQLPrepare", rc, SQL_HANDLE_STMT,
                 (*statement)->stmt);
     return APR_FROM_SQL_RESULT(rc);
 }
 
 /** pquery: query using a prepared statement + args **/
-static int odbc_pquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
-                       apr_dbd_prepared_t * statement, const char **args)
+static int odbc_pquery(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
+                       apr_dbd_prepared_t *statement, const char **args)
 {
     SQLRETURN rc = SQL_SUCCESS;
     int i, argp;
@@ -1420,30 +1478,31 @@
 
     for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++) {
         rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
-                             &argp, (const void **) args, TEXTMODE);
+                             &argp, (const void **)args, TEXTMODE);
     }
     if (SQL_SUCCEEDED(rc)) {
         rc = SQLExecute(statement->stmt);
         CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     if (SQL_SUCCEEDED(rc)) {
         SQLLEN rowcount;
 
         rc = SQLRowCount(statement->stmt, &rowcount);
-        *nrows = (int) rowcount;
+        *nrows = (int)rowcount;
         CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     return APR_FROM_SQL_RESULT(rc);
 }
 
 /** pvquery: query using a prepared statement + args **/
-static int odbc_pvquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
-                        apr_dbd_prepared_t * statement, va_list args)
+static int odbc_pvquery(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
+                        apr_dbd_prepared_t *statement, va_list args)
 {
     const char **values;
     int i;
+
     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
     for (i = 0; i < statement->nvals; i++)
         values[i] = va_arg(args, const char *);
@@ -1451,9 +1510,9 @@
 }
 
 /** pselect: select using a prepared statement + args **/
-int odbc_pselect(apr_pool_t * pool, apr_dbd_t * handle,
-                 apr_dbd_results_t ** res, apr_dbd_prepared_t * statement,
-                 int random, const char **args)
+static int odbc_pselect(apr_pool_t *pool, apr_dbd_t *handle,
+                        apr_dbd_results_t **res, apr_dbd_prepared_t *statement,
+                        int random, const char **args)
 {
     SQLRETURN rc = SQL_SUCCESS;
     int i, argp;
@@ -1463,32 +1522,33 @@
 
     if (random) {
         rc = SQLSetStmtAttr(statement->stmt, SQL_ATTR_CURSOR_SCROLLABLE,
-                            (SQLPOINTER) SQL_SCROLLABLE, 0);
+                            (SQLPOINTER)SQL_SCROLLABLE, 0);
         CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)",
                     rc, SQL_HANDLE_STMT, statement->stmt);
     }
     if (SQL_SUCCEEDED(rc)) {
-        for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++)
+        for (i = argp = 0; i < statement->nargs && SQL_SUCCEEDED(rc); i++) {
             rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
-                                 &argp, (const void **) args, TEXTMODE);
+                                 &argp, (const void **)args, TEXTMODE);
         }
+    }
     if (SQL_SUCCEEDED(rc)) {
         rc = SQLExecute(statement->stmt);
         CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     if (SQL_SUCCEEDED(rc)) {
         rc = odbc_create_results(handle, statement->stmt, pool, random, res);
         apr_pool_cleanup_register(pool, *res,
                                   odbc_close_results, apr_pool_cleanup_null);
-        }
+    }
     return APR_FROM_SQL_RESULT(rc);
 }
 
 /** pvselect: select using a prepared statement + args **/
-static int odbc_pvselect(apr_pool_t * pool, apr_dbd_t * handle,
-                         apr_dbd_results_t ** res,
-                         apr_dbd_prepared_t * statement, int random,
+static int odbc_pvselect(apr_pool_t *pool, apr_dbd_t *handle,
+                         apr_dbd_results_t **res,
+                         apr_dbd_prepared_t *statement, int random,
                          va_list args)
 {
     const char **values;
@@ -1501,7 +1561,7 @@
 }
 
 /** get_name: get a column title from a result set **/
-static const char *odbc_get_name(const apr_dbd_results_t * res, int col)
+static const char *odbc_get_name(const apr_dbd_results_t *res, int col)
 {
     SQLRETURN rc;
     char buffer[MAX_COLUMN_NAME];
@@ -1522,13 +1582,13 @@
 }
 
 /** transaction_mode_get: get the mode of transaction **/
-static int odbc_transaction_mode_get(apr_dbd_transaction_t * trans)
+static int odbc_transaction_mode_get(apr_dbd_transaction_t *trans)
 {
-    return (int) trans->apr_dbd->can_commit;
+    return (int)trans->apr_dbd->can_commit;
 }
 
 /** transaction_mode_set: set the mode of transaction **/
-static int odbc_transaction_mode_set(apr_dbd_transaction_t * trans, int mode)
+static int odbc_transaction_mode_set(apr_dbd_transaction_t *trans, int mode)
 {
     int legal = (  APR_DBD_TRANSACTION_IGNORE_ERRORS
                  | APR_DBD_TRANSACTION_COMMIT
@@ -1542,8 +1602,8 @@
 }
 
 /** pbquery: query using a prepared statement + binary args **/
-static int odbc_pbquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
-                        apr_dbd_prepared_t * statement, const void **args)
+static int odbc_pbquery(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
+                        apr_dbd_prepared_t *statement, const void **args)
 {
     SQLRETURN rc = SQL_SUCCESS;
     int i, argp;
@@ -1559,22 +1619,22 @@
         rc = SQLExecute(statement->stmt);
         CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     if (SQL_SUCCEEDED(rc)) {
         SQLLEN rowcount;
 
         rc = SQLRowCount(statement->stmt, &rowcount);
-        *nrows = (int) rowcount;
+        *nrows = (int)rowcount;
         CHECK_ERROR(handle, "SQLRowCount", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     return APR_FROM_SQL_RESULT(rc);
 }
 
 /** pbselect: select using a prepared statement + binary args **/
-static int odbc_pbselect(apr_pool_t * pool, apr_dbd_t * handle,
-                         apr_dbd_results_t ** res,
-                         apr_dbd_prepared_t * statement,
+static int odbc_pbselect(apr_pool_t *pool, apr_dbd_t *handle,
+                         apr_dbd_results_t **res,
+                         apr_dbd_prepared_t *statement,
                          int random, const void **args)
 {
     SQLRETURN rc = SQL_SUCCESS;
@@ -1585,7 +1645,7 @@
 
     if (random) {
         rc = SQLSetStmtAttr(statement->stmt, SQL_ATTR_CURSOR_SCROLLABLE,
-                            (SQLPOINTER) SQL_SCROLLABLE, 0);
+                            (SQLPOINTER)SQL_SCROLLABLE, 0);
         CHECK_ERROR(handle, "SQLSetStmtAttr (SQL_ATTR_CURSOR_SCROLLABLE)",
                     rc, SQL_HANDLE_STMT, statement->stmt);
     }
@@ -1594,24 +1654,24 @@
             rc = odbc_bind_param(pool, statement, i + 1, statement->types[i],
                                  &argp, args, BINARYMODE);
         }
-        }
+    }
     if (SQL_SUCCEEDED(rc)) {
         rc = SQLExecute(statement->stmt);
         CHECK_ERROR(handle, "SQLExecute", rc, SQL_HANDLE_STMT,
                     statement->stmt);
-        }
+    }
     if (SQL_SUCCEEDED(rc)) {
         rc = odbc_create_results(handle, statement->stmt, pool, random, res);
         apr_pool_cleanup_register(pool, *res,
                                   odbc_close_results, apr_pool_cleanup_null);
-        }
+    }
 
     return APR_FROM_SQL_RESULT(rc);
 }
 
 /** pvbquery: query using a prepared statement + binary args **/
-static int odbc_pvbquery(apr_pool_t * pool, apr_dbd_t * handle, int *nrows,
-                         apr_dbd_prepared_t * statement, va_list args)
+static int odbc_pvbquery(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
+                         apr_dbd_prepared_t *statement, va_list args)
 {
     const char **values;
     int i;
@@ -1619,13 +1679,13 @@
     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
     for (i = 0; i < statement->nvals; i++)
         values[i] = va_arg(args, const char *);
-    return odbc_pbquery(pool, handle, nrows, statement, (const void **) values);
+    return odbc_pbquery(pool, handle, nrows, statement, (const void **)values);
 }
 
 /** pvbselect: select using a prepared statement + binary args **/
-static int odbc_pvbselect(apr_pool_t * pool, apr_dbd_t * handle,
-                          apr_dbd_results_t ** res,
-                          apr_dbd_prepared_t * statement,
+static int odbc_pvbselect(apr_pool_t *pool, apr_dbd_t *handle,
+                          apr_dbd_results_t **res,
+                          apr_dbd_prepared_t *statement,
                           int random, va_list args)
 {
     const char **values;
@@ -1634,10 +1694,10 @@
     values = apr_palloc(pool, sizeof(*values) * statement->nvals);
     for (i = 0; i < statement->nvals; i++)
         values[i] = va_arg(args, const char *);
-    return odbc_pbselect(pool, handle, res, statement, random, (const void **) values);
+    return odbc_pbselect(pool, handle, res, statement, random, (const void **)values);
 }
 
-APU_MODULE_DECLARE_DATA const apr_dbd_driver_t    ODBC_DRIVER_ENTRY = {
+APU_MODULE_DECLARE_DATA const apr_dbd_driver_t ODBC_DRIVER_ENTRY = {
     ODBC_DRIVER_STRING,
     odbc_init,
     odbc_native_handle,
diff --git a/dbd/apr_dbd_oracle.c b/dbd/apr_dbd_oracle.c
index 7ef05f9..e2e2e7e 100644
--- a/dbd/apr_dbd_oracle.c
+++ b/dbd/apr_dbd_oracle.c
@@ -177,7 +177,7 @@
     define_arg *out;
     apr_dbd_t *handle;
     apr_pool_t *pool;
-    int type;
+    ub2 type;
 };
 
 /* AFAICT from the docs, the OCIEnv thingey can be used async
diff --git a/dbd/apr_dbd_sqlite3.c b/dbd/apr_dbd_sqlite3.c
index 02b2c02..d79dbe1 100644
--- a/dbd/apr_dbd_sqlite3.c
+++ b/dbd/apr_dbd_sqlite3.c
@@ -117,7 +117,6 @@
             }
         } else if (ret == SQLITE_ROW) {
             int length;
-            apr_dbd_column_t *col;
             row = apr_palloc(pool, sizeof(apr_dbd_row_t));
             row->res = *results;
             increment = sizeof(apr_dbd_column_t *);
@@ -156,7 +155,6 @@
                 case SQLITE_NULL:
                     break;
                 }
-                col = row->columns[i];
             }
             row->rownum = num_tuples++;
             row->next_row = 0;
diff --git a/dbm/NWGNUdbmdb b/dbm/NWGNUdbmdb
index e60e108..748c32f 100644
--- a/dbm/NWGNUdbmdb
+++ b/dbm/NWGNUdbmdb
@@ -11,11 +11,9 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
-#include $(APR)\build\NWGNUcustom.inc
-
 #
 # build this level's files
 
@@ -27,8 +25,8 @@
 
 # for now defined here - should finally go into build/NWGNUenvironment.inc
 DB_INC = $(DBSDK)/inc
-DB_IMP = $(DBSDK)/imp/libdb47.imp
-DB_LIB = $(DBSDK)/lib/libdb47.lib
+DB_IMP = libdb47.imp
+DB_LIB = libdb47.lib
 DB_NLM = libdb47
 
 #
@@ -38,8 +36,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(DB_INC) \
 			$(EOLIST)
@@ -69,6 +67,10 @@
 XLFLAGS		+= \
 			-l $(DBSDK)/lib \
 			$(EOLIST)
+else
+XLFLAGS		+= \
+			-l $(DBSDK)/imp \
+			$(EOLIST)
 endif
 
 #
@@ -151,12 +153,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -166,7 +168,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -201,7 +203,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -244,7 +246,7 @@
 # Any additional imports go here
 #
 FILES_nlm_Ximports = \
-	@$(APR)/aprlib.imp \
+	@aprlib.imp \
 	@libc.imp \
 	$(EOLIST)
 
@@ -291,7 +293,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbm/NWGNUdbmgdbm b/dbm/NWGNUdbmgdbm
index 048f6fc..ce61306 100644
--- a/dbm/NWGNUdbmgdbm
+++ b/dbm/NWGNUdbmgdbm
@@ -11,11 +11,9 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
-#include $(APR)\build\NWGNUcustom.inc
-
 #
 # build this level's files
 
@@ -27,8 +25,8 @@
 
 # for now defined here - should finally go into build/NWGNUenvironment.inc
 GDBM_INC = $(GDBMSDK)/inc
-GDBM_IMP = $(GDBMSDK)/imp/libgdbm.imp
-GDBM_LIB = $(GDBMSDK)/lib/libgdbm.lib
+GDBM_IMP = libgdbm.imp
+GDBM_LIB = libgdbm.lib
 GDBM_NLM = libgdbm
 
 #
@@ -38,8 +36,8 @@
 XINCDIRS	+= \
 			$(APR)/include/arch/netware \
 			$(APR)/include \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(APR) \
 			$(GDBM_INC) \
 			$(EOLIST)
@@ -68,6 +66,10 @@
 XLFLAGS		+= \
 			-l $(GDBMSDK)/lib \
 			$(EOLIST)
+else
+XLFLAGS		+= \
+			-l $(GDBMSDK)/imp \
+			$(EOLIST)
 endif
 
 #
@@ -150,12 +152,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -165,7 +167,7 @@
 #
 # If these are specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
 
 #
 # If this is specified it will be linked in with the XDCData option in the def
@@ -200,7 +202,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 ifeq ($(LINK_STATIC),1)
@@ -243,7 +245,7 @@
 # Any additional imports go here
 #
 FILES_nlm_Ximports = \
-	@$(APR)/aprlib.imp \
+	@aprlib.imp \
 	@libc.imp \
 	$(EOLIST)
 
@@ -290,7 +292,7 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
 
diff --git a/dbm/NWGNUmakefile b/dbm/NWGNUmakefile
index e30372f..9307b84 100644
--- a/dbm/NWGNUmakefile
+++ b/dbm/NWGNUmakefile
@@ -10,7 +10,7 @@
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
@@ -246,6 +246,6 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
 
diff --git a/dbm/apr_dbm_berkeleydb.c b/dbm/apr_dbm_berkeleydb.c
index 0cbab82..32f2a06 100644
--- a/dbm/apr_dbm_berkeleydb.c
+++ b/dbm/apr_dbm_berkeleydb.c
@@ -37,13 +37,13 @@
  * DB_185, DB2, DB3, and DB4.
  */
 
-#if   defined(DB_VERSION_MAJOR) && (DB_VERSION_MAJOR == 4)
+#if   defined(DB_VERSION_MAJOR) && (DB_VERSION_MAJOR >= 4)
 /* We will treat anything greater than 4.1 as DB4.
  * We can treat 4.0 as DB3.
  */
-#if   defined(DB_VERSION_MINOR) && (DB_VERSION_MINOR >= 1)
+#if   DB_VERSION_MAJOR > 4 || (defined(DB_VERSION_MINOR) && (DB_VERSION_MINOR >= 1))
 #define DB_VER 4
-#else
+#elif DB_VERSION_MAJOR == 4
 #define DB_VER 3
 #endif
 #elif defined(DB_VERSION_MAJOR) && (DB_VERSION_MAJOR == 3)
diff --git a/dbm/apr_dbm_sdbm.c b/dbm/apr_dbm_sdbm.c
index 6f531a1..e6cc4aa 100644
--- a/dbm/apr_dbm_sdbm.c
+++ b/dbm/apr_dbm_sdbm.c
@@ -27,11 +27,11 @@
 #include "apr_dbm_private.h"
 #include "apr_sdbm.h"
 
-#define APR_DBM_DBMODE_RO       (APR_READ | APR_BUFFERED)
-#define APR_DBM_DBMODE_RW       (APR_READ | APR_WRITE)
-#define APR_DBM_DBMODE_RWCREATE (APR_READ | APR_WRITE | APR_CREATE)
-#define APR_DBM_DBMODE_RWTRUNC  (APR_READ | APR_WRITE | APR_CREATE | \
-                                 APR_TRUNCATE)
+#define APR_DBM_DBMODE_RO       (APR_FOPEN_READ | APR_FOPEN_BUFFERED)
+#define APR_DBM_DBMODE_RW       (APR_FOPEN_READ | APR_FOPEN_WRITE)
+#define APR_DBM_DBMODE_RWCREATE (APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE)
+#define APR_DBM_DBMODE_RWTRUNC  (APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | \
+                                 APR_FOPEN_TRUNCATE)
 
 static apr_status_t set_error(apr_dbm_t *dbm, apr_status_t dbm_said)
 {
@@ -184,10 +184,9 @@
 
 static apr_status_t vt_sdbm_nextkey(apr_dbm_t *dbm, apr_datum_t *pkey)
 {
-    apr_status_t rv;
     apr_sdbm_datum_t rd;
 
-    rv = apr_sdbm_nextkey(dbm->file, &rd);
+    (void)apr_sdbm_nextkey(dbm->file, &rd);
 
     pkey->dptr = rd.dptr;
     pkey->dsize = rd.dsize;
diff --git a/dbm/sdbm/sdbm.c b/dbm/sdbm/sdbm.c
index 9dfcc4b..a1ce695 100644
--- a/dbm/sdbm/sdbm.c
+++ b/dbm/sdbm/sdbm.c
@@ -101,7 +101,7 @@
      * as required by this package. Also set our internal
      * flag for RDONLY if needed.
      */
-    if (!(flags & APR_WRITE)) {
+    if (!(flags & APR_FOPEN_WRITE)) {
         db->flags |= SDBM_RDONLY;
     }
 
@@ -111,12 +111,12 @@
      * an apr_file_t, in case it's ever introduced, and set
      * our own flag.
      */
-    if (flags & APR_SHARELOCK) {
+    if (flags & APR_FOPEN_SHARELOCK) {
         db->flags |= SDBM_SHARED;
-        flags &= ~APR_SHARELOCK;
+        flags &= ~APR_FOPEN_SHARELOCK;
     }
 
-    flags |= APR_BINARY | APR_READ;
+    flags |= APR_FOPEN_BINARY | APR_FOPEN_READ;
 
     /*
      * open the files in sequence, and stat the dirfile.
diff --git a/hooks/apr_hooks.c b/hooks/apr_hooks.c
index d8eb82d..6abe193 100644
--- a/hooks/apr_hooks.c
+++ b/hooks/apr_hooks.c
@@ -265,6 +265,10 @@
 #endif
     int n;    
 
+    if (!s_aHooksToSort) {
+        return;
+    }
+
     for(n=0 ; n < s_aHooksToSort->nelts ; ++n) {
         HookSortEntry *pEntry=&((HookSortEntry *)s_aHooksToSort->elts)[n];
         *pEntry->paHooks=NULL;
diff --git a/include/apr_buckets.h b/include/apr_buckets.h
index fb87635..b1d1861 100644
--- a/include/apr_buckets.h
+++ b/include/apr_buckets.h
@@ -679,10 +679,11 @@
 APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);
 
 /**
- * Move the buckets from the tail end of the existing brigade @param b into
- * the brigade @param a. If @param a is NULL a new brigade is created. Buckets
- * from @param e to the last bucket (inclusively) of brigade @param b are moved
- * from @param b to the returned brigade @param a.
+ * Move the buckets from the tail end of the existing brigade @a b into
+ * the brigade @a a. If @a a is NULL a new brigade is created. Buckets
+ * from @a e to the last bucket (inclusively) of brigade @a b are moved
+ * from @a b to the returned brigade @a a.
+ *
  * @param b The brigade to split
  * @param e The first bucket to move
  * @param a The brigade which should be used for the result or NULL if
@@ -774,7 +775,7 @@
                                                  apr_off_t maxbytes);
 
 /**
- * create an iovec of the elements in a bucket_brigade... return number 
+ * Create an iovec of the elements in a bucket_brigade... return number 
  * of elements used.  This is useful for writing to a file or to the
  * network efficiently.
  * @param b The bucket brigade to create the iovec from
diff --git a/include/apr_crypto.h b/include/apr_crypto.h
index 2577248..9c5778b 100644
--- a/include/apr_crypto.h
+++ b/include/apr_crypto.h
@@ -20,6 +20,7 @@
 #include "apu.h"
 #include "apr_pools.h"
 #include "apr_tables.h"
+#include "apr_hash.h"
 #include "apu_errno.h"
 
 #ifdef __cplusplus
@@ -36,49 +37,6 @@
  * @{
  */
 
-/** CA certificate type unknown */
-#define APR_CRYPTO_CA_TYPE_UNKNOWN           0
-/** binary DER encoded CA certificate */
-#define APR_CRYPTO_CA_TYPE_DER               1
-/** PEM encoded CA certificate */
-#define APR_CRYPTO_CA_TYPE_BASE64            2
-/** Netscape/Mozilla cert7.db CA certificate database */
-#define APR_CRYPTO_CA_TYPE_CERT7_DB          3
-/** Netscape/Mozilla secmod file */
-#define APR_CRYPTO_CA_TYPE_SECMOD            4
-/** Client certificate type unknown */
-#define APR_CRYPTO_CERT_TYPE_UNKNOWN         5
-/** binary DER encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_DER             6
-/** PEM encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_BASE64          7
-/** Netscape/Mozilla key3.db client certificate database */
-#define APR_CRYPTO_CERT_TYPE_KEY3_DB         8
-/** Netscape/Mozilla client certificate nickname */
-#define APR_CRYPTO_CERT_TYPE_NICKNAME        9
-/** Private key type unknown */
-#define APR_CRYPTO_KEY_TYPE_UNKNOWN          10
-/** binary DER encoded private key */
-#define APR_CRYPTO_KEY_TYPE_DER              11
-/** PEM encoded private key */
-#define APR_CRYPTO_KEY_TYPE_BASE64           12
-/** PKCS#12 encoded client certificate */
-#define APR_CRYPTO_CERT_TYPE_PFX             13
-/** PKCS#12 encoded private key */
-#define APR_CRYPTO_KEY_TYPE_PFX              14
-/** Openldap directory full of base64-encoded cert
- * authorities with hashes in corresponding .0 directory
- */
-#define APR_CRYPTO_CA_TYPE_CACERTDIR_BASE64  15
-/** CMS Key Database with private key and cert chain */
-#define APR_CRYPTO_CA_TYPE_CMS               16
-/** Symmetrical key */
-#define APR_CRYPTO_KEY_TYPE_SYM              17
-/** Netscape/Mozilla certificate database directory */
-#define APR_CRYPTO_CA_TYPE_DIR               18
-/** Crypto engine */
-#define APR_CRYPTO_ENGINE                    101
-
 #if APU_HAVE_CRYPTO
 
 #ifndef APU_CRYPTO_RECOMMENDED_DRIVER
@@ -141,77 +99,71 @@
  * aligned data, use 3DES_192/CBC, AES_256/CBC or AES_256/ECB.
  */
 
-typedef enum {
-    KEY_NONE, KEY_3DES_192, /** 192 bit (3-Key) 3DES */
-    KEY_AES_128, /** 128 bit AES */
-    KEY_AES_192, /** 192 bit AES */
-    KEY_AES_256
+typedef enum
+{
+    APR_KEY_NONE, APR_KEY_3DES_192, /** 192 bit (3-Key) 3DES */
+    APR_KEY_AES_128, /** 128 bit AES */
+    APR_KEY_AES_192, /** 192 bit AES */
+    APR_KEY_AES_256
 /** 256 bit AES */
 } apr_crypto_block_key_type_e;
 
-typedef enum {
-    MODE_NONE, /** An error condition */
-    MODE_ECB, /** Electronic Code Book */
-    MODE_CBC
+typedef enum
+{
+    APR_MODE_NONE, /** An error condition */
+    APR_MODE_ECB, /** Electronic Code Book */
+    APR_MODE_CBC
 /** Cipher Block Chaining */
 } apr_crypto_block_key_mode_e;
 
-/**
- * Certificate and private key structure.
- *
- * The various crypto backends expect certificates and keys in a wide
- * array of formats. This structure is analogous to apr_ldap_opt_tls_cert_t
- * from the LDAP interface. Ultimately that interface should be meshed with
- * this one.
- * @param type Type of certificate APR_CRYPTO_*_TYPE_*
- * @param path Path, file or nickname of the certificate
- * @param password Optional password, can be NULL
- */
-typedef struct apr_crypto_param_t {
-    int type;
-    const char *path;
-    const char *password;
-} apr_crypto_param_t;
-
 /* These are opaque structs.  Instantiation is up to each backend */
 typedef struct apr_crypto_driver_t apr_crypto_driver_t;
+typedef struct apr_crypto_t apr_crypto_t;
 typedef struct apr_crypto_config_t apr_crypto_config_t;
 typedef struct apr_crypto_key_t apr_crypto_key_t;
 typedef struct apr_crypto_block_t apr_crypto_block_t;
 
 /**
- * Public factory API, common to all backends.
- */
-typedef struct apr_crypto_t {
-    apr_pool_t *pool;
-    apu_err_t *result;
-    apr_array_header_t *keys;
-    apr_crypto_config_t *config;
-} apr_crypto_t;
-
-/**
  * @brief Perform once-only initialisation. Call once only.
  *
  * @param pool - pool to register any shutdown cleanups, etc
  * @return APR_NOTIMPL in case of no crypto support.
  */
-APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool,
-        const apr_array_header_t *params);
+APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool);
+
+/**
+ * @brief Register a cleanup to zero out the buffer provided
+ * when the pool is cleaned up.
+ *
+ * @param pool - pool to register the cleanup
+ * @param buffer - buffer to zero out
+ * @param size - size of the buffer to zero out
+ */
+APR_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool, void *buffer,
+        apr_size_t size);
 
 /**
  * @brief Get the driver struct for a name
  *
- * @param pool - (process) pool to register cleanup
- * @param name - driver name
  * @param driver - pointer to driver struct.
+ * @param name - driver name
+ * @param params - array of initialisation parameters
+ * @param result - result and error message on failure
+ * @param pool - (process) pool to register cleanup
  * @return APR_SUCCESS for success
  * @return APR_ENOTIMPL for no driver (when DSO not enabled)
  * @return APR_EDSOOPEN if DSO driver file can't be opened
  * @return APR_ESYMNOTFOUND if the driver file doesn't contain a driver
+ * @remarks NSS: the params can have "dir", "key3", "cert7" and "secmod"
+ *  keys, each followed by an equal sign and a value. Such key/value pairs can
+ *  be delimited by space or tab. If the value contains a space, surround the
+ *  whole key value pair in quotes: "dir=My Directory".
+ * @remarks OpenSSL: currently no params are supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_get_driver(apr_pool_t *pool, const char *name,
-        const apr_crypto_driver_t **driver, const apr_array_header_t *params,
-        const apu_err_t **result);
+APU_DECLARE(apr_status_t) apr_crypto_get_driver(
+        const apr_crypto_driver_t **driver,
+        const char *name, const char *params, const apu_err_t **result,
+        apr_pool_t *pool);
 
 /**
  * @brief Return the name of the driver.
@@ -219,33 +171,59 @@
  * @param driver - The driver in use.
  * @return The name of the driver.
  */
-APU_DECLARE(const char *)apr_crypto_driver_name (const apr_crypto_driver_t *driver);
+APU_DECLARE(const char *) apr_crypto_driver_name(
+        const apr_crypto_driver_t *driver);
 
 /**
- * @brief Get the result of the last operation on a factory. If the result
+ * @brief Get the result of the last operation on a context. If the result
  *        is NULL, the operation was successful.
- * @param driver - driver to use
- * @param factory - factory pointer will be written here
  * @param result - the result structure
+ * @param f - context pointer
  * @return APR_SUCCESS for success
  */
-APU_DECLARE(apr_status_t) apr_crypto_error(const apr_crypto_t *f,
-        const apu_err_t **result);
+APU_DECLARE(apr_status_t) apr_crypto_error(const apu_err_t **result,
+        const apr_crypto_t *f);
 
 /**
  * @brief Create a context for supporting encryption. Keys, certificates,
  *        algorithms and other parameters will be set per context. More than
  *        one context can be created at one time. A cleanup will be automatically
  *        registered with the given pool to guarantee a graceful shutdown.
+ * @param f - context pointer will be written here
  * @param driver - driver to use
- * @param pool - process pool
  * @param params - array of key parameters
- * @param factory - factory pointer will be written here
+ * @param pool - process pool
  * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
  * if the engine cannot be initialised.
+ * @remarks NSS: currently no params are supported.
+ * @remarks OpenSSL: the params can have "engine" as a key, followed by an equal
+ *  sign and a value.
  */
-APU_DECLARE(apr_status_t) apr_crypto_factory(const apr_crypto_driver_t *driver,
-        apr_pool_t *pool, const apr_array_header_t *params, apr_crypto_t **f);
+APU_DECLARE(apr_status_t) apr_crypto_make(apr_crypto_t **f,
+        const apr_crypto_driver_t *driver, const char *params,
+        apr_pool_t *pool);
+
+/**
+ * @brief Get a hash table of key types, keyed by the name of the type against
+ * an integer pointer constant.
+ *
+ * @param types - hashtable of key types keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_types(apr_hash_t **types,
+        const apr_crypto_t *f);
+
+/**
+ * @brief Get a hash table of key modes, keyed by the name of the mode against
+ * an integer pointer constant.
+ *
+ * @param modes - hashtable of key modes keyed to constants.
+ * @param f - encryption context
+ * @return APR_SUCCESS for success
+ */
+APU_DECLARE(apr_status_t) apr_crypto_get_block_key_modes(apr_hash_t **modes,
+        const apr_crypto_t *f);
 
 /**
  * @brief Create a key from the given passphrase. By default, the PBKDF2
@@ -256,9 +234,9 @@
  *        operations.
  * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
  *       *key is not NULL, *key must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The context to use.
+ * @param key The key returned, see note.
+ * @param ivSize The size of the initialisation vector will be returned, based
+ *               on whether an IV is relevant for this type of crypto.
  * @param pass The passphrase to use.
  * @param passLen The passphrase length in bytes
  * @param salt The salt to use.
@@ -266,45 +244,41 @@
  * @param type 3DES_192, AES_128, AES_192, AES_256.
  * @param mode Electronic Code Book / Cipher Block Chaining.
  * @param doPad Pad if necessary.
- * @param key The key returned, see note.
- * @param ivSize The size of the initialisation vector will be returned, based
- *               on whether an IV is relevant for this type of crypto.
+ * @param iterations Number of iterations to use in algorithm
+ * @param f The context to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
  *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
  *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
  *         not known. APR_EPADDING if padding was requested but is not supported.
  *         APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_passphrase(const apr_crypto_driver_t *driver,
-        apr_pool_t *p, const apr_crypto_t *f, const char *pass,
-        apr_size_t passLen, const unsigned char * salt, apr_size_t saltLen,
+APU_DECLARE(apr_status_t) apr_crypto_passphrase(apr_crypto_key_t **key,
+        apr_size_t *ivSize, const char *pass, apr_size_t passLen,
+        const unsigned char * salt, apr_size_t saltLen,
         const apr_crypto_block_key_type_e type,
         const apr_crypto_block_key_mode_e mode, const int doPad,
-        const int iterations, apr_crypto_key_t **key, apr_size_t *ivSize);
+        const int iterations, const apr_crypto_t *f, apr_pool_t *p);
 
 /**
  * @brief Initialise a context for encrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure to use.
+ * @param ctx The block context returned, see note.
  * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
  *           an IV will be created at random, in space allocated from the pool.
  *           If the buffer pointed to is not NULL, the IV in the buffer will be
  *           used.
- * @param ctx The block context returned, see note.
+ * @param key The key structure to use.
  * @param blockSize The block size of the cipher.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
 APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_init(
-        const apr_crypto_driver_t *driver, apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char **iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize);
+        apr_crypto_block_t **ctx, const unsigned char **iv,
+        const apr_crypto_key_t *key, apr_size_t *blockSize, apr_pool_t *p);
 
 /**
  * @brief Encrypt data provided by in, write it to out.
@@ -315,20 +289,18 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_encrypt(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_encrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx);
 
 /**
  * @brief Encrypt final data block, write it to out.
@@ -338,41 +310,35 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_encrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_finish(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_encrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx);
 
 /**
  * @brief Initialise a context for decrypting arbitrary data using the given key.
  * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
  *       *ctx is not NULL, *ctx must point at a previously created structure.
- * @param driver - driver to use
- * @param p The pool to use.
- * @param f The block factory to use.
- * @param key The key structure to use.
- * @param iv Optional initialisation vector.
  * @param ctx The block context returned, see note.
  * @param blockSize The block size of the cipher.
+ * @param iv Optional initialisation vector.
+ * @param key The key structure to use.
+ * @param p The pool to use.
  * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
  *         Returns APR_EINIT if the backend failed to initialise the context. Returns
  *         APR_ENOTIMPL if not implemented.
  */
 APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_init(
-        const apr_crypto_driver_t *driver, apr_pool_t *p,
-        const apr_crypto_t *f, const apr_crypto_key_t *key,
-        const unsigned char *iv, apr_crypto_block_t **ctx,
-        apr_size_t *blockSize);
+        apr_crypto_block_t **ctx, apr_size_t *blockSize,
+        const unsigned char *iv, const apr_crypto_key_t *key, apr_pool_t *p);
 
 /**
  * @brief Decrypt data provided by in, write it to out.
@@ -383,20 +349,18 @@
  *       to NULL, a buffer sufficiently large will be created from
  *       the pool provided. If *out points to a not-NULL value, this
  *       value will be used as a buffer instead.
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written,
  *        see note.
  * @param outlen Length of the output will be written here.
  * @param in Address of the buffer to read.
  * @param inlen Length of the buffer to read.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
  *         not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_decrypt(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char **out, apr_size_t *outlen, const unsigned char *in,
-        apr_size_t inlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_decrypt(unsigned char **out,
+        apr_size_t *outlen, const unsigned char *in, apr_size_t inlen,
+        apr_crypto_block_t *ctx);
 
 /**
  * @brief Decrypt final data block, write it to out.
@@ -406,50 +370,43 @@
  *       number of bytes returned as actually written by the
  *       apr_crypto_block_decrypt() call. After this call, the context
  *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
- * @param driver - driver to use
- * @param ctx The block context to use.
  * @param out Address of a buffer to which data will be written. This
  *            buffer must already exist, and is usually the same
  *            buffer used by apr_evp_crypt(). See note.
  * @param outlen Length of the output will be written here.
+ * @param ctx The block context to use.
  * @return APR_ECRYPT if an error occurred.
  * @return APR_EPADDING if padding was enabled and the block was incorrectly
  *         formatted.
  * @return APR_ENOTIMPL if not implemented.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_finish(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx,
-        unsigned char *out, apr_size_t *outlen);
+APU_DECLARE(apr_status_t) apr_crypto_block_decrypt_finish(unsigned char *out,
+        apr_size_t *outlen, apr_crypto_block_t *ctx);
 
 /**
  * @brief Clean encryption / decryption context.
  * @note After cleanup, a context is free to be reused if necessary.
- * @param driver - driver to use
  * @param ctx The block context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_block_cleanup(
-        const apr_crypto_driver_t *driver, apr_crypto_block_t *ctx);
+APU_DECLARE(apr_status_t) apr_crypto_block_cleanup(apr_crypto_block_t *ctx);
 
 /**
- * @brief Clean encryption / decryption factory.
- * @note After cleanup, a factory is free to be reused if necessary.
- * @param driver - driver to use
- * @param f The factory to use.
+ * @brief Clean encryption / decryption context.
+ * @note After cleanup, a context is free to be reused if necessary.
+ * @param f The context to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_cleanup(const apr_crypto_driver_t *driver,
-        apr_crypto_t *f);
+APU_DECLARE(apr_status_t) apr_crypto_cleanup(apr_crypto_t *f);
 
 /**
  * @brief Shutdown the crypto library.
  * @note After shutdown, it is expected that the init function can be called again.
  * @param driver - driver to use
- * @param p The pool to use.
  * @return Returns APR_ENOTIMPL if not supported.
  */
-APU_DECLARE(apr_status_t) apr_crypto_shutdown(const apr_crypto_driver_t *driver,
-        apr_pool_t *p);
+APU_DECLARE(apr_status_t) apr_crypto_shutdown(
+        const apr_crypto_driver_t *driver);
 
 #endif /* APU_HAVE_CRYPTO */
 
diff --git a/include/apr_hooks.h b/include/apr_hooks.h
index 9f2a807..b675711 100644
--- a/include/apr_hooks.h
+++ b/include/apr_hooks.h
@@ -21,23 +21,6 @@
 /* For apr_array_header_t */
 #include "apr_tables.h"
 
-#ifdef APR_DTRACE_PROVIDER
-#include <sys/sdt.h>
-#ifndef OLD_DTRACE_PROBE
-#define OLD_DTRACE_PROBE(name) __dtrace_ap___##name()
-#endif
-#ifndef OLD_DTRACE_PROBE1
-#define OLD_DTRACE_PROBE1(name,a) __dtrace_ap___##name(a)
-#endif
-#ifndef OLD_DTRACE_PROBE2
-#define OLD_DTRACE_PROBE2(name,a,b) __dtrace_ap___##name(a,b)
-#endif
-#else
-#define OLD_DTRACE_PROBE(a)
-#define OLD_DTRACE_PROBE1(a,b)
-#define OLD_DTRACE_PROBE2(a,b,c)
-#endif
-
 /**
  * @file apr_hooks.h
  * @brief Apache hook functions
@@ -51,6 +34,82 @@
  * @ingroup APR_Util
  * @{
  */
+
+/**
+ * @defgroup apr_hook_probes Hook probe capability
+ * APR hooks provide a trace probe capability for capturing
+ * the flow of control and return values with hooks.
+ *
+ * In order to use this facility, the application must define
+ * the symbol APR_HOOK_PROBES_ENABLED and the four APR_HOOK_PROBE_
+ * macros described below before including apr_hooks.h in files
+ * that use the APR_IMPLEMENT_EXTERNAL_HOOK_* macros.
+ *
+ * This probe facility is not provided for APR optional hooks.
+ * @{
+ */
+
+#ifdef APR_HOOK_PROBES_ENABLED
+#define APR_HOOK_INT_DCL_UD void *ud = NULL
+#else
+/** internal implementation detail to avoid the ud declaration when
+ * hook probes are not used
+ */
+#define APR_HOOK_INT_DCL_UD
+/**
+ * User-defined hook probe macro that is invoked when the hook
+ * is run, before calling any hook functions.
+ * @param ud A void * user data field that should be filled in by
+ * this macro, and will be provided to the other hook probe macros.
+ * @param ns The namespace prefix of the hook functions
+ * @param name The name of the hook
+ * @param args The argument list to the hook functions, with enclosing
+ * parens.
+ */
+#define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
+/**
+ * User-defined hook probe macro that is invoked after the hook
+ * has run.
+ * @param ud A void * user data field that was filled in by the user-
+ * provided APR_HOOK_PROBE_ENTRY().
+ * @param ns The namespace prefix of the hook functions
+ * @param name The name of the hook
+ * @param rv The return value of the hook, or 0 if the hook is void.
+ * @param args The argument list to the hook functions, with enclosing
+ * parens.
+ */
+#define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
+/**
+ * User-defined hook probe macro that is invoked before calling a
+ * hook function.
+ * @param ud A void * user data field that was filled in by the user-
+ * provided APR_HOOK_PROBE_ENTRY().
+ * @param ns The namespace prefix of the hook functions
+ * @param name The name of the hook
+ * @param src The value of apr_hook_debug_current at the time the function
+ * was hooked (usually the source file implementing the hook function).
+ * @param args The argument list to the hook functions, with enclosing
+ * parens.
+ */
+#define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
+/**
+ * User-defined hook probe macro that is invoked after calling a
+ * hook function.
+ * @param ud A void * user data field that was filled in by the user-
+ * provided APR_HOOK_PROBE_ENTRY().
+ * @param ns The namespace prefix of the hook functions
+ * @param name The name of the hook
+ * @param src The value of apr_hook_debug_current at the time the function
+ * was hooked (usually the source file implementing the hook function).
+ * @param rv The return value of the hook function, or 0 if the hook is void.
+ * @param args The argument list to the hook functions, with enclosing
+ * parens.
+ */
+#define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
+#endif
+
+/** @} */
+
 /** macro to return the prototype of the hook function */    
 #define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
 link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
@@ -123,21 +182,22 @@
     { \
     ns##_LINK_##name##_t *pHook; \
     int n; \
+    APR_HOOK_INT_DCL_UD; \
 \
-    OLD_DTRACE_PROBE(name##__entry); \
+    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
 \
     if(_hooks.link_##name) \
         { \
         pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
         for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
             { \
-            OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
+            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
 	    pHook[n].pFunc args_use; \
-            OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, 0); \
+            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, 0, args_use); \
             } \
         } \
 \
-    OLD_DTRACE_PROBE1(name##__return, 0); \
+    APR_HOOK_PROBE_RETURN(ud, ns, name, 0, args_use); \
 \
     }
 
@@ -166,24 +226,25 @@
     ns##_LINK_##name##_t *pHook; \
     int n; \
     ret rv = ok; \
+    APR_HOOK_INT_DCL_UD; \
 \
-    OLD_DTRACE_PROBE(name##__entry); \
+    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
 \
     if(_hooks.link_##name) \
         { \
         pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
         for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
             { \
-            OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
+            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
             rv=pHook[n].pFunc args_use; \
-            OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, rv); \
+            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
             if(rv != ok && rv != decline) \
                 break; \
             rv = ok; \
             } \
         } \
 \
-    OLD_DTRACE_PROBE1(name##__return, rv); \
+    APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
 \
     return rv; \
     }
@@ -210,24 +271,25 @@
     ns##_LINK_##name##_t *pHook; \
     int n; \
     ret rv = decline; \
+    APR_HOOK_INT_DCL_UD; \
 \
-    OLD_DTRACE_PROBE(name##__entry); \
+    APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
 \
     if(_hooks.link_##name) \
         { \
         pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
         for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
             { \
-            OLD_DTRACE_PROBE1(name##__dispatch__invoke, (char *)pHook[n].szName); \
+            APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
             rv=pHook[n].pFunc args_use; \
-            OLD_DTRACE_PROBE2(name##__dispatch__complete, (char *)pHook[n].szName, rv); \
+            APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
 \
             if(rv != decline) \
                 break; \
             } \
         } \
 \
-    OLD_DTRACE_PROBE1(name##__return, rv); \
+    APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
 \
     return rv; \
     }
diff --git a/include/apr_ldap.h.in b/include/apr_ldap.h.in
index 6087783..e30d344 100644
--- a/include/apr_ldap.h.in
+++ b/include/apr_ldap.h.in
@@ -192,6 +192,6 @@
 #include "apr_ldap_option.h"
 #include "apr_ldap_rebind.h"
 
-/** @} */
 #endif /* APR_HAS_LDAP */
+/** @} */
 #endif /* APU_LDAP_H */
diff --git a/include/apr_memcache.h b/include/apr_memcache.h
index 6efcfc3..8287882 100644
--- a/include/apr_memcache.h
+++ b/include/apr_memcache.h
@@ -120,6 +120,7 @@
 
 /**
  * Creates a crc32 hash used to split keys between servers
+ * @param mc The memcache client object to use
  * @param data Data to be hashed
  * @param data_len Length of the data to use
  * @return crc32 hash of data
@@ -150,21 +151,20 @@
  * @return server that controls specified hash
  * @see apr_memcache_hash
  */
-APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc, 
+APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc,
                                                                    const apr_uint32_t hash);
 
 /**
  * server selection compatible with the standard Perl Client.
  */
-APU_DECLARE(apr_memcache_server_t *)
-apr_memcache_find_server_hash_default(void *baton,
-                                      apr_memcache_t *mc, 
-                                      const apr_uint32_t hash);
+APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash_default(void *baton,
+                                                                           apr_memcache_t *mc, 
+                                                                           const apr_uint32_t hash);
 
 /**
  * Adds a server to a client object
  * @param mc The memcache client object to use
- * @param ms Server to add
+ * @param server Server to add
  * @remark Adding servers is not thread safe, and should be done once at startup.
  * @warning Changing servers after startup may cause keys to go to
  * different servers.
@@ -284,7 +284,7 @@
  * @param mc client to use
  * @param key   null terminated string containing the key
  * @param baton data to store on the server
- * @param len   length of data at baton
+ * @param data_size   length of data at baton
  * @param timeout time in seconds for the data to live on the server
  * @param flags any flags set by the client for this key
  */
@@ -300,7 +300,7 @@
  * @param mc client to use
  * @param key   null terminated string containing the key
  * @param baton data to store on the server
- * @param len   length of data at baton
+ * @param data_size   length of data at baton
  * @param timeout time for the data to live on the server
  * @param flags any flags set by the client for this key
  * @return APR_SUCCESS if the key was added, APR_EEXIST if the key 
@@ -318,7 +318,7 @@
  * @param mc client to use
  * @param key   null terminated string containing the key
  * @param baton data to store on the server
- * @param len   length of data at baton
+ * @param data_size   length of data at baton
  * @param timeout time for the data to live on the server
  * @param flags any flags set by the client for this key
  * @return APR_SUCCESS if the key was added, APR_EEXIST if the key 
@@ -326,7 +326,7 @@
  */
 APU_DECLARE(apr_status_t) apr_memcache_replace(apr_memcache_t *mc,
                                                const char *key,
-                                               char *data,
+                                               char *baton,
                                                const apr_size_t data_size,
                                                apr_uint32_t timeout,
                                                apr_uint16_t flags);
@@ -357,7 +357,7 @@
  * @param mc client to use
  * @param key   null terminated string containing the key
  * @param n     number to decrement by
- * @param nv    new value after decrementing
+ * @param new_value    new value after decrementing
  */
 APU_DECLARE(apr_status_t) apr_memcache_decr(apr_memcache_t *mc, 
                                             const char *key,
diff --git a/include/apr_reslist.h b/include/apr_reslist.h
index 72349ff..1e30a53 100644
--- a/include/apr_reslist.h
+++ b/include/apr_reslist.h
@@ -69,11 +69,13 @@
  *                list will be stored.
  * @param min Allowed minimum number of available resources. Zero
  *            creates new resources only when needed.
- * @param smax Resources will be destroyed to meet this maximum
- *             restriction as they expire.
+ * @param smax Resources will be destroyed during reslist maintenance to
+ *             meet this maximum restriction as they expire (reach their ttl).
  * @param hmax Absolute maximum limit on the number of total resources.
- * @param ttl If non-zero, sets the maximum amount of time in microseconds a
- *            resource may be available while exceeding the soft limit.
+ * @param ttl If non-zero, sets the maximum amount of time in microseconds an
+ *            unused resource is valid.  Any resource which has exceeded this
+ *            time will be destroyed, either when encountered by
+ *            apr_reslist_acquire() or during reslist maintenance.
  * @param con Constructor routine that is called to create a new resource.
  * @param de Destructor routine that is called to destroy an expired resource.
  * @param params Passed to constructor and deconstructor
diff --git a/include/apr_xml.h b/include/apr_xml.h
index 829f0fd..ac7f003 100644
--- a/include/apr_xml.h
+++ b/include/apr_xml.h
@@ -304,10 +304,10 @@
 
 /**
  * quote an XML string
- * Replace '<', '>', and '&' with '&lt;', '&gt;', and '&amp;'.
+ * Replace '\<', '\>', and '\&' with '\&lt;', '\&gt;', and '\&amp;'.
  * @param p The pool to allocate out of
  * @param s The string to quote
- * @param quotes If quotes is true, then replace '"' with '&quot;'.
+ * @param quotes If quotes is true, then replace '&quot;' with '\&quot;'.
  * @return The quoted string
  * @note If the string does not contain special characters, it is not
  * duplicated into the pool and the original string is returned.
diff --git a/include/apu_version.h b/include/apu_version.h
index fc70b88..6c1760d 100644
--- a/include/apu_version.h
+++ b/include/apu_version.h
@@ -66,7 +66,7 @@
  * "development" copies of APU.  It is undefined for released versions
  * of APU.
  */
-#define APU_IS_DEV_VERSION
+/* #define APU_IS_DEV_VERSION */
 
 
 #if defined(APU_IS_DEV_VERSION) || defined(DOXYGEN)
diff --git a/include/private/apr_crypto_internal.h b/include/private/apr_crypto_internal.h
index de109de..b571451 100644
--- a/include/private/apr_crypto_internal.h
+++ b/include/private/apr_crypto_internal.h
@@ -36,24 +36,47 @@
      * @brief: allow driver to perform once-only initialisation.
      * Called once only.
      * @param pool The pool to register the cleanup in.
-     * @param params An array of optional init parameters.
+     * @param params Optional init parameter string.
+     * @param rc Driver-specific additional error code
      */
-    apr_status_t (*init)(apr_pool_t *pool, const apr_array_header_t *params, int *rc);
+    apr_status_t (*init)(apr_pool_t *pool, const char *params, int *rc);
 
     /**
      * @brief Create a context for supporting encryption. Keys, certificates,
      *        algorithms and other parameters will be set per context. More than
      *        one context can be created at one time. A cleanup will be automatically
      *        registered with the given pool to guarantee a graceful shutdown.
-     * @param driver - driver to use
-     * @param pool - process pool
-     * @param params - array of key parameters
      * @param f - context pointer will be written here
+     * @param provider - provider to use
+     * @param params - array of key parameters
+     * @param pool - process pool
      * @return APR_ENOENGINE when the engine specified does not exist. APR_EINITENGINE
      * if the engine cannot be initialised.
      */
-    apr_status_t (*factory)(apr_pool_t *pool, const apr_array_header_t *params,
-            apr_crypto_t **f);
+    apr_status_t (*make)(apr_crypto_t **f, const apr_crypto_driver_t *provider,
+            const char *params, apr_pool_t *pool);
+
+    /**
+     * @brief Get a hash table of key types, keyed by the name of the type against
+     * an integer pointer constant.
+     *
+     * @param types - hashtable of key types keyed to constants.
+     * @param f - encryption context
+     * @return APR_SUCCESS for success
+     */
+    apr_status_t (*get_block_key_types)(apr_hash_t **types,
+            const apr_crypto_t *f);
+
+    /**
+     * @brief Get a hash table of key modes, keyed by the name of the mode against
+     * an integer pointer constant.
+     *
+     * @param modes - hashtable of key modes keyed to constants.
+     * @param f - encryption context
+     * @return APR_SUCCESS for success
+     */
+    apr_status_t (*get_block_key_modes)(apr_hash_t **modes,
+            const apr_crypto_t *f);
 
     /**
      * @brief Create a key from the given passphrase. By default, the PBKDF2
@@ -64,9 +87,9 @@
      *        operations.
      * @note If *key is NULL, a apr_crypto_key_t will be created from a pool. If
      *       *key is not NULL, *key must point at a previously created structure.
-     * @param driver - driver to use
-     * @param p The pool to use.
-     * @param f The context to use.
+     * @param key The key returned, see note.
+     * @param ivSize The size of the initialisation vector will be returned, based
+     *               on whether an IV is relevant for this type of crypto.
      * @param pass The passphrase to use.
      * @param passLen The passphrase length in bytes
      * @param salt The salt to use.
@@ -74,43 +97,40 @@
      * @param type 3DES_192, AES_128, AES_192, AES_256.
      * @param mode Electronic Code Book / Cipher Block Chaining.
      * @param doPad Pad if necessary.
-     * @param key The key returned, see note.
-     * @param ivSize The size of the initialisation vector will be returned, based
-     *               on whether an IV is relevant for this type of crypto.
+     * @param iterations Iteration count
+     * @param f The context to use.
+     * @param p The pool to use.
      * @return Returns APR_ENOKEY if the pass phrase is missing or empty, or if a backend
      *         error occurred while generating the key. APR_ENOCIPHER if the type or mode
      *         is not supported by the particular backend. APR_EKEYTYPE if the key type is
      *         not known. APR_EPADDING if padding was requested but is not supported.
      *         APR_ENOTIMPL if not implemented.
      */
-    apr_status_t (*passphrase)(apr_pool_t *p, const apr_crypto_t *f,
+    apr_status_t (*passphrase)(apr_crypto_key_t **key, apr_size_t *ivSize,
             const char *pass, apr_size_t passLen, const unsigned char * salt,
             apr_size_t saltLen, const apr_crypto_block_key_type_e type,
             const apr_crypto_block_key_mode_e mode, const int doPad,
-            const int iterations, apr_crypto_key_t **key, apr_size_t *ivSize);
+            const int iterations, const apr_crypto_t *f, apr_pool_t *p);
 
     /**
      * @brief Initialise a context for encrypting arbitrary data using the given key.
      * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
      *       *ctx is not NULL, *ctx must point at a previously created structure.
-     * @param p The pool to use.
-     * @param f The block factory to use.
-     * @param key The key structure.
+     * @param ctx The block context returned, see note.
      * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
      *           an IV will be created at random, in space allocated from the pool.
      *           If the buffer pointed to is not NULL, the IV in the buffer will be
      *           used.
-     * @param ctx The block context returned, see note.
-     * @param ivSize The size of the initialisation vector will be returned, based
-     *               on whether an IV is relevant for this type of crypto.
+     * @param key The key structure.
      * @param blockSize The block size of the cipher.
+     * @param p The pool to use.
      * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
      *         Returns APR_EINIT if the backend failed to initialise the context. Returns
      *         APR_ENOTIMPL if not implemented.
      */
-    apr_status_t (*block_encrypt_init)(apr_pool_t *p, const apr_crypto_t *f,
-            const apr_crypto_key_t *key, const unsigned char **iv,
-            apr_crypto_block_t **ctx, apr_size_t *blockSize);
+    apr_status_t (*block_encrypt_init)(apr_crypto_block_t **ctx,
+            const unsigned char **iv, const apr_crypto_key_t *key,
+            apr_size_t *blockSize, apr_pool_t *p);
 
     /**
      * @brief Encrypt data provided by in, write it to out.
@@ -121,17 +141,17 @@
      *       to NULL, a buffer sufficiently large will be created from
      *       the pool provided. If *out points to a not-NULL value, this
      *       value will be used as a buffer instead.
-     * @param ctx The block context to use.
      * @param out Address of a buffer to which data will be written,
      *        see note.
      * @param outlen Length of the output will be written here.
      * @param in Address of the buffer to read.
      * @param inlen Length of the buffer to read.
+     * @param ctx The block context to use.
      * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
      *         not implemented.
      */
-    apr_status_t (*block_encrypt)(apr_crypto_block_t *ctx, unsigned char **out,
-            apr_size_t *outlen, const unsigned char *in, apr_size_t inlen);
+    apr_status_t (*block_encrypt)(unsigned char **out, apr_size_t *outlen,
+            const unsigned char *in, apr_size_t inlen, apr_crypto_block_t *ctx);
 
     /**
      * @brief Encrypt final data block, write it to out.
@@ -141,38 +161,37 @@
      *       number of bytes returned as actually written by the
      *       apr_crypto_block_encrypt() call. After this call, the context
      *       is cleaned and can be reused by apr_crypto_block_encrypt_init().
-     * @param ctx The block context to use.
      * @param out Address of a buffer to which data will be written. This
      *            buffer must already exist, and is usually the same
      *            buffer used by apr_evp_crypt(). See note.
      * @param outlen Length of the output will be written here.
+     * @param ctx The block context to use.
      * @return APR_ECRYPT if an error occurred.
      * @return APR_EPADDING if padding was enabled and the block was incorrectly
      *         formatted.
      * @return APR_ENOTIMPL if not implemented.
      */
-    apr_status_t (*block_encrypt_finish)(apr_crypto_block_t *ctx,
-            unsigned char *out, apr_size_t *outlen);
+    apr_status_t (*block_encrypt_finish)(unsigned char *out,
+            apr_size_t *outlen, apr_crypto_block_t *ctx);
 
     /**
      * @brief Initialise a context for decrypting arbitrary data using the given key.
      * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If
      *       *ctx is not NULL, *ctx must point at a previously created structure.
-     * @param p The pool to use.
-     * @param f The block factory to use.
-     * @param key The key structure.
+     * @param ctx The block context returned, see note.
+     * @param blockSize The block size of the cipher.
      * @param iv Optional initialisation vector. If the buffer pointed to is NULL,
      *           an IV will be created at random, in space allocated from the pool.
      *           If the buffer is not NULL, the IV in the buffer will be used.
-     * @param ctx The block context returned, see note.
-     * @param blockSize The block size of the cipher.
+     * @param key The key structure.
+     * @param p The pool to use.
      * @return Returns APR_ENOIV if an initialisation vector is required but not specified.
      *         Returns APR_EINIT if the backend failed to initialise the context. Returns
      *         APR_ENOTIMPL if not implemented.
      */
-    apr_status_t (*block_decrypt_init)(apr_pool_t *p, const apr_crypto_t *f,
-            const apr_crypto_key_t *key, const unsigned char *iv,
-            apr_crypto_block_t **ctx, apr_size_t *blockSize);
+    apr_status_t (*block_decrypt_init)(apr_crypto_block_t **ctx,
+            apr_size_t *blockSize, const unsigned char *iv,
+            const apr_crypto_key_t *key, apr_pool_t *p);
 
     /**
      * @brief Decrypt data provided by in, write it to out.
@@ -183,17 +202,17 @@
      *       to NULL, a buffer sufficiently large will be created from
      *       the pool provided. If *out points to a not-NULL value, this
      *       value will be used as a buffer instead.
-     * @param ctx The block context to use.
      * @param out Address of a buffer to which data will be written,
      *        see note.
      * @param outlen Length of the output will be written here.
      * @param in Address of the buffer to read.
      * @param inlen Length of the buffer to read.
+     * @param ctx The block context to use.
      * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if
      *         not implemented.
      */
-    apr_status_t (*block_decrypt)(apr_crypto_block_t *ctx, unsigned char **out,
-            apr_size_t *outlen, const unsigned char *in, apr_size_t inlen);
+    apr_status_t (*block_decrypt)(unsigned char **out, apr_size_t *outlen,
+            const unsigned char *in, apr_size_t inlen, apr_crypto_block_t *ctx);
 
     /**
      * @brief Decrypt final data block, write it to out.
@@ -203,44 +222,49 @@
      *       number of bytes returned as actually written by the
      *       apr_crypto_block_decrypt() call. After this call, the context
      *       is cleaned and can be reused by apr_crypto_block_decrypt_init().
-     * @param ctx The block context to use.
      * @param out Address of a buffer to which data will be written. This
      *            buffer must already exist, and is usually the same
      *            buffer used by apr_evp_crypt(). See note.
      * @param outlen Length of the output will be written here.
+     * @param ctx The block context to use.
      * @return APR_ECRYPT if an error occurred.
      * @return APR_EPADDING if padding was enabled and the block was incorrectly
      *         formatted.
      * @return APR_ENOTIMPL if not implemented.
      */
-    apr_status_t (*block_decrypt_finish)(apr_crypto_block_t *ctx,
-            unsigned char *out, apr_size_t *outlen);
+    apr_status_t (*block_decrypt_finish)(unsigned char *out,
+            apr_size_t *outlen, apr_crypto_block_t *ctx);
 
     /**
      * @brief Clean encryption / decryption context.
      * @note After cleanup, a context is free to be reused if necessary.
-     * @param driver - driver to use
      * @param ctx The block context to use.
      * @return Returns APR_ENOTIMPL if not supported.
      */
     apr_status_t (*block_cleanup)(apr_crypto_block_t *ctx);
 
     /**
-     * @brief Clean encryption / decryption factory.
-     * @note After cleanup, a factory is free to be reused if necessary.
-     * @param driver - driver to use
-     * @param f The factory to use.
+     * @brief Clean encryption / decryption context.
+     * @note After cleanup, a context is free to be reused if necessary.
+     * @param f The context to use.
      * @return Returns APR_ENOTIMPL if not supported.
      */
     apr_status_t (*cleanup)(apr_crypto_t *f);
 
     /**
-     * @brief Clean encryption / decryption factory.
-     * @note After cleanup, a factory is free to be reused if necessary.
-     * @param pool The pool to use.
+     * @brief Clean encryption / decryption context.
+     * @note After cleanup, a context is free to be reused if necessary.
      * @return Returns APR_ENOTIMPL if not supported.
      */
-    apr_status_t (*shutdown)(apr_pool_t *p);
+    apr_status_t (*shutdown)(void);
+
+    /**
+     * @brief: fetch the most recent error from this driver.
+     * @param result - the result structure
+     * @param f - context pointer
+     * @return APR_SUCCESS for success.
+     */
+    apr_status_t (*error)(const apu_err_t **result, const apr_crypto_t *f);
 
 };
 
diff --git a/include/private/apr_dbd_odbc_v2.h b/include/private/apr_dbd_odbc_v2.h
index dc7bc9c..b8da7b1 100644
--- a/include/private/apr_dbd_odbc_v2.h
+++ b/include/private/apr_dbd_odbc_v2.h
@@ -17,13 +17,13 @@
 
 /*  ONLY USED FOR ODBC Version 2   -DODBCV2
 *
-*   Re-define everything to work (more-or-less) in an ODBC V2 environment 
+*   Re-define everything to work (more-or-less) in an ODBC V2 environment
 *       Random access to retrieved rows is not supported - i.e. calls to apr_dbd_select() cannot
 *       have a 'random' argument of 1.  apr_dbd_get_row() must always pass rownum as 0 (get next row)
 *
 */
 
-#define SQLHANDLE SQLHENV   // Presumes that ENV, DBC, and STMT handles are all the same datatype
+#define SQLHANDLE SQLHENV /* Presumes that ENV, DBC, and STMT handles are all the same datatype */
 #define SQL_NULL_HANDLE 0
 #define SQL_HANDLE_STMT 1
 #define SQL_HANDLE_DBC  2
@@ -87,32 +87,32 @@
 #undef SQLColAttribute
 #define SQLColAttribute(s, c, f, a, l, m, n) SQLColAttributes(s, c, f, a, l, m, n)
 
-#define SQL_ATTR_ACCESS_MODE		SQL_ACCESS_MODE
-#define SQL_ATTR_AUTOCOMMIT			SQL_AUTOCOMMIT
-#define SQL_ATTR_CONNECTION_TIMEOUT	113
-#define SQL_ATTR_CURRENT_CATALOG	SQL_CURRENT_QUALIFIER
-#define SQL_ATTR_DISCONNECT_BEHAVIOR	114
-#define SQL_ATTR_ENLIST_IN_DTC		1207
-#define SQL_ATTR_ENLIST_IN_XA		1208
+#define SQL_ATTR_ACCESS_MODE            SQL_ACCESS_MODE
+#define SQL_ATTR_AUTOCOMMIT             SQL_AUTOCOMMIT
+#define SQL_ATTR_CONNECTION_TIMEOUT     113
+#define SQL_ATTR_CURRENT_CATALOG        SQL_CURRENT_QUALIFIER
+#define SQL_ATTR_DISCONNECT_BEHAVIOR    114
+#define SQL_ATTR_ENLIST_IN_DTC          1207
+#define SQL_ATTR_ENLIST_IN_XA           1208
 
-#define SQL_ATTR_CONNECTION_DEAD	1209
-#define SQL_CD_TRUE					1L		/* Connection is closed/dead */
-#define SQL_CD_FALSE				0L		/* Connection is open/available */
+#define SQL_ATTR_CONNECTION_DEAD        1209
+#define SQL_CD_TRUE                     1L   /* Connection is closed/dead */
+#define SQL_CD_FALSE                    0L   /* Connection is open/available */
 
-#define SQL_ATTR_LOGIN_TIMEOUT		SQL_LOGIN_TIMEOUT
-#define SQL_ATTR_ODBC_CURSORS		SQL_ODBC_CURSORS
-#define SQL_ATTR_PACKET_SIZE		SQL_PACKET_SIZE
-#define SQL_ATTR_QUIET_MODE			SQL_QUIET_MODE
-#define SQL_ATTR_TRACE				SQL_OPT_TRACE
-#define SQL_ATTR_TRACEFILE			SQL_OPT_TRACEFILE
-#define SQL_ATTR_TRANSLATE_LIB		SQL_TRANSLATE_DLL
-#define SQL_ATTR_TRANSLATE_OPTION	SQL_TRANSLATE_OPTION
-#define SQL_ATTR_TXN_ISOLATION		SQL_TXN_ISOLATION
+#define SQL_ATTR_LOGIN_TIMEOUT          SQL_LOGIN_TIMEOUT
+#define SQL_ATTR_ODBC_CURSORS           SQL_ODBC_CURSORS
+#define SQL_ATTR_PACKET_SIZE            SQL_PACKET_SIZE
+#define SQL_ATTR_QUIET_MODE             SQL_QUIET_MODE
+#define SQL_ATTR_TRACE                  SQL_OPT_TRACE
+#define SQL_ATTR_TRACEFILE              SQL_OPT_TRACEFILE
+#define SQL_ATTR_TRANSLATE_LIB          SQL_TRANSLATE_DLL
+#define SQL_ATTR_TRANSLATE_OPTION       SQL_TRANSLATE_OPTION
+#define SQL_ATTR_TXN_ISOLATION          SQL_TXN_ISOLATION
 
 #define SQL_ATTR_CURSOR_SCROLLABLE -1
 
-#define SQL_C_SBIGINT	(SQL_BIGINT+SQL_SIGNED_OFFSET)	   /* SIGNED BIGINT */
-#define SQL_C_UBIGINT	(SQL_BIGINT+SQL_UNSIGNED_OFFSET)   /* UNSIGNED BIGINT */
+#define SQL_C_SBIGINT (SQL_BIGINT+SQL_SIGNED_OFFSET)   /* SIGNED BIGINT */
+#define SQL_C_UBIGINT (SQL_BIGINT+SQL_UNSIGNED_OFFSET) /* UNSIGNED BIGINT */
 
 #define SQL_FALSE           0
 #define SQL_TRUE            1
diff --git a/ldap/NWGNUmakefile b/ldap/NWGNUmakefile
index 967a9f1..06260d1 100644
--- a/ldap/NWGNUmakefile
+++ b/ldap/NWGNUmakefile
@@ -10,7 +10,7 @@
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
@@ -26,8 +26,8 @@
 XINCDIRS	+= \
 			$(APR)/include \
 			$(APR)/include/arch/NetWare \
-			$(APRUTIL)/include \
-			$(APRUTIL)/include/private \
+			$(APU)/include \
+			$(APU)/include/private \
 			$(LDAPSDK)/inc \
 			$(EOLIST)
 
@@ -123,7 +123,7 @@
 NLM_THREAD_NAME	= 
 #
 # If this is specified, it will override VERSION value in 
-# $(APR_WORK)\build\NWGNUenvironment.inc
+# $(APR_WORK)/build/NWGNUenvironment.inc
 #
 NLM_VERSION		=
 
@@ -135,12 +135,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= 
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= 
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -246,7 +246,7 @@
 
 #
 # Updated this target to create necessary directories and copy files to the 
-# correct place.  (See $(APR_WORK)\build\NWGNUhead.inc for examples)
+# correct place.  (See $(APR_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
 
@@ -259,5 +259,5 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
diff --git a/ldap/apr_ldap_init.c b/ldap/apr_ldap_init.c
index 458f281..8aacb2a 100644
--- a/ldap/apr_ldap_init.c
+++ b/ldap/apr_ldap_init.c
@@ -156,13 +156,29 @@
     *result_err = result;
 
 #if APR_HAS_LDAPSSL_INIT
+#if APR_HAS_SOLARIS_LDAPSDK
+    /*
+     * Using the secure argument should aways be possible.  But as LDAP SDKs
+     * tend to have different quirks and bugs, this needs to be tested for
+     * for each of them, first. For Solaris LDAP it works, and the method
+     * with ldap_set_option doesn't.
+     */
+    *ldap = ldapssl_init(hostname, portno, secure == APR_LDAP_SSL);
+#else
     *ldap = ldapssl_init(hostname, portno, 0);
+#endif
 #elif APR_HAS_LDAP_SSLINIT
     *ldap = ldap_sslinit((char *)hostname, portno, 0);
 #else
     *ldap = ldap_init((char *)hostname, portno);
 #endif
+
     if (*ldap != NULL) {
+#if APR_HAS_SOLARIS_LDAPSDK
+        if (secure == APR_LDAP_SSL)
+            return APR_SUCCESS;
+        else
+#endif
         return apr_ldap_set_option(pool, *ldap, APR_LDAP_OPT_TLS, &secure, result_err);
     }
     else {
diff --git a/ldap/apr_ldap_rebind.c b/ldap/apr_ldap_rebind.c
index 4818d05..1f91b2b 100644
--- a/ldap/apr_ldap_rebind.c
+++ b/ldap/apr_ldap_rebind.c
@@ -64,6 +64,14 @@
 static int apr_ldap_rebind_set_callback(LDAP *ld);
 static apr_status_t apr_ldap_rebind_remove_helper(void *data);
 
+static apr_status_t apr_ldap_pool_cleanup_set_null(void *data_)
+{
+    void **ptr = (void **)data_;
+    *ptr = NULL;
+    return APR_SUCCESS;
+}
+
+
 /* APR utility routine used to create the xref_lock. */
 APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_init(apr_pool_t *pool)
 {
@@ -74,6 +82,10 @@
 #endif
 
 #if APR_HAS_THREADS
+    /* run after apr_thread_mutex_create cleanup */
+    apr_pool_cleanup_register(pool, &apr_ldap_xref_lock, apr_ldap_pool_cleanup_set_null,
+                              apr_pool_cleanup_null);
+
     if (apr_ldap_xref_lock == NULL) {
         retcode = apr_thread_mutex_create(&apr_ldap_xref_lock, APR_THREAD_MUTEX_DEFAULT, pool);
     }
@@ -107,14 +119,20 @@
         }
     
 #if APR_HAS_THREADS
-       apr_thread_mutex_lock(apr_ldap_xref_lock);
+       retcode = apr_thread_mutex_lock(apr_ldap_xref_lock);
+       if (retcode != APR_SUCCESS) { 
+           return retcode;
+       }
 #endif
     
         new_xref->next = xref_head;
         xref_head = new_xref;
     
 #if APR_HAS_THREADS
-        apr_thread_mutex_unlock(apr_ldap_xref_lock);
+        retcode = apr_thread_mutex_unlock(apr_ldap_xref_lock);
+        if (retcode != APR_SUCCESS) { 
+           return retcode;
+        }
 #endif
     }
     else {
@@ -138,13 +156,17 @@
 APU_DECLARE_LDAP(apr_status_t) apr_ldap_rebind_remove(LDAP *ld)
 {
     apr_ldap_rebind_entry_t *tmp_xref, *prev = NULL;
+    apr_status_t retcode = 0;
 
 #ifdef NETWARE
     get_apd
 #endif
 
 #if APR_HAS_THREADS
-    apr_thread_mutex_lock(apr_ldap_xref_lock);
+    retcode = apr_thread_mutex_lock(apr_ldap_xref_lock);
+    if (retcode != APR_SUCCESS) { 
+        return retcode;
+    }
 #endif
     tmp_xref = xref_head;
 
@@ -169,7 +191,10 @@
     }
 
 #if APR_HAS_THREADS
-    apr_thread_mutex_unlock(apr_ldap_xref_lock);
+    retcode = apr_thread_mutex_unlock(apr_ldap_xref_lock);
+    if (retcode != APR_SUCCESS) { 
+       return retcode;
+    }
 #endif
     return APR_SUCCESS;
 }
@@ -348,4 +373,5 @@
 
 #endif
 
+
 #endif       /* APR_HAS_LDAP */
diff --git a/libaprutil.dsp b/libaprutil.dsp
index f59866e..44f3993 100644
--- a/libaprutil.dsp
+++ b/libaprutil.dsp
@@ -45,7 +45,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "NDEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "NDEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "XML_STATIC" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -77,7 +77,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /EHsc /c
-# ADD CPP /nologo /MDd /W3 /Zi /Od /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "_DEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /EHsc /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "_DEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "XML_STATIC" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /EHsc /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -109,7 +109,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "NDEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "NDEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "XML_STATIC" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -141,7 +141,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /EHsc /c
-# ADD CPP /nologo /MDd /W3 /Zi /Od /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "_DEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /EHsc /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "./include" /I "../apr/include" /I "./include/private" /I "../apr-iconv/include" /I "./dbm/sdbm" /I "./xml/expat/lib" /D "_DEBUG" /D "APU_DECLARE_EXPORT" /D "APU_USE_SDBM" /D "XML_STATIC" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\libaprutil_src" /FD /EHsc /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
diff --git a/libaprutil.rc b/libaprutil.rc
index dbdad17..2beceeb 100644
--- a/libaprutil.rc
+++ b/libaprutil.rc
@@ -1,6 +1,6 @@
 #include "apu_version.h"
 
-#define APU_COPYRIGHT "Copyright (c) 2009 The Apache Software " \
+#define APU_COPYRIGHT "Copyright (c) 2011 The Apache Software " \
                       "Foundation or its licensors, as applicable."
 
 #define APU_LICENSE \
diff --git a/memcache/apr_memcache.c b/memcache/apr_memcache.c
index d244d56..f96d887 100644
--- a/memcache/apr_memcache.c
+++ b/memcache/apr_memcache.c
@@ -418,15 +418,17 @@
                                mc_conn_construct,       /* Make a New Connection */
                                mc_conn_destruct,        /* Kill Old Connection */
                                server, np);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
 
     apr_reslist_cleanup_order_set(server->conns, APR_RESLIST_CLEANUP_FIRST);
 #else
     rv = mc_conn_construct((void**)&(server->conn), server, np);
-#endif
-
     if (rv != APR_SUCCESS) {
         return rv;
     }
+#endif
 
     *ms = server;
 
@@ -772,11 +774,9 @@
     if (strncmp(MS_VALUE, conn->buffer, MS_VALUE_LEN) == 0) {
         char *flags;
         char *length;
-        char *start;
         char *last;
         apr_size_t len = 0;
 
-        start = conn->buffer;
         flags = apr_strtok(conn->buffer, " ", &last);
         flags = apr_strtok(NULL, " ", &last);
         flags = apr_strtok(NULL, " ", &last);
@@ -1345,12 +1345,10 @@
                char *key;
                char *flags;
                char *length;
-               char *start;
                char *last;
                char *data;
                apr_size_t len = 0;
 
-               start = conn->buffer;
                key = apr_strtok(conn->buffer, " ", &last); /* just the VALUE, ignore */
                key = apr_strtok(NULL, " ", &last);
                flags = apr_strtok(NULL, " ", &last);
diff --git a/misc/apr_queue.c b/misc/apr_queue.c
index b74fdf8..82859c8 100644
--- a/misc/apr_queue.c
+++ b/misc/apr_queue.c
@@ -185,7 +185,9 @@
     }
 
     queue->data[queue->in] = data;
-    queue->in = (queue->in + 1) % queue->bounds;
+    queue->in++;
+    if (queue->in >= queue->bounds)
+        queue->in -= queue->bounds;
     queue->nelts++;
 
     if (queue->empty_waiters) {
@@ -225,7 +227,9 @@
     }
     
     queue->data[queue->in] = data;
-    queue->in = (queue->in + 1) % queue->bounds;
+    queue->in++;
+    if (queue->in >= queue->bounds)
+        queue->in -= queue->bounds;
     queue->nelts++;
 
     if (queue->empty_waiters) {
@@ -297,7 +301,9 @@
     *data = queue->data[queue->out];
     queue->nelts--;
 
-    queue->out = (queue->out + 1) % queue->bounds;
+    queue->out++;
+    if (queue->out >= queue->bounds)
+        queue->out -= queue->bounds;
     if (queue->full_waiters) {
         Q_DBG("signal !full", queue);
         rv = apr_thread_cond_signal(queue->not_full);
@@ -337,7 +343,9 @@
     *data = queue->data[queue->out];
     queue->nelts--;
 
-    queue->out = (queue->out + 1) % queue->bounds;
+    queue->out++;
+    if (queue->out >= queue->bounds)
+        queue->out -= queue->bounds;
     if (queue->full_waiters) {
         Q_DBG("signal !full", queue);
         rv = apr_thread_cond_signal(queue->not_full);
diff --git a/misc/apr_thread_pool.c b/misc/apr_thread_pool.c
index 693518d..01c2e21 100644
--- a/misc/apr_thread_pool.c
+++ b/misc/apr_thread_pool.c
@@ -72,7 +72,6 @@
     struct apr_thread_list *busy_thds;
     struct apr_thread_list *idle_thds;
     apr_thread_mutex_t *lock;
-    apr_thread_mutex_t *cond_lock;
     apr_thread_cond_t *cond;
     volatile int terminated;
     struct apr_thread_pool_tasks *recycled_tasks;
@@ -95,16 +94,9 @@
     if (APR_SUCCESS != rv) {
         return rv;
     }
-    rv = apr_thread_mutex_create(&me->cond_lock, APR_THREAD_MUTEX_UNNESTED,
-                                 me->pool);
-    if (APR_SUCCESS != rv) {
-        apr_thread_mutex_destroy(me->lock);
-        return rv;
-    }
     rv = apr_thread_cond_create(&me->cond, me->pool);
     if (APR_SUCCESS != rv) {
         apr_thread_mutex_destroy(me->lock);
-        apr_thread_mutex_destroy(me->cond_lock);
         return rv;
     }
     me->tasks = apr_palloc(me->pool, sizeof(*me->tasks));
@@ -148,7 +140,6 @@
   CATCH_ENOMEM:
     rv = APR_ENOMEM;
     apr_thread_mutex_destroy(me->lock);
-    apr_thread_mutex_destroy(me->cond_lock);
     apr_thread_cond_destroy(me->cond);
   FINAL_EXIT:
     return rv;
@@ -246,7 +237,6 @@
  */
 static void *APR_THREAD_FUNC thread_pool_func(apr_thread_t * t, void *param)
 {
-    apr_status_t rv = APR_SUCCESS;
     apr_thread_pool_t *me = param;
     apr_thread_pool_task_t *task = NULL;
     apr_interval_time_t wait;
@@ -321,16 +311,12 @@
         else
             wait = -1;
 
-        apr_thread_mutex_unlock(me->lock);
-        apr_thread_mutex_lock(me->cond_lock);
         if (wait >= 0) {
-            rv = apr_thread_cond_timedwait(me->cond, me->cond_lock, wait);
+            apr_thread_cond_timedwait(me->cond, me->lock, wait);
         }
         else {
-            rv = apr_thread_cond_wait(me->cond, me->cond_lock);
+            apr_thread_cond_wait(me->cond, me->lock);
         }
-        apr_thread_mutex_unlock(me->cond_lock);
-        apr_thread_mutex_lock(me->lock);
     }
 
     /* idle thread been asked to stop, will be joined */
@@ -342,16 +328,15 @@
 
 static apr_status_t thread_pool_cleanup(void *me)
 {
-    apr_thread_pool_t *_self = me;
+    apr_thread_pool_t *_myself = me;
 
-    _self->terminated = 1;
-    apr_thread_pool_idle_max_set(_self, 0);
-    while (_self->thd_cnt) {
+    _myself->terminated = 1;
+    apr_thread_pool_idle_max_set(_myself, 0);
+    while (_myself->thd_cnt) {
         apr_sleep(20 * 1000);   /* spin lock with 20 ms */
     }
-    apr_thread_mutex_destroy(_self->lock);
-    apr_thread_mutex_destroy(_self->cond_lock);
-    apr_thread_cond_destroy(_self->cond);
+    apr_thread_mutex_destroy(_myself->lock);
+    apr_thread_cond_destroy(_myself->cond);
     return APR_SUCCESS;
 }
 
@@ -367,17 +352,28 @@
     *me = NULL;
     tp = apr_pcalloc(pool, sizeof(apr_thread_pool_t));
 
-    tp->pool = pool;
-
-    rv = thread_pool_construct(tp, init_threads, max_threads);
-    if (APR_SUCCESS != rv) {
+    /*
+     * This pool will be used by different threads. As we cannot ensure that
+     * our caller won't use the pool without acquiring the mutex, we must
+     * create a new sub pool.
+     */
+    rv = apr_pool_create(&tp->pool, pool);
+    if (APR_SUCCESS != rv)
         return rv;
-    }
-    apr_pool_cleanup_register(pool, tp, thread_pool_cleanup,
+    rv = thread_pool_construct(tp, init_threads, max_threads);
+    if (APR_SUCCESS != rv)
+        return rv;
+    apr_pool_cleanup_register(tp->pool, tp, thread_pool_cleanup,
                               apr_pool_cleanup_null);
 
     while (init_threads) {
+        /* Grab the mutex as apr_thread_create() and thread_pool_func() will 
+         * allocate from (*me)->pool. This is dangerous if there are multiple 
+         * initial threads to create.
+         */
+        apr_thread_mutex_lock(tp->lock);
         rv = apr_thread_create(&t, NULL, thread_pool_func, tp, tp->pool);
+        apr_thread_mutex_unlock(tp->lock);
         if (APR_SUCCESS != rv) {
             break;
         }
@@ -524,10 +520,8 @@
                 me->thd_high = me->thd_cnt;
         }
     }
-    apr_thread_mutex_unlock(me->lock);
-    apr_thread_mutex_lock(me->cond_lock);
     apr_thread_cond_signal(me->cond);
-    apr_thread_mutex_unlock(me->cond_lock);
+    apr_thread_mutex_unlock(me->lock);
     return rv;
 }
 
@@ -579,11 +573,9 @@
                 me->thd_high = me->thd_cnt;
         }
     }
-    apr_thread_mutex_unlock(me->lock);
 
-    apr_thread_mutex_lock(me->cond_lock);
     apr_thread_cond_signal(me->cond);
-    apr_thread_mutex_unlock(me->cond_lock);
+    apr_thread_mutex_unlock(me->lock);
 
     return rv;
 }
@@ -841,9 +833,9 @@
 
     elt = trim_threads(me, &cnt, 1);
 
-    apr_thread_mutex_lock(me->cond_lock);
+    apr_thread_mutex_lock(me->lock);
     apr_thread_cond_broadcast(me->cond);
-    apr_thread_mutex_unlock(me->cond_lock);
+    apr_thread_mutex_unlock(me->lock);
 
     n_dbg = 0;
     if (NULL != (head = elt)) {
diff --git a/test/Makefile.in b/test/Makefile.in
index a2a3c6d..cf89a54 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -12,7 +12,7 @@
 
 INCLUDES = @APRUTIL_PRIV_INCLUDES@ @APR_INCLUDES@ @APRUTIL_INCLUDES@
 
-STDTEST_PORTABLE = testall dbd
+STDTEST_PORTABLE = dbd testall
 
 TESTS = teststrmatch.lo testuri.lo testuuid.lo testbuckets.lo testpass.lo \
 	testmd4.lo testmd5.lo testldap.lo testdate.lo testdbm.lo testdbd.lo \
@@ -59,7 +59,7 @@
 check: $(TESTALL_COMPONENTS) $(STDTEST_PORTABLE) $(STDTEST_NONPORTABLE)
 	teststatus=0; \
 	progfailed=""; \
-	for prog in $(STDTEST_PORTABLE) $(STDTEST_NONPORTABLE); do \
+	for prog in $(STDTEST_NONPORTABLE) $(STDTEST_PORTABLE); do \
 	        if test "$$prog" = 'dbd'; then \
 			for driver in none @apu_dbd_tests@; do \
 				if test "$$driver" != 'none'; then \
diff --git a/test/Makefile.win b/test/Makefile.win
index c1c8533..9f5ca84 100644
--- a/test/Makefile.win
+++ b/test/Makefile.win
@@ -157,11 +157,11 @@
 APR_ICONV1_PATH=$(API_PATH)\$(OUTDIR)\iconv
 
 check: $(PROGRAMS) $(OTHER_PROGRAMS)
+	echo Testing dbd sqlite2 && $(OUTDIR)\dbd.exe sqlite2 || echo Failed
+	echo Testing dbd sqlite3 && $(OUTDIR)\dbd.exe sqlite3 || echo Failed
 	@for %p in ($(PROGRAMS)) do @( \
 	    echo Testing %p && %p -v || echo %p failed \
 	)
-	echo Testing dbd sqlite2 && $(OUTDIR)\dbd.exe sqlite2 || echo Failed
-	echo Testing dbd sqlite3 && $(OUTDIR)\dbd.exe sqlite3 || echo Failed
 
 checkall: check
 
diff --git a/test/NWGNUaputest b/test/NWGNUaputest
index f41b8f7..6b710ad 100644
--- a/test/NWGNUaputest
+++ b/test/NWGNUaputest
@@ -8,7 +8,7 @@
 #
 
 ifndef EnvironmentDefined
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 endif
 
 #
@@ -18,7 +18,7 @@
 XINCDIRS	+= \
 			$(APR)/include \
 			$(APR)/include/arch/NetWare \
-			$(APRUTIL)/include \
+			$(APU)/include \
 			$(LDAPSDK)/inc \
 			$(EOLIST)
 
@@ -112,7 +112,7 @@
 
 #
 # If this is specified, it will override VERSION value in 
-# $(APR_WORK)\build\NWGNUenvironment.inc
+# $(APR_WORK)/build/NWGNUenvironment.inc
 #
 NLM_VERSION	=
 
@@ -124,12 +124,12 @@
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= _LibCPrelude
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= _LibCPostlude
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -139,7 +139,7 @@
 #
 # If this is specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS	= AUTOUNLOAD, PSEUDOPREEMPTION
+NLM_FLAGS	=
  
 #
 # If this is specified it will be linked in with the XDCData option in the def 
@@ -201,7 +201,7 @@
 # These will be added as a library command in the link.opt file.
 #
 FILES_nlm_libs = \
-	libcpre.o \
+	$(PRELUDE) \
 	$(EOLIST)
 
 #
@@ -213,7 +213,6 @@
 	APRLIB \
 	lldapsdk \
 	lldapssl \
-	lldapx \
 	$(EOLIST)
 
 #
@@ -236,9 +235,9 @@
 #
 FILES_nlm_Ximports = \
 	@libc.imp \
-	@$(APR)/aprlib.imp \
-	@$(LDAPSDK)/imports/lldapsdk.imp \
-	@$(LDAPSDK)/imports/lldapssl.imp \
+	@aprlib.imp \
+	@lldapsdk.imp \
+	@lldapssl.imp \
 	$(EOLIST)
  
 #   
@@ -264,7 +263,7 @@
 
 #
 # Updated this target to create necessary directories and copy files to the 
-# correct place.  (See $(APR_WORK)\build\NWGNUhead.inc for examples)
+# correct place.  (See $(APR_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
 
@@ -278,5 +277,5 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
diff --git a/test/NWGNUmakefile b/test/NWGNUmakefile
index c28e3e2..a36d178 100644
--- a/test/NWGNUmakefile
+++ b/test/NWGNUmakefile
@@ -10,7 +10,7 @@
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
@@ -120,7 +120,7 @@
 
 #
 # If this is specified, it will override VERSION value in
-# $(APR_WORK)\build\NWGNUenvironment.inc
+# $(APR_WORK)/build/NWGNUenvironment.inc
 #
 NLM_VERSION	=
 
@@ -239,10 +239,10 @@
 
 #
 # Updated this target to create necessary directories and copy files to the
-# correct place.  (See $(APR_WORK)\build\NWGNUhead.inc for examples)
+# correct place.  (See $(APR_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
-	copy $(OBJDIR)\*.nlm $(INSTALLBASE)
+	$(call COPY,$(OBJDIR)/*.nlm,$(INSTALLBASE))
 
 #
 # Any specialized rules here
@@ -253,5 +253,5 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
diff --git a/test/nw_misc.c b/test/nw_misc.c
index 2c1e5e2..b45f951 100644
--- a/test/nw_misc.c
+++ b/test/nw_misc.c
@@ -1,4 +1,6 @@
+#include <stdio.h>
 #include <stdlib.h>
+#include <screen.h>
 /*
 #include "testutil.h"
 */
@@ -6,6 +8,7 @@
 /* function to keep the screen open if not launched from bash */
 void _NonAppStop( void )
 {
+  if (getenv("_IN_NETWARE_BASH_") == NULL) {
     printf("\r\n<Press any key to close screen> ");
     getcharacter();
   }
diff --git a/test/testbuckets.c b/test/testbuckets.c
index 6c3653f..807b2a5 100644
--- a/test/testbuckets.c
+++ b/test/testbuckets.c
@@ -368,7 +368,7 @@
 
     ABTS_ASSERT(tc, "create test file",
                 apr_file_open(&f, fname,
-                              APR_READ|APR_WRITE|APR_TRUNCATE|APR_CREATE,
+                              APR_FOPEN_READ|APR_FOPEN_WRITE|APR_FOPEN_TRUNCATE|APR_FOPEN_CREATE,
                               APR_OS_DEFAULT, p) == APR_SUCCESS);
     
     ABTS_ASSERT(tc, "write test file contents",
diff --git a/test/testcrypto.c b/test/testcrypto.c
index cc81b73..335c3ae 100644
--- a/test/testcrypto.c
+++ b/test/testcrypto.c
@@ -29,16 +29,17 @@
 #define ALIGNED_STRING "123456789012345"
 
 static const apr_crypto_driver_t *get_driver(abts_case *tc, apr_pool_t *pool,
-        const char *name, const apr_array_header_t *params) {
+        const char *name, const char *params)
+{
 
     const apr_crypto_driver_t *driver = NULL;
     const apu_err_t *err = NULL;
     apr_status_t rv;
 
-    rv = apr_crypto_init(pool, params);
+    rv = apr_crypto_init(pool);
     ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS);
 
-    rv = apr_crypto_get_driver(pool, name, &driver, params, &err);
+    rv = apr_crypto_get_driver(&driver, name, params, &err, pool);
     if (APR_SUCCESS != rv && err) {
         ABTS_NOT_IMPL(tc, err->msg);
         return NULL;
@@ -58,29 +59,25 @@
 }
 
 static const apr_crypto_driver_t *get_nss_driver(abts_case *tc,
-        apr_pool_t *pool) {
-
-    apr_array_header_t *params;
-    apr_crypto_param_t *param;
+        apr_pool_t *pool)
+{
 
     /* initialise NSS */
-    params = apr_array_make(pool, 10, sizeof(apr_crypto_param_t));
-    param = apr_array_push(params);
-    param->type = APR_CRYPTO_CA_TYPE_DIR;
-    param->path = "data";
-    return get_driver(tc, pool, "nss", params);
+    return get_driver(tc, pool, "nss", "dir=data");
 
 }
 
 static const apr_crypto_driver_t *get_openssl_driver(abts_case *tc,
-        apr_pool_t *pool) {
+        apr_pool_t *pool)
+{
 
     return get_driver(tc, pool, "openssl", NULL);
 
 }
 
-static apr_crypto_t *factory(abts_case *tc, apr_pool_t *pool,
-        const apr_crypto_driver_t *driver) {
+static apr_crypto_t *make(abts_case *tc, apr_pool_t *pool,
+        const apr_crypto_driver_t *driver)
+{
 
     apr_crypto_t *f = NULL;
 
@@ -88,9 +85,9 @@
         return NULL;
     }
 
-    /* get the factory */
-    apr_crypto_factory(driver, pool, NULL, &f);
-    ABTS_ASSERT(tc, "apr_crypto_factory returned NULL", f != NULL);
+    /* get the context */
+    apr_crypto_make(&f, driver, "engine=openssl", pool);
+    ABTS_ASSERT(tc, "apr_crypto_make returned NULL", f != NULL);
 
     return f;
 
@@ -99,30 +96,38 @@
 static const apr_crypto_key_t *passphrase(abts_case *tc, apr_pool_t *pool,
         const apr_crypto_driver_t *driver, const apr_crypto_t *f,
         apr_crypto_block_key_type_e type, apr_crypto_block_key_mode_e mode,
-        int doPad, const char *description) {
+        int doPad, const char *description)
+{
 
     apr_crypto_key_t *key = NULL;
+    const apu_err_t *result = NULL;
     const char *pass = "secret";
     const char *salt = "salt";
     apr_status_t rv;
 
-    if (!driver || !f) {
+    if (!f) {
         return NULL;
     }
 
     /* init the passphrase */
-    rv = apr_crypto_passphrase(driver, pool, f, pass, strlen(pass),
-            (unsigned char *) salt, strlen(salt), type, mode, doPad, 4096,
-            &key, NULL);
+    rv = apr_crypto_passphrase(&key, NULL, pass, strlen(pass),
+            (unsigned char *) salt, strlen(salt), type, mode, doPad, 4096, f,
+            pool);
     if (APR_ENOCIPHER == rv) {
-        ABTS_NOT_IMPL(tc, apr_psprintf(pool, "skipped: %s %s passphrase return APR_ENOCIPHER: error %d: %s (%s)\n", description, apr_crypto_driver_name(driver), f->result->rc, f->result->reason ? f->result->reason : "", f->result->msg ? f->result->msg : ""));
+        apr_crypto_error(&result, f);
+        ABTS_NOT_IMPL(tc, apr_psprintf(pool,
+                        "skipped: %s %s passphrase return APR_ENOCIPHER: error %d: %s (%s)\n",
+                        description, apr_crypto_driver_name(driver), result->rc,
+                        result->reason ? result->reason : "", result->msg ? result->msg : ""));
         return NULL;
-    } else {
+    }
+    else {
         if (APR_SUCCESS != rv) {
+            apr_crypto_error(&result, f);
             fprintf(stderr, "passphrase: %s %s native error %d: %s (%s)\n",
-                    description, apr_crypto_driver_name(driver), f->result->rc,
-                    f->result->reason ? f->result->reason : "",
-                    f->result->msg ? f->result->msg : "");
+                    description, apr_crypto_driver_name(driver), result->rc,
+                    result->reason ? result->reason : "",
+                    result->msg ? result->msg : "");
         }
         ABTS_ASSERT(tc, "apr_crypto_passphrase returned APR_ENOKEY", rv != APR_ENOKEY);
         ABTS_ASSERT(tc, "apr_crypto_passphrase returned APR_EPADDING", rv != APR_EPADDING);
@@ -142,9 +147,11 @@
         const apr_crypto_key_t *key, const unsigned char *in,
         const apr_size_t inlen, unsigned char **cipherText,
         apr_size_t *cipherTextLen, const unsigned char **iv,
-        apr_size_t *blockSize, const char *description) {
+        apr_size_t *blockSize, const char *description)
+{
 
     apr_crypto_block_t *block = NULL;
+    const apu_err_t *result = NULL;
     apr_size_t len = 0;
     apr_status_t rv;
 
@@ -153,16 +160,17 @@
     }
 
     /* init the encryption */
-    rv = apr_crypto_block_encrypt_init(driver, pool, f, key, iv, &block,
-            blockSize);
+    rv = apr_crypto_block_encrypt_init(&block, iv, key, blockSize, pool);
     if (APR_ENOTIMPL == rv) {
         ABTS_NOT_IMPL(tc, "apr_crypto_block_encrypt_init returned APR_ENOTIMPL");
-    } else {
+    }
+    else {
         if (APR_SUCCESS != rv) {
+            apr_crypto_error(&result, f);
             fprintf(stderr, "encrypt_init: %s %s native error %d: %s (%s)\n",
-                    description, apr_crypto_driver_name(driver), f->result->rc,
-                    f->result->reason ? f->result->reason : "",
-                    f->result->msg ? f->result->msg : "");
+                    description, apr_crypto_driver_name(driver), result->rc,
+                    result->reason ? result->reason : "",
+                    result->msg ? result->msg : "");
         }
         ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOKEY", rv != APR_ENOKEY);
         ABTS_ASSERT(tc, "apr_crypto_block_encrypt_init returned APR_ENOIV", rv != APR_ENOIV);
@@ -176,13 +184,13 @@
     }
 
     /* encrypt the block */
-    rv = apr_crypto_block_encrypt(driver, block, cipherText,
-            cipherTextLen, in, inlen);
+    rv = apr_crypto_block_encrypt(cipherText, cipherTextLen, in, inlen, block);
     if (APR_SUCCESS != rv) {
+        apr_crypto_error(&result, f);
         fprintf(stderr, "encrypt: %s %s native error %d: %s (%s)\n",
-                description, apr_crypto_driver_name(driver), f->result->rc,
-                f->result->reason ? f->result->reason : "",
-                f->result->msg ? f->result->msg : "");
+                description, apr_crypto_driver_name(driver), result->rc,
+                result->reason ? result->reason : "", result->msg ? result->msg
+                        : "");
     }
     ABTS_ASSERT(tc, "apr_crypto_block_encrypt returned APR_ECRYPT", rv != APR_ECRYPT);
     ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt", rv == APR_SUCCESS);
@@ -192,19 +200,20 @@
     }
 
     /* finalise the encryption */
-    rv = apr_crypto_block_encrypt_finish(driver, block, *cipherText
-            + *cipherTextLen, &len);
+    rv = apr_crypto_block_encrypt_finish(*cipherText + *cipherTextLen, &len,
+            block);
     if (APR_SUCCESS != rv) {
+        apr_crypto_error(&result, f);
         fprintf(stderr, "encrypt_finish: %s %s native error %d: %s (%s)\n",
-                description, apr_crypto_driver_name(driver), f->result->rc,
-                f->result->reason ? f->result->reason : "",
-                f->result->msg ? f->result->msg : "");
+                description, apr_crypto_driver_name(driver), result->rc,
+                result->reason ? result->reason : "", result->msg ? result->msg
+                        : "");
     }
     ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT);
     ABTS_ASSERT(tc, "apr_crypto_block_encrypt_finish returned APR_EPADDING", rv != APR_EPADDING);
     ABTS_ASSERT(tc, "failed to apr_crypto_block_encrypt_finish", rv == APR_SUCCESS);
     *cipherTextLen += len;
-    apr_crypto_block_cleanup(driver, block);
+    apr_crypto_block_cleanup(block);
     if (rv) {
         return NULL;
     }
@@ -218,9 +227,11 @@
         const apr_crypto_key_t *key, unsigned char *cipherText,
         apr_size_t cipherTextLen, unsigned char **plainText,
         apr_size_t *plainTextLen, const unsigned char *iv,
-        apr_size_t *blockSize, const char *description) {
+        apr_size_t *blockSize, const char *description)
+{
 
     apr_crypto_block_t *block = NULL;
+    const apu_err_t *result = NULL;
     apr_size_t len = 0;
     apr_status_t rv;
 
@@ -229,16 +240,17 @@
     }
 
     /* init the decryption */
-    rv = apr_crypto_block_decrypt_init(driver, pool, f, key, iv, &block,
-            blockSize);
+    rv = apr_crypto_block_decrypt_init(&block, blockSize, iv, key, pool);
     if (APR_ENOTIMPL == rv) {
         ABTS_NOT_IMPL(tc, "apr_crypto_block_decrypt_init returned APR_ENOTIMPL");
-    } else {
+    }
+    else {
         if (APR_SUCCESS != rv) {
+            apr_crypto_error(&result, f);
             fprintf(stderr, "decrypt_init: %s %s native error %d: %s (%s)\n",
-                    description, apr_crypto_driver_name(driver), f->result->rc,
-                    f->result->reason ? f->result->reason : "",
-                    f->result->msg ? f->result->msg : "");
+                    description, apr_crypto_driver_name(driver), result->rc,
+                    result->reason ? result->reason : "",
+                    result->msg ? result->msg : "");
         }
         ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_ENOKEY", rv != APR_ENOKEY);
         ABTS_ASSERT(tc, "apr_crypto_block_decrypt_init returned APR_ENOIV", rv != APR_ENOIV);
@@ -252,13 +264,14 @@
     }
 
     /* decrypt the block */
-    rv = apr_crypto_block_decrypt(driver, block, plainText, plainTextLen,
-            cipherText, cipherTextLen);
+    rv = apr_crypto_block_decrypt(plainText, plainTextLen, cipherText,
+            cipherTextLen, block);
     if (APR_SUCCESS != rv) {
+        apr_crypto_error(&result, f);
         fprintf(stderr, "decrypt: %s %s native error %d: %s (%s)\n",
-                description, apr_crypto_driver_name(driver), f->result->rc,
-                f->result->reason ? f->result->reason : "",
-                f->result->msg ? f->result->msg : "");
+                description, apr_crypto_driver_name(driver), result->rc,
+                result->reason ? result->reason : "", result->msg ? result->msg
+                        : "");
     }
     ABTS_ASSERT(tc, "apr_crypto_block_decrypt returned APR_ECRYPT", rv != APR_ECRYPT);
     ABTS_ASSERT(tc, "failed to apr_crypto_block_decrypt", rv == APR_SUCCESS);
@@ -268,13 +281,14 @@
     }
 
     /* finalise the decryption */
-    rv = apr_crypto_block_decrypt_finish(driver, block, *plainText
-            + *plainTextLen, &len);
+    rv = apr_crypto_block_decrypt_finish(*plainText + *plainTextLen, &len,
+            block);
     if (APR_SUCCESS != rv) {
+        apr_crypto_error(&result, f);
         fprintf(stderr, "decrypt_finish: %s %s native error %d: %s (%s)\n",
-                description, apr_crypto_driver_name(driver), f->result->rc,
-                f->result->reason ? f->result->reason : "",
-                f->result->msg ? f->result->msg : "");
+                description, apr_crypto_driver_name(driver), result->rc,
+                result->reason ? result->reason : "", result->msg ? result->msg
+                        : "");
     }
     ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_ECRYPT", rv != APR_ECRYPT);
     ABTS_ASSERT(tc, "apr_crypto_block_decrypt_finish returned APR_EPADDING", rv != APR_EPADDING);
@@ -284,7 +298,7 @@
     }
 
     *plainTextLen += len;
-    apr_crypto_block_cleanup(driver, block);
+    apr_crypto_block_cleanup(block);
 
     return *plainText;
 
@@ -302,7 +316,8 @@
         const apr_crypto_driver_t **drivers,
         const apr_crypto_block_key_type_e type,
         const apr_crypto_block_key_mode_e mode, int doPad,
-        const unsigned char *in, apr_size_t inlen, const char *description) {
+        const unsigned char *in, apr_size_t inlen, const char *description)
+{
     const apr_crypto_driver_t *driver1 = drivers[0];
     const apr_crypto_driver_t *driver2 = drivers[1];
     apr_crypto_t *f1 = NULL;
@@ -317,8 +332,8 @@
     const unsigned char *iv = NULL;
     apr_size_t blockSize = 0;
 
-    f1 = factory(tc, pool, driver1);
-    f2 = factory(tc, pool, driver2);
+    f1 = make(tc, pool, driver1);
+    f2 = make(tc, pool, driver2);
     key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description);
     key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description);
 
@@ -342,13 +357,14 @@
 /**
  * Test initialisation.
  */
-static void test_crypto_init(abts_case *tc, void *data) {
+static void test_crypto_init(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     apr_status_t rv;
 
     apr_pool_create(&pool, NULL);
 
-    rv = apr_crypto_init(pool, NULL);
+    rv = apr_crypto_init(pool);
     ABTS_ASSERT(tc, "failed to init apr_crypto", rv == APR_SUCCESS);
 
     apr_pool_destroy(pool);
@@ -358,7 +374,8 @@
 /**
  * Simple test of OpenSSL block crypt.
  */
-static void test_crypto_block_openssl(abts_case *tc, void *data) {
+static void test_crypto_block_openssl(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -368,22 +385,22 @@
     apr_pool_create(&pool, NULL);
     drivers[0] = get_openssl_driver(tc, pool);
     drivers[1] = get_openssl_driver(tc, pool);
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 0, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen,
-            "KEY_3DES_192/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 0, in, inlen,
-            "KEY_AES_256/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 0, in, inlen,
-            "KEY_AES_256/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen,
-            "KEY_AES_192/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen,
-            "KEY_AES_192/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen,
-            "KEY_AES_128/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen,
-            "KEY_AES_128/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 0,
+            in, inlen, "KEY_3DES_192/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_256/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_192/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_128/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_128/MODE_ECB");
     apr_pool_destroy(pool);
 
 }
@@ -391,7 +408,8 @@
 /**
  * Simple test of NSS block crypt.
  */
-static void test_crypto_block_nss(abts_case *tc, void *data) {
+static void test_crypto_block_nss(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -401,22 +419,22 @@
     apr_pool_create(&pool, NULL);
     drivers[0] = get_nss_driver(tc, pool);
     drivers[1] = get_nss_driver(tc, pool);
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 0, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 0, in, inlen,
-            "KEY_AES_256/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 0, in, inlen,
-            "KEY_AES_256/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 0, in, inlen,
-            "KEY_AES_192/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 0, in, inlen,
-            "KEY_AES_192/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 0, in, inlen,
-            "KEY_AES_128/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 0, in, inlen,
-            "KEY_AES_128/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_256/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_192/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_128/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_128/MODE_ECB");
     apr_pool_destroy(pool);
 
 }
@@ -424,7 +442,8 @@
 /**
  * Encrypt NSS, decrypt OpenSSL.
  */
-static void test_crypto_block_nss_openssl(abts_case *tc, void *data) {
+static void test_crypto_block_nss_openssl(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -435,15 +454,15 @@
     drivers[0] = get_nss_driver(tc, pool);
     drivers[1] = get_openssl_driver(tc, pool);
 
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 0, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
 
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 0, in, inlen,
-            "KEY_AES_256/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 0, in, inlen,
-            "KEY_AES_256/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_256/MODE_ECB");
 
     /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
      * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
@@ -462,7 +481,8 @@
 /**
  * Encrypt OpenSSL, decrypt NSS.
  */
-static void test_crypto_block_openssl_nss(abts_case *tc, void *data) {
+static void test_crypto_block_openssl_nss(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -472,16 +492,16 @@
     apr_pool_create(&pool, NULL);
     drivers[0] = get_openssl_driver(tc, pool);
     drivers[1] = get_nss_driver(tc, pool);
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 0, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 0,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
 
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 0, in, inlen, "KEY_3DES_192/MODE_ECB"); */
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 0, in, inlen,
-            "KEY_AES_256/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 0, in, inlen,
-            "KEY_AES_256/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 0, in,
+            inlen, "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 0, in,
+            inlen, "KEY_AES_256/MODE_ECB");
 
     /* all 4 of these tests fail to interoperate - a clue from the xml-security code is that
      * NSS cannot distinguish between the 128 and 192 bit versions of AES. Will need to be
@@ -500,7 +520,8 @@
 /**
  * Simple test of OpenSSL block crypt.
  */
-static void test_crypto_block_openssl_pad(abts_case *tc, void *data) {
+static void test_crypto_block_openssl_pad(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -511,22 +532,22 @@
     drivers[0] = get_openssl_driver(tc, pool);
     drivers[1] = get_openssl_driver(tc, pool);
 
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 1, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen,
-            "KEY_3DES_192/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 1, in, inlen,
-            "KEY_AES_256/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen,
-            "KEY_AES_256/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen,
-            "KEY_AES_192/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen,
-            "KEY_AES_192/MODE_ECB");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen,
-            "KEY_AES_128/MODE_CBC");
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen,
-            "KEY_AES_128/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_ECB, 1,
+            in, inlen, "KEY_3DES_192/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_ECB, 1, in,
+            inlen, "KEY_AES_256/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_ECB, 1, in,
+            inlen, "KEY_AES_192/MODE_ECB");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_128/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_ECB, 1, in,
+            inlen, "KEY_AES_128/MODE_ECB");
 
     apr_pool_destroy(pool);
 
@@ -535,9 +556,11 @@
 /**
  * Simple test of NSS block crypt.
  */
-static void test_crypto_block_nss_pad(abts_case *tc, void *data) {
+static void test_crypto_block_nss_pad(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
-    const apr_crypto_driver_t *drivers[] = { NULL, NULL };
+    const apr_crypto_driver_t *drivers[] =
+    { NULL, NULL };
 
     const unsigned char *in = (const unsigned char *) TEST_STRING;
     apr_size_t inlen = sizeof(TEST_STRING);
@@ -546,25 +569,25 @@
     drivers[0] = get_nss_driver(tc, pool);
     drivers[1] = get_nss_driver(tc, pool);
 
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 1, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 1, in, inlen,
-            "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_256/MODE_CBC");
 
     /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
     /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_CBC, 1, in, inlen,
-            "KEY_AES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_192, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_192/MODE_CBC");
 
     /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
     /*crypto_block_cross(tc, pool, drivers, KEY_AES_192, MODE_ECB, 1, in, inlen, "KEY_AES_192/MODE_ECB");*/
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_CBC, 1, in, inlen,
-            "KEY_AES_128/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_128, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_128/MODE_CBC");
 
     /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
     /*crypto_block_cross(tc, pool, drivers, KEY_AES_128, MODE_ECB, 1, in, inlen, "KEY_AES_128/MODE_ECB");*/
@@ -576,7 +599,8 @@
 /**
  * Encrypt NSS, decrypt OpenSSL.
  */
-static void test_crypto_block_nss_openssl_pad(abts_case *tc, void *data) {
+static void test_crypto_block_nss_openssl_pad(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -587,14 +611,14 @@
     drivers[0] = get_nss_driver(tc, pool);
     drivers[1] = get_openssl_driver(tc, pool);
 
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 1, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
 
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 1, in, inlen,
-            "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_256/MODE_CBC");
 
     /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
     /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
@@ -616,7 +640,8 @@
 /**
  * Encrypt OpenSSL, decrypt NSS.
  */
-static void test_crypto_block_openssl_nss_pad(abts_case *tc, void *data) {
+static void test_crypto_block_openssl_nss_pad(abts_case *tc, void *data)
+{
     apr_pool_t *pool = NULL;
     const apr_crypto_driver_t *drivers[] = { NULL, NULL };
 
@@ -626,14 +651,14 @@
     apr_pool_create(&pool, NULL);
     drivers[0] = get_openssl_driver(tc, pool);
     drivers[1] = get_nss_driver(tc, pool);
-    crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_CBC, 1, in, inlen,
-            "KEY_3DES_192/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_3DES_192, APR_MODE_CBC, 1,
+            in, inlen, "KEY_3DES_192/MODE_CBC");
 
     /* KEY_3DES_192 / MODE_ECB doesn't work on NSS */
     /* crypto_block_cross(tc, pool, drivers, KEY_3DES_192, MODE_ECB, 1, in, inlen, "KEY_3DES_192/MODE_ECB"); */
 
-    crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_CBC, 1, in, inlen,
-            "KEY_AES_256/MODE_CBC");
+    crypto_block_cross(tc, pool, drivers, APR_KEY_AES_256, APR_MODE_CBC, 1, in,
+            inlen, "KEY_AES_256/MODE_CBC");
 
     /* KEY_AES_256 / MODE_ECB doesn't support padding on NSS */
     /*crypto_block_cross(tc, pool, drivers, KEY_AES_256, MODE_ECB, 1, in, inlen, "KEY_AES_256/MODE_ECB");*/
@@ -652,7 +677,160 @@
 
 }
 
-abts_suite *testcrypto(abts_suite *suite) {
+/**
+ * Get Types, OpenSSL.
+ */
+static void test_crypto_get_block_key_types_openssl(abts_case *tc, void *data)
+{
+    apr_pool_t *pool = NULL;
+    const apr_crypto_driver_t *driver;
+    apr_crypto_t *f;
+    apr_hash_t *types;
+    int *key_3des_192;
+    int *key_aes_128;
+    int *key_aes_192;
+    int *key_aes_256;
+
+    apr_pool_create(&pool, NULL);
+    driver = get_openssl_driver(tc, pool);
+    if (driver) {
+
+        f = make(tc, pool, driver);
+        apr_crypto_get_block_key_types(&types, f);
+
+        key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_3des_192);
+        ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192);
+
+        key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_128);
+        ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128);
+
+        key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_192);
+        ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192);
+
+        key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_256);
+        ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256);
+
+    }
+
+    apr_pool_destroy(pool);
+
+}
+
+/**
+ * Get Types, NSS.
+ */
+static void test_crypto_get_block_key_types_nss(abts_case *tc, void *data)
+{
+    apr_pool_t *pool = NULL;
+    const apr_crypto_driver_t *driver;
+    apr_crypto_t *f;
+    apr_hash_t *types;
+    int *key_3des_192;
+    int *key_aes_128;
+    int *key_aes_192;
+    int *key_aes_256;
+
+    apr_pool_create(&pool, NULL);
+    driver = get_nss_driver(tc, pool);
+    if (driver) {
+
+        f = make(tc, pool, driver);
+        apr_crypto_get_block_key_types(&types, f);
+
+        key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_3des_192);
+        ABTS_INT_EQUAL(tc, *key_3des_192, APR_KEY_3DES_192);
+
+        key_aes_128 = apr_hash_get(types, "aes128", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_128);
+        ABTS_INT_EQUAL(tc, *key_aes_128, APR_KEY_AES_128);
+
+        key_aes_192 = apr_hash_get(types, "aes192", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_192);
+        ABTS_INT_EQUAL(tc, *key_aes_192, APR_KEY_AES_192);
+
+        key_aes_256 = apr_hash_get(types, "aes256", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, key_aes_256);
+        ABTS_INT_EQUAL(tc, *key_aes_256, APR_KEY_AES_256);
+
+    }
+
+    apr_pool_destroy(pool);
+
+}
+
+/**
+ * Get Modes, OpenSSL.
+ */
+static void test_crypto_get_block_key_modes_openssl(abts_case *tc, void *data)
+{
+    apr_pool_t *pool = NULL;
+    const apr_crypto_driver_t *driver;
+    apr_crypto_t *f;
+    apr_hash_t *modes;
+    int *mode_ecb;
+    int *mode_cbc;
+
+    apr_pool_create(&pool, NULL);
+    driver = get_openssl_driver(tc, pool);
+    if (driver) {
+
+        f = make(tc, pool, driver);
+        apr_crypto_get_block_key_modes(&modes, f);
+
+        mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, mode_ecb);
+        ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB);
+
+        mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, mode_cbc);
+        ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC);
+
+    }
+
+    apr_pool_destroy(pool);
+
+}
+
+/**
+ * Get Modes, NSS.
+ */
+static void test_crypto_get_block_key_modes_nss(abts_case *tc, void *data)
+{
+    apr_pool_t *pool = NULL;
+    const apr_crypto_driver_t *driver;
+    apr_crypto_t *f;
+    apr_hash_t *modes;
+    int *mode_ecb;
+    int *mode_cbc;
+
+    apr_pool_create(&pool, NULL);
+    driver = get_nss_driver(tc, pool);
+    if (driver) {
+
+        f = make(tc, pool, driver);
+        apr_crypto_get_block_key_modes(&modes, f);
+
+        mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, mode_ecb);
+        ABTS_INT_EQUAL(tc, *mode_ecb, APR_MODE_ECB);
+
+        mode_cbc = apr_hash_get(modes, "cbc", APR_HASH_KEY_STRING);
+        ABTS_PTR_NOTNULL(tc, mode_cbc);
+        ABTS_INT_EQUAL(tc, *mode_cbc, APR_MODE_CBC);
+
+    }
+
+    apr_pool_destroy(pool);
+
+}
+
+abts_suite *testcrypto(abts_suite *suite)
+{
     suite = ADD_SUITE(suite);
 
     /* test simple init and shutdown */
@@ -682,6 +860,18 @@
     /* test padded encrypt openssl / decrypt nss */
     abts_run_test(suite, test_crypto_block_openssl_nss_pad, NULL);
 
+    /* test block key types openssl */
+    abts_run_test(suite, test_crypto_get_block_key_types_openssl, NULL);
+
+    /* test block key types nss */
+    abts_run_test(suite, test_crypto_get_block_key_types_nss, NULL);
+
+    /* test block key modes openssl */
+    abts_run_test(suite, test_crypto_get_block_key_modes_openssl, NULL);
+
+    /* test block key modes nss */
+    abts_run_test(suite, test_crypto_get_block_key_modes_nss, NULL);
+
     return suite;
 }
 
diff --git a/test/testldap.c b/test/testldap.c
index 7595a55..4f4fef9 100644
--- a/test/testldap.c
+++ b/test/testldap.c
@@ -80,7 +80,7 @@
 
     ldap_host[0] = '\0';
     rv = apr_file_open(&thefile, FILENAME, 
-                       APR_READ, 
+                       APR_FOPEN_READ,
                        APR_UREAD | APR_UWRITE | APR_GREAD, p);
     if (rv != APR_SUCCESS) {
         return 0;
diff --git a/test/testmemcache.c b/test/testmemcache.c
index bcdf02e..4947621 100644
--- a/test/testmemcache.c
+++ b/test/testmemcache.c
@@ -72,8 +72,8 @@
  * if you wanted to use some external hashing library or functions for
  * consistent hashing, for example, this would be a good place to do it.
  */
-apr_uint32_t my_hash_func(void *baton, const char *data,
-                          apr_size_t data_len)
+static apr_uint32_t my_hash_func(void *baton, const char *data,
+                                 apr_size_t data_len)
 {
 
   return HASH_FUNC_RESULT;
@@ -85,9 +85,9 @@
  * and pulls some number from the *baton, which is a struct that has some 
  * kind of meaningful stuff in it.
  */
-apr_memcache_server_t *my_server_func(void *baton, 
-                                      apr_memcache_t *mc,
-                                      const apr_uint32_t hash)
+static apr_memcache_server_t *my_server_func(void *baton, 
+                                             apr_memcache_t *mc,
+                                             const apr_uint32_t hash)
 {
   apr_memcache_server_t *ms = NULL;
   my_hash_server_baton *mhsb = (my_hash_server_baton *)baton;
@@ -106,7 +106,7 @@
 }
 
 apr_uint16_t firsttime = 0;
-int randval(apr_uint32_t high)
+static int randval(apr_uint32_t high)
 {
     apr_uint32_t i = 0;
     double d = 0;
@@ -177,7 +177,7 @@
 
 /* install our own custom hashing and server selection routines. */
 
-int create_test_hash(apr_pool_t *p, apr_hash_t *h)
+static int create_test_hash(apr_pool_t *p, apr_hash_t *h)
 {
   int i;
   
@@ -433,7 +433,6 @@
   rv = apr_memcache_add_server(memcache, server);
   ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);
   
-  values = apr_hash_make(p);
   tdata = apr_hash_make(p);
   
   create_test_hash(pool, tdata);
@@ -487,7 +486,7 @@
     apr_status_t rv;
     apr_memcache_t *memcache;
     apr_memcache_server_t *server;
-    apr_hash_t *tdata, *values;
+    apr_hash_t *tdata;
     apr_hash_index_t *hi;
     char *result;
     apr_size_t len;
@@ -502,7 +501,6 @@
     ABTS_ASSERT(tc, "server add failed", rv == APR_SUCCESS);
 
     tdata = apr_hash_make(pool);
-    values = apr_hash_make(pool);
 
     create_test_hash(pool, tdata);
 
@@ -539,7 +537,7 @@
 /* use apr_socket stuff to see if there is in fact a memcached server 
  * running on PORT. 
  */
-apr_status_t check_mc(void)
+static apr_status_t check_mc(void)
 {
   apr_pool_t *pool = p;
   apr_status_t rv;
diff --git a/test/testpass.c b/test/testpass.c
index 789f17c..0ec128b 100644
--- a/test/testpass.c
+++ b/test/testpass.c
@@ -28,6 +28,14 @@
 #include "abts.h"
 #include "testutil.h"
 
+#if defined(WIN32) || defined(BEOS) || defined(NETWARE)
+#define CRYPT_ALGO_SUPPORTED 0
+#else
+#define CRYPT_ALGO_SUPPORTED 1
+#endif
+
+#if CRYPT_ALGO_SUPPORTED
+
 static struct {
     const char *password;
     const char *hash;
@@ -104,6 +112,8 @@
 }
 #endif
 
+#endif /* CRYPT_ALGO_SUPPORTED */
+
 static void test_shapass(abts_case *tc, void *data)
 {
     const char *pass = "hellojed";
@@ -130,10 +140,12 @@
 {
     suite = ADD_SUITE(suite);
 
+#if CRYPT_ALGO_SUPPORTED
     abts_run_test(suite, test_crypt, NULL);
 #if APR_HAS_THREADS
     abts_run_test(suite, test_threadsafe, NULL);
 #endif
+#endif /* CRYPT_ALGO_SUPPORTED */
     abts_run_test(suite, test_shapass, NULL);
     abts_run_test(suite, test_md5pass, NULL);
     
diff --git a/test/testreslist.c b/test/testreslist.c
index aa24815..36333a1 100644
--- a/test/testreslist.c
+++ b/test/testreslist.c
@@ -142,7 +142,6 @@
 {
     apr_status_t rv;
     my_resource_t *resources[RESLIST_HMAX];
-    my_resource_t *res;
     void *vp;
     int i;
 
@@ -163,8 +162,6 @@
     rv = apr_reslist_acquire(rl, &vp);
     ABTS_TRUE(tc, APR_STATUS_IS_TIMEUP(rv));
 
-    res = vp;
-
     /* release the resources; otherwise the destroy operation
      * will blow
      */
diff --git a/test/testxml.c b/test/testxml.c
index 9a09644..eed1067 100644
--- a/test/testxml.c
+++ b/test/testxml.c
@@ -28,8 +28,8 @@
     apr_off_t off = 0L;
     char template[] = "data/testxmldummyerrorXXXXXX";
 
-    rv = apr_file_mktemp(fd, template, APR_CREATE | APR_TRUNCATE | APR_DELONCLOSE |
-                         APR_READ | APR_WRITE | APR_EXCL, p);
+    rv = apr_file_mktemp(fd, template, APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE | APR_FOPEN_DELONCLOSE |
+                         APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_EXCL, p);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
     if (rv != APR_SUCCESS)
@@ -62,8 +62,8 @@
     apr_off_t off = 0L;
     char template[] = "data/testxmldummyXXXXXX";
 
-    rv = apr_file_mktemp(fd, template, APR_CREATE | APR_TRUNCATE | APR_DELONCLOSE |
-                         APR_READ | APR_WRITE | APR_EXCL, p);
+    rv = apr_file_mktemp(fd, template, APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE | APR_FOPEN_DELONCLOSE |
+                         APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_EXCL, p);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
     if (rv != APR_SUCCESS)
@@ -159,18 +159,47 @@
                        APR_FOPEN_READ, 0, p);
     apr_assert_success(tc, "open billion-laughs.xml", rv);
 
-    rv = apr_xml_parse_file(p, &parser, &doc, fd, 2000);
-    ABTS_TRUE(tc, rv != APR_SUCCESS);
+    /* Don't test for return value; if it returns, chances are the bug
+     * is fixed or the machine has insane amounts of RAM. */
+    apr_xml_parse_file(p, &parser, &doc, fd, 2000);
 
     apr_file_close(fd);
 }
 
+static void test_CVE_2009_3720_alpha(abts_case *tc, void *data)
+{
+    apr_xml_parser *xp;
+    apr_xml_doc *doc;
+    apr_status_t rv;
+
+    xp = apr_xml_parser_create(p);
+    
+    rv = apr_xml_parser_feed(xp, "\0\r\n", 3);
+    if (rv == APR_SUCCESS)
+        apr_xml_parser_done(xp, &doc);
+}
+
+static void test_CVE_2009_3720_beta(abts_case *tc, void *data)
+{
+    apr_xml_parser *xp;
+    apr_xml_doc *doc;
+    apr_status_t rv;
+
+    xp = apr_xml_parser_create(p);
+    
+    rv = apr_xml_parser_feed(xp, "<?xml version\xc2\x85='1.0'?>\r\n", 25);
+    if (rv == APR_SUCCESS)
+        apr_xml_parser_done(xp, &doc);
+}
+
 abts_suite *testxml(abts_suite *suite)
 {
     suite = ADD_SUITE(suite);
 
     abts_run_test(suite, test_xml_parser, NULL);
     abts_run_test(suite, test_billion_laughs, NULL);
+    abts_run_test(suite, test_CVE_2009_3720_alpha, NULL);
+    abts_run_test(suite, test_CVE_2009_3720_beta, NULL);
 
     return suite;
 }
diff --git a/xml/NWGNUmakefile b/xml/NWGNUmakefile
index 5f85964..cc01646 100644
--- a/xml/NWGNUmakefile
+++ b/xml/NWGNUmakefile
@@ -3,14 +3,14 @@
 #
 
 SUBDIRS = \
-	$(EOLIST) 
+	$(EOLIST)
 
 #
 # Get the 'head' of the build environment.  This includes default targets and
 # paths to tools
 #
 
-include $(APR_WORK)\build\NWGNUhead.inc
+include $(APR_WORK)/build/NWGNUhead.inc
 
 #
 # build this level's files
@@ -26,17 +26,18 @@
 XINCDIRS	+= \
 			$(APR)/include \
 			$(APR)/include/arch/NetWare \
-			$(APRUTIL)/include \
-			$(APRUTIL)/uri \
-			$(APRUTIL)/dbm/sdbm \
-			$(APRUTIL)/include/private \
-			$(APRUTIL)/xml/expat/lib \
+			$(APU)/include \
+			$(APU)/uri \
+			$(APU)/dbm/sdbm \
+			$(APU)/include/private \
+			$(APUXML)/expat/lib \
 			$(EOLIST)
 
 #
 # These flags will come after CFLAGS
 #
 XCFLAGS		+= \
+			-DHAVE_EXPAT_CONFIG_H \
 			$(EOLIST)
 
 #
@@ -102,39 +103,39 @@
 # This is used by the link 'name' directive to name the nlm.  If left blank
 # TARGET_nlm (see below) will be used.
 #
-NLM_NAME		= 
+NLM_NAME	=
 
 #
-# This is used by the link '-desc ' directive. 
+# This is used by the link '-desc ' directive.
 # If left blank, NLM_NAME will be used.
 #
-NLM_DESCRIPTION	= 
+NLM_DESCRIPTION	=
 
 #
 # This is used by the '-threadname' directive.  If left blank,
 # NLM_NAME Thread will be used.
 #
-NLM_THREAD_NAME	= 
+NLM_THREAD_NAME	=
 #
-# If this is specified, it will override VERSION value in 
-# $(APR_WORK)\build\NWGNUenvironment.inc
+# If this is specified, it will override VERSION value in
+# $(APR_WORK)/build/NWGNUenvironment.inc
 #
-NLM_VERSION		=
+NLM_VERSION	=
 
 #
 # If this is specified, it will override the default of 64K
 #
-NLM_STACK_SIZE	= 
+NLM_STACK_SIZE	=
 
 #
 # If this is specified it will be used by the link '-entry' directive
 #
-NLM_ENTRY_SYM	= 
+NLM_ENTRY_SYM	=
 
 #
 # If this is specified it will be used by the link '-exit' directive
 #
-NLM_EXIT_SYM	= 
+NLM_EXIT_SYM	=
 
 #
 # If this is specified it will be used by the link '-check' directive
@@ -144,14 +145,14 @@
 #
 # If this is specified it will be used by the link '-flags' directive
 #
-NLM_FLAGS		=
- 
+NLM_FLAGS	=
+
 #
-# If this is specified it will be linked in with the XDCData option in the def 
-# file instead of the default of $(APR)/misc/netware/apache.xdc.  XDCData can 
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(APR)/misc/netware/apache.xdc.  XDCData can
 # be disabled by setting APACHE_UNIPROC in the environment
 #
-XDCDATA         = 
+XDCDATA		=
 
 #
 # Declare all target files (you must add your files here)
@@ -167,7 +168,7 @@
 # If there is an LIB target, put it here
 #
 TARGET_lib = \
-	$(OBJDIR)/xmllib.lib \
+	$(OBJDIR)/apuxml.lib \
 	$(EOLIST)
 
 #
@@ -195,7 +196,7 @@
 # If the nlm has a msg file, put it's path here
 #
 FILE_nlm_msg =
- 
+
 #
 # If the nlm has a hlp file put it's path here
 #
@@ -211,14 +212,14 @@
 #
 FILES_nlm_Ximports = \
 	$(EOLIST)
- 
-#   
+
+#
 # Any symbols exported to here
 #
 FILES_nlm_exports = \
 	$(EOLIST)
-	
-#   
+
+#
 # These are the OBJ files needed to create the LIB target above.
 # Paths must all use the '/' character
 #
@@ -238,8 +239,8 @@
 nlms :: libs $(TARGET_nlm)
 
 #
-# Updated this target to create necessary directories and copy files to the 
-# correct place.  (See $(APR_WORK)\build\NWGNUhead.inc for examples)
+# Updated this target to create necessary directories and copy files to the
+# correct place.  (See $(APR_WORK)/build/NWGNUhead.inc for examples)
 #
 install :: nlms FORCE
 
@@ -254,5 +255,5 @@
 # in this makefile
 #
 
-include $(APR_WORK)\build\NWGNUtail.inc
+include $(APRBUILD)/NWGNUtail.inc
 
diff --git a/xml/expat/COPYING b/xml/expat/COPYING
index fc97b02..e3ad54e 100644
--- a/xml/expat/COPYING
+++ b/xml/expat/COPYING
@@ -1,5 +1,6 @@
 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
                                and Clark Cooper
+Copyright (c) 2001, 2002 Expat maintainers.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/xml/expat/Makefile.in b/xml/expat/Makefile.in
index bbf0a9f..eafb1e4 100644
--- a/xml/expat/Makefile.in
+++ b/xml/expat/Makefile.in
@@ -17,140 +17,99 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN EXPAT.
 #
-#  ---
-#  I started using automake, but
-#		1) it seemed like overkill
-#		2) I don't want all the GNU policies
-#		3) I wanted more explicit control over what gets built
-#
-#  So I'm doing my Makefile.in files manually. But a fair part is based
-#  on what I learned from perusing the Makefile.in's generated by automake,
-#  and the automake authors still get my kudos.
-#
 
 SHELL = @SHELL@
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
+
 prefix = @prefix@
 exec_prefix = @exec_prefix@
 
 bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
 libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
 includedir = @includedir@
-oldincludedir = /usr/include
+mandir = ${prefix}/man/man1
 
 top_builddir = .
 
 
-AUTOCONF = autoconf
-
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
+mkinstalldirs = $(SHELL) $(top_srcdir)/conftools/mkinstalldirs
 
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-host_alias = @host_alias@
-host_triplet = @host@
+MANFILE = $(srcdir)/doc/xmlwf.1
+APIHEADER = $(srcdir)/lib/expat.h
+LIBRARY = libexpat.la
 
 CC = @CC@
-
 LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-PACKAGE = @PACKAGE@
-RANLIB = @RANLIB@
-VERSION = @VERSION@
 
-SUBDIRS = lib
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-CONFIG_HEADERS = config.h
+INCLUDES = -I$(srcdir)/lib -I.
+LDFLAGS = @LDFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CFLAGS = @CFLAGS@ -DHAVE_EXPAT_CONFIG_H
+VSNFLAG = -version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@
 
-DISTDIR = $(PACKAGE)-$(VERSION)
-DISTRIBUTION = $(DISTDIR).tar.gz
+### autoconf this?
+LTFLAGS = --silent
 
-all: build-subdirs
+COMPILE = $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $(INCLUDES)
+LTCOMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(COMPILE)
+LINK_LIB = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) -no-undefined $(VSNFLAG) -rpath $(libdir) $(LDFLAGS) -o $@
+LINK_EXE = $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) $(LDFLAGS) -o $@
 
-.PHONY: all build-subdirs clean distclean extraclean maintainer-clean dist install \
-        uninstall distdir
+LIB_OBJS = lib/xmlparse.lo lib/xmltok.lo lib/xmlrole.lo
 
-Makefile: Makefile.in config.status
-	CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) config.status
-
-config.status: configure
-	@if test -f $@; then \
-		$(SHELL) config.status --recheck ; \
-	else \
-		$(SHELL) configure ; \
-	fi
-
-configure: configure.in
-	$(AUTOCONF)
-
-config.h: config.h.in config.status
-	CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADERS) \
-	$(SHELL) ./config.status
-
-build-subdirs:
-	@list='$(SUBDIRS)'; \
-	for dir in $$list; do \
-	  cd $$dir; $(MAKE); cd ..; \
-	done
+all: $(LIBRARY)
 
 clean:
-	@list='$(SUBDIRS)'; for dir in $$list; do \
-	  cd $$dir; $(MAKE) clean; cd ..; \
-	done
-	rm -f core *~
+	cd lib && rm -f $(LIBRARY) *.o *.lo && rm -rf .libs _libs
+	rm -rf .libs libexpat.la
 
-distclean:
-	@list='$(SUBDIRS)'; for dir in $$list; do \
-	  cd $$dir; $(MAKE) distclean; cd ..; \
-	done
-	rm -f config.h config.status config.log libtool examples/Makefile xmlwf/Makefile Makefile
+clobber: clean
+
+distclean: clean
+	rm -f expat_config.h config.status config.log config.cache libtool
+	rm -f Makefile
 
 extraclean: distclean
-	rm -f configure aclocal.m4
+	rm -f expat_config.h.in configure
+	rm -f conftools/aclocal.m4 conftools/ltconfig conftools/ltmain.sh
+	rm -f conftools/argz.m4 conftools/libtool.m4 conftools/ltoptions.m4
+	rm -f conftools/ltsugar.m4 conftools/ltversion.m4 conftools/lt~obsolete.m4
 
-maintainer-clean: distclean
-	rm -f $(DISTRIBUTION)
-	rm -rf $(DISTDIR)
+check: tests/runtests
+	tests/runtests
 
-distdir: MANIFEST
-	test -d $(DISTDIR) && rm -rf $(DISTDIR); \
-	mkdir $(DISTDIR); \
-	flist=`sed -e "s/[ 	]:.*$$//" MANIFEST`; for file in $$flist; do \
-	  cp -P $$file $(DISTDIR); \
-	done
+install: installlib
 
-$(DISTRIBUTION): distdir
-	tar cfz $(DISTRIBUTION) $(DISTDIR)	
+installlib: $(LIBRARY) $(APIHEADER)
+	$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+	$(LIBTOOL)  --mode=install $(INSTALL) $(LIBRARY) $(DESTDIR)$(libdir)/$(LIBRARY)
+	$(INSTALL_DATA) $(APIHEADER) $(DESTDIR)$(includedir)
 
-dist: $(DISTRIBUTION)
+$(LIBRARY): $(LIB_OBJS)
+	$(LINK_LIB) $(LIB_OBJS)
 
-install:
-	@list='$(SUBDIRS)'; for dir in $$list; do \
-	  cd $$dir; $(MAKE) install; cd ..; \
-	done
+lib/xmlparse.lo: lib/xmlparse.c lib/expat.h lib/xmlrole.h lib/xmltok.h \
+	$(top_builddir)/expat_config.h lib/internal.h
 
-uninstall:
-	@list='$(SUBDIRS)'; for dir in $$list; do \
-	  cd $$dir; $(MAKE) uninstall; cd ..; \
-	done
+lib/xmltok.lo: lib/xmltok.c lib/xmltok_impl.c lib/xmltok_ns.c \
+	lib/ascii.h lib/asciitab.h lib/iasciitab.h lib/latin1tab.h \
+	lib/nametab.h lib/utf8tab.h lib/xmltok.h lib/xmltok_impl.h \
+	$(top_builddir)/expat_config.h
 
-depend:
-	echo SOMEONE SHOULD MAKE THIS DO SOMETHING!!!
+.SUFFIXES: .c .lo .o
+
+.c.o:
+	$(COMPILE) -o $@ -c $<
+.c.lo:
+	$(LTCOMPILE) -o $@ -c $<
+
+.PHONY: buildlib all \
+	clean distclean extraclean maintainer-clean \
+	dist distdir \
+	install uninstall
diff --git a/xml/expat/README b/xml/expat/README
index 15bcdcc..d391c7e 100644
--- a/xml/expat/README
+++ b/xml/expat/README
@@ -1,7 +1,7 @@
 
-			Expat, Release 1.95.2
+                        Expat, Release 1.95.7
 
-This is expat, a C library for parsing XML, written by James Clark.
+This is Expat, a C library for parsing XML, written by James Clark.
 Expat is a stream-oriented XML parser.  This means that you register
 handlers with the parser before starting the parse.  These handlers
 are called when the parser discovers the associated structures in the
@@ -17,15 +17,26 @@
 with this package.  This license is the same as the MIT/X Consortium
 license.
 
-Versions of expat that have an odd minor version (the middle number in
+Versions of Expat that have an odd minor version (the middle number in
 the release above), are development releases and should be considered
 as beta software.  Releases with even minor version numbers are
 intended to be production grade software.
 
-To build expat, you first run the configuration shell script in the
-top level distribution directory:
+If you are building Expat from a check-out from the CVS repository,
+you need to run a script that generates the configure script using the
+GNU autoconf and libtool tools.  To do this, you need to have
+autoconf 2.52 or newer and libtool 1.4 or newer.  Run the script like
+this:
 
-	./configure
+        ./buildconf.sh
+
+Once this has been done, follow the same instructions as for building
+from a source distribution.
+
+To build Expat from a source distribution, you first run the
+configuration shell script in the top level distribution directory:
+
+        ./configure
 
 There are many options which you may provide to configure (which you
 can discover by running configure with the --help option).  But the
@@ -36,19 +47,41 @@
 into /home/me/mystuff/lib, /home/me/mystuff/include, and
 /home/me/mystuff/bin, you can tell configure about that with:
 
-	./configure --prefix=/home/me/mystuff
+        ./configure --prefix=/home/me/mystuff
 
 After running the configure script, the "make" command will build
 things and "make install" will install things into their proper
 location.  Note that you need to have write permission into the
 directories into which things will be installed.
 
-When building for use with C++, you may need to add additional
-compiler flags to support proper interaction with exceptions.  This
-can be done by setting the CFLAGS environment variable.  For example,
-when using GCC, you can use:
+If you are interested in building Expat to provide document
+information in UTF-16 rather than the default UTF-8, following these
+instructions:
 
-	CFLAGS=-fexceptions ./configure
+        1. For UTF-16 output as unsigned short (and version/error
+           strings as char), run:
+
+               ./configure CPPFLAGS=-DXML_UNICODE
+
+           For UTF-16 output as wchar_t (incl. version/error strings),
+           run:
+
+               ./configure CFLAGS="-g -O2 -fshort-wchar" \
+                           CPPFLAGS=-DXML_UNICODE_WCHAR_T
+
+        2. Edit the MakeFile, changing:
+
+               LIBRARY = libexpat.la
+
+           to:
+
+               LIBRARY = libexpatw.la
+
+           (Note the additional "w" in the library name.)
+
+        3. Run "make buildlib" (which builds the library only).
+
+        4. Run "make installlib" (which installs the library only).
 
 Note for Solaris users:  The "ar" command is usually located in
 "/usr/ccs/bin", which is not in the default PATH.  You will need to
@@ -57,16 +90,30 @@
 properly -- appearantly it does not understand .PHONY directives).  If
 you're using ksh or bash, use this command to build:
 
-	PATH=/usr/ccs/bin:$PATH make
+        PATH=/usr/ccs/bin:$PATH make
+
+The unit and regression tests for Expat require the "check" library on
+Unix; more information is available at http://check.sourceforge.net/,
+and downloadable packages are available from the library's project
+page on SourceForge: http://sourceforge.net/projects/check/.  You do
+not need to install the check library to build and use Expat, only to
+build and run Expat's test suite.
+
+When using Expat with a project using autoconf for configuration, you
+can use the probing macro in conftools/expat.m4 to determine how to
+include Expat.  See the comments at the top of that file for more
+information.
 
 A reference manual is available in the file doc/reference.html in this
 distribution.
 
-The homepage for this project is http://expat.sourceforge.net/.  There
+The homepage for this project is http://www.libexpat.org/.  There
 are links there to connect you to the bug reports page.  If you need
 to report a bug when you don't have access to a browser, you may also
-send a bug report by email to expat-bugs@lists.sourceforge.net.
+send a bug report by email to expat-bugs@mail.libexpat.org.
 
 Discussion related to the direction of future expat development takes
-place on expat-discuss@lists.sourceforge.net.  Archives of this list
-may be found at http://www.geocrawler.com/redir-sf.php3?list=expat-discuss.
+place on expat-discuss@mail.libexpat.org.  Archives of this list and
+other Expat-related lists may be found at:
+
+        http://mail.libexpat.org/mailman-21/listinfo/
diff --git a/xml/expat/acconfig.h b/xml/expat/acconfig.h
deleted file mode 100644
index 1283ad6..0000000
--- a/xml/expat/acconfig.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This file is used by autoheader to add items to expat_config.h.in */
-
-#ifdef WORDS_BIGENDIAN
-#define XML_BYTE_ORDER 21
-#else
-#define XML_BYTE_ORDER 12
-#endif
-
-@BOTTOM@
-
-#define XML_NS
-#define XML_DTD
-
-#define XML_CONTEXT_BYTES 1024
-
-#ifndef HAVE_MEMMOVE
-#ifdef HAVE_BCOPY
-#define memmove(d,s,l) bcopy((s),(d),(l))
-#else
-#define memmove(d,s,l) ;punting on memmove;
-#endif
-
-#endif
diff --git a/xml/expat/buildconf.sh b/xml/expat/buildconf.sh
index 63cdbf1..817dd59 100755
--- a/xml/expat/buildconf.sh
+++ b/xml/expat/buildconf.sh
@@ -1,53 +1,90 @@
-#! /bin/sh
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+# 
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
 
-#
-# Find libtoolize. Prefer 1.x versions.
-#
-libtoolize=`conftools/PrintPath glibtoolize1 glibtoolize libtoolize libtoolize15 libtoolize14`
+# buildconf: Build the support scripts needed to compile from a
+#            checked-out version of the source code.
+
+if [ "$1" = "--verbose" -o "$1" = "-v" ]; then
+    verbose="--verbose"
+    shift
+fi
+
+libtoolize=`conftools/PrintPath glibtoolize1 glibtoolize libtoolize15 libtoolize14 libtoolize`
 if [ "x$libtoolize" = "x" ]; then
     echo "libtoolize not found in path"
     exit 1
 fi
 
-#
 # Create the libtool helper files
 #
-# Note: we copy (rather than link) the files.
+# Note: we copy (rather than link) them to simplify distribution.
+# Note: APR supplies its own config.guess and config.sub -- we do not
+#       rely on libtool's versions
 #
-# Note: This bundled version of expat will not always replace the
-# files since we have a special config.guess/config.sub that we
-# want to ensure is used.
-echo "Copying libtool helper files ..."
+echo "Copying libtool helper files using $libtoolize"
 
-# Remove any m4 cache and libtool files so one can switch between 
-# autoconf and libtool versions by simply rerunning the buildconf script.
-#
-(cd conftools ; rm -f ltconfig ltmain.sh)
-rm -rf aclocal.m4 libtool.m4 ltsugar.m4 autom4te*.cache
+# Remove any libtool files so one can switch between libtool versions
+# by simply rerunning the buildconf script.
+rm -rf autom4te*.cache aclocal.m4
+m4files='argz.m4 libtool.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4'
+(cd conftools ; rm -f ltconfig ltmain.sh aclocal.m4 $m4files)
 
-$libtoolize --copy --automake
+# Determine libtool version, because --copy behaves differently
+# w.r.t. copying libtool.m4
+lt_pversion=`$libtoolize --version 2>/dev/null|sed -e 's/([^)]*)//g;s/^[^0-9]*//;s/[- ].*//g;q'`
+lt_version=`echo $lt_pversion|sed -e 's/\([a-z]*\)$/.\1/'`
+IFS=.; set $lt_version; IFS=' '
 
-#
-# Build aclocal.m4 from libtool's libtool.m4
-#
-if [ -f libtool.m4 ]; then
-  ltfile=libtool.m4
-else
-  ltpath=`dirname $libtoolize`
-  ltfile=${LIBTOOL_M4-`cd $ltpath/../share/aclocal ; pwd`/libtool.m4}
+# libtool 1
+if test "$1" = "1"; then
+  $libtoolize --copy --automake
+  # Unlikely, maybe for old versions the file exists
+  if [ -f libtool.m4 ]; then 
+    ltfile=`pwd`/libtool.m4
+  else
+
+    # Extract all lines setting variables from libtoolize up until
+    # libtool_m4 gets set
+    ltfindcmd="`sed -n \"/=[^\\\`]/p;/libtool_m4=/{s/.*=/echo /p;q;}\" \
+                   < $libtoolize`"
+
+    # Get path to libtool.m4 either from LIBTOOL_M4 env var or our libtoolize based script
+    ltfile=${LIBTOOL_M4-`eval "$ltfindcmd"`}
+
+    # Expecting the code above to be very portable, but just in case...
+    if [ -z "$ltfile" -o ! -f "$ltfile" ]; then
+      ltpath=`dirname $libtoolize`
+      ltfile=`cd $ltpath/../share/aclocal ; pwd`/libtool.m4
+    fi
+  fi
+  if [ ! -f $ltfile ]; then
+    echo "$ltfile not found"
+    exit 1
+  fi
+  # Do we need this anymore?
+  echo "Using libtool.m4 at ${ltfile}."
+  rm -f conftools/libtool.m4
+  cp -p $ltfile conftools/libtool.m4
+
+# libtool 2
+elif test "$1" = "2"; then
+  $libtoolize --copy --quiet $verbose
 fi
-echo "Incorporating $ltfile into aclocal.m4 ..."
-echo "dnl THIS FILE IS AUTOMATICALLY GENERATED BY buildconf.sh" > aclocal.m4
-echo "dnl edits here will be lost" >> aclocal.m4
-cat $ltfile >> aclocal.m4
-
-if [ -f ltsugar.m4 ]; then
-  echo "Incorporating ltsugar.m4 into aclocal.m4 ..."
-  cat ltsugar.m4 >> aclocal.m4
-fi
-
-# Clean up again
-rm -f libtool.m4 ltsugar.m4
 
 cross_compile_warning="warning: AC_TRY_RUN called without default to allow cross compiling"
 
@@ -55,13 +92,13 @@
 # Generate the autoconf header template (config.h.in) and ./configure
 #
 echo "Creating config.h.in ..."
-${AUTOHEADER:-autoheader} 2>&1 | grep -v "$cross_compile_warning"
+${AUTOHEADER:-autoheader} $verbose 2>&1 | grep -v "$cross_compile_warning"
 
 echo "Creating configure ..."
 ### do some work to toss config.cache?
-${AUTOCONF:-autoconf} 2>&1 | grep -v "$cross_compile_warning"
+${AUTOCONF:-autoconf} $verbose 2>&1 | grep -v "$cross_compile_warning"
 
-# Remove autoconf caches
-rm -rf autom4te*.cache
+# Clean up any leftovers and autoconf caches
+rm -rf autom4te*.cache aclocal.m4 libtool.m4
 
 exit 0
diff --git a/xml/expat/configure.in b/xml/expat/configure.in
index 04cbf08..3d5bf66 100644
--- a/xml/expat/configure.in
+++ b/xml/expat/configure.in
@@ -10,23 +10,16 @@
 dnl   in the file COPYING that comes with this distribution.
 dnl
 
-AC_INIT(Makefile.in)
+dnl Ensure that Expat is configured with autoconf 2.52 or newer
+AC_PREREQ(2.52)
+
+
+dnl ### apr-util hack: just hard-code the version here, as is done in expat.h.
+AC_INIT(expat, 1.95.7, expat-bugs@mail.libexpat.org)
+
+AC_CONFIG_SRCDIR(Makefile.in)
 AC_CONFIG_AUX_DIR(conftools)
-
-dnl
-dnl Follow the GNU/Linux convention of odd number minor version for
-dnl beta/development releases and even number minor version for stable
-dnl releases. Edit is bumped with each release and set to 0 with
-dnl change to major or minor version.
-dnl
-
-EXPAT_MAJOR_VERSION=1
-EXPAT_MINOR_VERSION=95
-EXPAT_EDIT=2
-
-EXPAT_VERSION=$EXPAT_MAJOR_VERSION.$EXPAT_MINOR_VERSION.$EXPAT_EDIT
-VERSION=$EXPAT_VERSION
-PACKAGE=expat
+AC_CONFIG_MACRO_DIR(conftools)
 
 dnl
 dnl Increment LIBREVISION if source code has changed at all
@@ -39,13 +32,25 @@
 dnl If the API changes incompatibly set LIBAGE back to 0
 dnl
 
-LIBCURRENT=1
+LIBCURRENT=5
 LIBREVISION=0
-LIBAGE=1
+LIBAGE=5
 
-AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADER(expat_config.h)
+
+dnl
+dnl Include our own M4 macros along with those for libtool
+dnl
+sinclude(conftools/ac_c_bigendian_cross.m4)
+sinclude(conftools/libtool.m4)
+sinclude(conftools/ltsugar.m4)
+sinclude(conftools/argz.m4)
+sinclude(conftools/ltoptions.m4)
+sinclude(conftools/ltversion.m4)
+sinclude(conftools/lt~obsolete.m4)
 
 AC_CANONICAL_SYSTEM
+
 case "$host_os" in
 *os2*)
     # Use a custom made libtool replacement
@@ -53,20 +58,11 @@
     LIBTOOL="$srcdir/../../../apr/build/aplibtool"
     ;;
 *)
-    AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
     ;;
 esac
 
-blddir=`pwd`
-AC_SUBST(blddir)
-
-AC_SUBST(PACKAGE)
-AC_SUBST(VERSION)
-AC_SUBST(EXPAT_MAJOR_VERSION)
-AC_SUBST(EXPAT_MINOR_VERSION)
-AC_SUBST(EXPAT_EDIT)
-
 AC_SUBST(LIBCURRENT)
 AC_SUBST(LIBREVISION)
 AC_SUBST(LIBAGE)
@@ -75,11 +71,8 @@
 AC_PROG_CC
 AC_PROG_INSTALL
 
-dnl Checks for libraries.
-
 dnl Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h unistd.h string.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 dnl check for endianness
@@ -90,20 +83,26 @@
                 [byte order is unknown due to cross-compilation])
 fi
 AC_C_CONST
-AC_TYPE_OFF_T
 AC_TYPE_SIZE_T
-
-dnl Checks for library functions.
-
-AC_FUNC_MEMCMP
-AC_FUNC_MMAP
-AC_SUBST(FILEMAP_OBJ)
-if test -z "$HAVE_MMAP"; then
-FILEMAP_OBJ=unixfilemap.o
-else
-FILEMAP_OBJ=readfilemap.o
-fi
-
 AC_CHECK_FUNCS(memmove bcopy)
 
-AC_OUTPUT(Makefile lib/Makefile lib/expat.h)
+dnl Only needed for regression tests:
+AC_CHECK_HEADERS(check.h)
+
+dnl Some basic configuration:
+AC_DEFINE([XML_NS], 1,
+          [Define to make XML Namespaces functionality available.])
+AC_DEFINE([XML_DTD], 1,
+          [Define to make parameter entity parsing functionality available.])
+AC_DEFINE([XML_CONTEXT_BYTES], 1024,
+          [Define to specify how much context to retain around the current parse point.])
+
+AC_CONFIG_FILES(Makefile)
+AC_OUTPUT
+
+abs_srcdir="`cd $srcdir && pwd`"
+abs_builddir="`pwd`"
+if test "$abs_srcdir" != "$abs_builddir"; then
+  mkdir lib
+fi
+
diff --git a/xml/expat/conftools/PrintPath b/xml/expat/conftools/PrintPath
index 68435f3..2a2b48b 100755
--- a/xml/expat/conftools/PrintPath
+++ b/xml/expat/conftools/PrintPath
@@ -1,4 +1,21 @@
 #!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
 # Look for program[s] somewhere in $PATH.
 #
 # Options:
@@ -12,9 +29,6 @@
 #
 # Initially written by Jim Jagielski for the Apache configuration mechanism
 #  (with kudos to Kernighan/Pike)
-#
-# This script falls under the Apache License.
-# See http://www.apache.org/docs/LICENSE
 
 ##
 # Some "constants"
@@ -45,7 +59,7 @@
 #
 # First of all, all OS/2 programs have the '.exe' extension.
 # Next, we adjust PATH (or what was given to us as PATH) to
-# be whitespace seperated directories.
+# be whitespace separated directories.
 # Finally, we try to determine the best flag to use for
 # test/[] to look for an executable file. OS/2 just has '-r'
 # but with other OSs, we do some funny stuff to check to see
diff --git a/xml/expat/conftools/ac_c_bigendian_cross.m4 b/xml/expat/conftools/ac_c_bigendian_cross.m4
new file mode 100644
index 0000000..8ed3edb
--- /dev/null
+++ b/xml/expat/conftools/ac_c_bigendian_cross.m4
@@ -0,0 +1,81 @@
+dnl @synopsis AC_C_BIGENDIAN_CROSS
+dnl
+dnl Check endianess even when crosscompiling
+dnl (partially based on the original AC_C_BIGENDIAN).
+dnl
+dnl The implementation will create a binary, and instead of running
+dnl the binary it will be grep'ed for some symbols that will look
+dnl different for different endianess of the binary.
+dnl
+dnl @version $Id: ac_c_bigendian_cross.m4,v 1.2 2001/10/01 20:03:13 fdrake Exp $
+dnl @author Guido Draheim <guidod@gmx.de>
+dnl
+AC_DEFUN([AC_C_BIGENDIAN_CROSS],
+[AC_CACHE_CHECK(whether byte ordering is bigendian, ac_cv_c_bigendian,
+[ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif], [# It does; now see whether it defined to BIG_ENDIAN or not.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif], ac_cv_c_bigendian=yes, ac_cv_c_bigendian=no)])
+if test $ac_cv_c_bigendian = unknown; then
+AC_TRY_RUN([main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}], ac_cv_c_bigendian=no, ac_cv_c_bigendian=yes,
+[ echo $ac_n "cross-compiling... " 2>&AC_FD_MSG ])
+fi])
+if test $ac_cv_c_bigendian = unknown; then
+AC_MSG_CHECKING(to probe for byte ordering)
+[
+cat >conftest.c <<EOF
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
+int main() { _ascii (); _ebcdic (); return 0; }
+EOF
+] if test -f conftest.c ; then
+     if ${CC-cc} -c conftest.c -o conftest.o && test -f conftest.o ; then
+        if test `grep -l BIGenDianSyS conftest.o` ; then
+           echo $ac_n ' big endian probe OK, ' 1>&AC_FD_MSG
+           ac_cv_c_bigendian=yes
+        fi
+        if test `grep -l LiTTleEnDian conftest.o` ; then
+           echo $ac_n ' little endian probe OK, ' 1>&AC_FD_MSG
+           if test $ac_cv_c_bigendian = yes ; then
+            ac_cv_c_bigendian=unknown;
+           else
+            ac_cv_c_bigendian=no
+           fi
+        fi
+        echo $ac_n 'guessing bigendian ...  ' >&AC_FD_MSG
+     fi
+  fi
+AC_MSG_RESULT($ac_cv_c_bigendian)
+fi
+if test $ac_cv_c_bigendian = yes; then
+  AC_DEFINE(WORDS_BIGENDIAN, 1, [whether byteorder is bigendian])
+  BYTEORDER=4321
+else
+  BYTEORDER=1234
+fi
+AC_DEFINE_UNQUOTED(BYTEORDER, $BYTEORDER, [1234 = LIL_ENDIAN, 4321 = BIGENDIAN])
+if test $ac_cv_c_bigendian = unknown; then
+  AC_MSG_ERROR(unknown endianess - sorry, please pre-set ac_cv_c_bigendian)
+fi
+])
diff --git a/xml/expat/conftools/config.guess b/xml/expat/conftools/config.guess
index 6cfac28..40eaed4 100755
--- a/xml/expat/conftools/config.guess
+++ b/xml/expat/conftools/config.guess
@@ -1,9 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2002-03-20'
+timestamp='2011-05-11'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -17,28 +18,25 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-#####################################################################
-# This file contains changes for Apache, clearly marked below.
-# These changes are hereby donated to the public domain.
-#####################################################################
 
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
 #
 # This script attempts to guess a canonical system name similar to
 # config.sub.  If it succeeds, it prints the system name on stdout, and
 # exits with 0.  Otherwise, it exits with 1.
 #
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -58,8 +56,9 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -71,11 +70,11 @@
 while test $# -gt 0 ; do
   case $1 in
     --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit 0 ;;
+       echo "$timestamp" ; exit ;;
     --version | -v )
-       echo "$version" ; exit 0 ;;
+       echo "$version" ; exit ;;
     --help | --h* | -h )
-       echo "$usage"; exit 0 ;;
+       echo "$usage"; exit ;;
     -- )     # Stop option processing
        shift; break ;;
     - )	# Use stdin as input.
@@ -93,30 +92,42 @@
   exit 1
 fi
 
+trap 'exit 1' 1 2 15
 
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
 
-# CC_FOR_BUILD -- compiler used by this script.
 # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
 # use `HOST_CC' if defined, but it is deprecated.
 
-set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int dummy(){}" > $dummy.c ;
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
 	for c in cc gcc c89 c99 ; do
-	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
-	  if test $? = 0 ; then
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
 	     CC_FOR_BUILD="$c"; break ;
 	  fi ;
 	done ;
-	rm -f $dummy.c $dummy.o $dummy.rel ;
 	if test x"$CC_FOR_BUILD" = x ; then
 	  CC_FOR_BUILD=no_compiler_found ;
 	fi
 	;;
  ,,*)   CC_FOR_BUILD=$CC ;;
  ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac'
+esac ; set_cc_for_build= ;'
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi@noc.rutgers.edu 1994-08-24)
@@ -147,9 +158,11 @@
 	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
 	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
@@ -158,7 +171,7 @@
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep __ELF__ >/dev/null
+			| grep -q __ELF__
 		then
 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 		    # Return netbsd for either.  FIX?
@@ -168,163 +181,135 @@
 		fi
 		;;
 	    *)
-	        os=netbsd
+		os=netbsd
 		;;
 	esac
 	# The OS release
-	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	echo "${machine}-${os}${release}"
-	exit 0 ;;
-    amiga:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    arc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    hp300:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mac68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    macppc:OpenBSD:*:*)
-	echo powerpc-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme68k:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvme88k:OpenBSD:*:*)
-	echo m88k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    mvmeppc:OpenBSD:*:*)
-	echo powerpc-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    pmax:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    sgi:OpenBSD:*:*)
-	echo mipseb-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    sun3:OpenBSD:*:*)
-	echo m68k-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
-    wgrisc:OpenBSD:*:*)
-	echo mipsel-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:OpenBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
-	exit 0 ;;
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
     alpha:OSF1:*:*)
-	if test $UNAME_RELEASE = "V4.0"; then
+	case $UNAME_RELEASE in
+	*4.0)
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-	fi
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	cat <<EOF >$dummy.s
-	.data
-\$Lformat:
-	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
-
-	.text
-	.globl main
-	.align 4
-	.ent main
-main:
-	.frame \$30,16,\$26,0
-	ldgp \$29,0(\$27)
-	.prologue 1
-	.long 0x47e03d80 # implver \$0
-	lda \$2,-1
-	.long 0x47e20c21 # amask \$2,\$1
-	lda \$16,\$Lformat
-	mov \$0,\$17
-	not \$1,\$18
-	jsr \$26,printf
-	ldgp \$29,0(\$26)
-	mov 0,\$16
-	jsr \$26,exit
-	.end main
-EOF
-	eval $set_cc_for_build
-	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-	if test "$?" = 0 ; then
-		case `./$dummy` in
-			0-0)
-				UNAME_MACHINE="alpha"
-				;;
-			1-0)
-				UNAME_MACHINE="alphaev5"
-				;;
-			1-1)
-				UNAME_MACHINE="alphaev56"
-				;;
-			1-101)
-				UNAME_MACHINE="alphapca56"
-				;;
-			2-303)
-				UNAME_MACHINE="alphaev6"
-				;;
-			2-307)
-				UNAME_MACHINE="alphaev67"
-				;;
-			2-1307)
-				UNAME_MACHINE="alphaev68"
-				;;
-		esac
-	fi
-	rm -f $dummy.s $dummy
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	exit 0 ;;
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
     Alpha\ *:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# Should we change UNAME_MACHINE based on the output of uname instead
 	# of the specific Alpha model?
 	echo alpha-pc-interix
-	exit 0 ;;
+	exit ;;
     21064:Windows_NT:50:3)
 	echo alpha-dec-winnt3.5
-	exit 0 ;;
+	exit ;;
     Amiga*:UNIX_System_V:4.0:*)
 	echo m68k-unknown-sysv4
-	exit 0;;
+	exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-amigaos
-	exit 0 ;;
+	exit ;;
     *:[Mm]orph[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-morphos
-	exit 0 ;;
-#########################
-# Apache changes
-#
-#   *:OS/390:*:*)
-#      echo i370-ibm-openedition
-#      exit 0 ;;
-    *:OS390:*:* | *:OS/390:*:*)
-       echo s390-ibm-os390
-       exit 0 ;; 
-    *:OS400:*:* | *:OS/400:*:*) 
-       echo as400-ibm-os400
-       exit 0 ;;
-    *:OS/2:*:*)
-       echo "i386-pc-os2_emx"
-       exit 0;;
-#
-# end Apache changes
-#########################
+	exit ;;
     *:OS/390:*:*)
 	echo i370-ibm-openedition
-	exit 0 ;;
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
-	exit 0;;
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
 	echo hppa1.1-hitachi-hiuxmpp
-	exit 0;;
+	exit ;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
 	if test "`(/bin/universe) 2>/dev/null`" = att ; then
@@ -332,25 +317,51 @@
 	else
 		echo pyramid-pyramid-bsd
 	fi
-	exit 0 ;;
+	exit ;;
     NILE*:*:*:dcosx)
 	echo pyramid-pyramid-svr4
-	exit 0 ;;
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
-    i86pc:SunOS:5.*:*)
-	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
 	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     sun4*:SunOS:*:*)
 	case "`/usr/bin/arch -k`" in
 	    Series*|S4*)
@@ -359,10 +370,10 @@
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
 	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-	exit 0 ;;
+	exit ;;
     sun3*:SunOS:*:*)
 	echo m68k-sun-sunos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
 	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
@@ -374,10 +385,10 @@
 		echo sparc-sun-sunos${UNAME_RELEASE}
 		;;
 	esac
-	exit 0 ;;
+	exit ;;
     aushp:SunOS:*:*)
 	echo sparc-auspex-sunos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -387,38 +398,41 @@
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 	echo m68k-atari-mint${UNAME_RELEASE}
-        exit 0 ;;
+	exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-        echo m68k-atari-mint${UNAME_RELEASE}
-	exit 0 ;;
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-        echo m68k-milan-mint${UNAME_RELEASE}
-        exit 0 ;;
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-        echo m68k-hades-mint${UNAME_RELEASE}
-        exit 0 ;;
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-        echo m68k-unknown-mint${UNAME_RELEASE}
-        exit 0 ;;
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
     powerpc:machten:*:*)
 	echo powerpc-apple-machten${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     RISC*:Mach:*:*)
 	echo mips-dec-mach_bsd4.3
-	exit 0 ;;
+	exit ;;
     RISC*:ULTRIX:*:*)
 	echo mips-dec-ultrix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     VAX*:ULTRIX*:*:*)
 	echo vax-dec-ultrix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
 	echo clipper-intergraph-clix${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
@@ -442,30 +456,36 @@
 	  exit (-1);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy \
-	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
-	  && rm -f $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
 	echo mips-mips-riscos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     Motorola:PowerMAX_OS:*:*)
 	echo powerpc-motorola-powermax
-	exit 0 ;;
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
     Night_Hawk:Power_UNIX:*:*)
 	echo powerpc-harris-powerunix
-	exit 0 ;;
+	exit ;;
     m88k:CX/UX:7*:*)
 	echo m88k-harris-cxux7
-	exit 0 ;;
+	exit ;;
     m88k:*:4*:R4*)
 	echo m88k-motorola-sysv4
-	exit 0 ;;
+	exit ;;
     m88k:*:3*:R3*)
 	echo m88k-motorola-sysv3
-	exit 0 ;;
+	exit ;;
     AViiON:dgux:*:*)
-        # DG/UX returns AViiON for all architectures
-        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
 	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
 	then
 	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -478,29 +498,29 @@
 	else
 	    echo i586-dg-dgux${UNAME_RELEASE}
 	fi
- 	exit 0 ;;
+	exit ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 	echo m88k-dolphin-sysv3
-	exit 0 ;;
+	exit ;;
     M88*:*:R3*:*)
 	# Delta 88k system running SVR3
 	echo m88k-motorola-sysv3
-	exit 0 ;;
+	exit ;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
 	echo m88k-tektronix-sysv3
-	exit 0 ;;
+	exit ;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
 	echo m68k-tektronix-bsd
-	exit 0 ;;
+	exit ;;
     *:IRIX*:*:*)
 	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-	exit 0 ;;
+	exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
-	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
     i*86:AIX:*:*)
 	echo i386-ibm-aix
-	exit 0 ;;
+	exit ;;
     ia64:AIX:*:*)
 	if [ -x /usr/bin/oslevel ] ; then
 		IBM_REV=`/usr/bin/oslevel`
@@ -508,7 +528,7 @@
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
-	exit 0 ;;
+	exit ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
 		eval $set_cc_for_build
@@ -523,16 +543,19 @@
 			exit(0);
 			}
 EOF
-		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
-		rm -f $dummy.c $dummy
-		echo rs6000-ibm-aix3.2.5
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
 		echo rs6000-ibm-aix3.2.4
 	else
 		echo rs6000-ibm-aix3.2
 	fi
-	exit 0 ;;
-    *:AIX:*:[45])
+	exit ;;
+    *:AIX:*:[4567])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
@@ -545,28 +568,28 @@
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-	exit 0 ;;
+	exit ;;
     *:AIX:*:*)
 	echo rs6000-ibm-aix
-	exit 0 ;;
+	exit ;;
     ibmrt:4.4BSD:*|romp-ibm:BSD:*)
 	echo romp-ibm-bsd4.4
-	exit 0 ;;
+	exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
 	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-	exit 0 ;;                           # report: romp-ibm BSD 4.3
+	exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
 	echo rs6000-bull-bosx
-	exit 0 ;;
+	exit ;;
     DPX/2?00:B.O.S.:*:*)
 	echo m68k-bull-sysv3
-	exit 0 ;;
+	exit ;;
     9000/[34]??:4.3bsd:1.*:*)
 	echo m68k-hp-bsd
-	exit 0 ;;
+	exit ;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
 	echo m68k-hp-bsd4.4
-	exit 0 ;;
+	exit ;;
     9000/[34678]??:HP-UX:*:*)
 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	case "${UNAME_MACHINE}" in
@@ -575,64 +598,84 @@
 	    9000/[678][0-9][0-9])
 		if [ -x /usr/bin/getconf ]; then
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                    case "${sc_cpu_version}" in
-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
-                      532)                      # CPU_PA_RISC2_0
-                        case "${sc_kernel_bits}" in
-                          32) HP_ARCH="hppa2.0n" ;;
-                          64) HP_ARCH="hppa2.0w" ;;
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
 			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
-                        esac ;;
-                    esac
+			esac ;;
+		    esac
 		fi
 		if [ "${HP_ARCH}" = "" ]; then
 		    eval $set_cc_for_build
-		    sed 's/^              //' << EOF >$dummy.c
+		    sed 's/^		//' << EOF >$dummy.c
 
-              #define _HPUX_SOURCE
-              #include <stdlib.h>
-              #include <unistd.h>
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
 
-              int main ()
-              {
-              #if defined(_SC_KERNEL_BITS)
-                  long bits = sysconf(_SC_KERNEL_BITS);
-              #endif
-                  long cpu  = sysconf (_SC_CPU_VERSION);
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
 
-                  switch (cpu)
-              	{
-              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
-              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
-              	case CPU_PA_RISC2_0:
-              #if defined(_SC_KERNEL_BITS)
-              	    switch (bits)
-              		{
-              		case 64: puts ("hppa2.0w"); break;
-              		case 32: puts ("hppa2.0n"); break;
-              		default: puts ("hppa2.0"); break;
-              		} break;
-              #else  /* !defined(_SC_KERNEL_BITS) */
-              	    puts ("hppa2.0"); break;
-              #endif
-              	default: puts ("hppa1.0"); break;
-              	}
-                  exit (0);
-              }
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
 EOF
-		    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
-		    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
-		    rm -f $dummy.c $dummy
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-	exit 0 ;;
+	exit ;;
     ia64:HP-UX:*:*)
 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	echo ia64-hp-hpux${HPUX_REV}
-	exit 0 ;;
+	exit ;;
     3050*:HI-UX:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
@@ -660,160 +703,164 @@
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
-	rm -f $dummy.c $dummy
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
 	echo unknown-hitachi-hiuxwe2
-	exit 0 ;;
+	exit ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
 	echo hppa1.1-hp-bsd
-	exit 0 ;;
+	exit ;;
     9000/8??:4.3bsd:*:*)
 	echo hppa1.0-hp-bsd
-	exit 0 ;;
+	exit ;;
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
 	echo hppa1.0-hp-mpeix
-	exit 0 ;;
+	exit ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
 	echo hppa1.1-hp-osf
-	exit 0 ;;
+	exit ;;
     hp8??:OSF1:*:*)
 	echo hppa1.0-hp-osf
-	exit 0 ;;
+	exit ;;
     i*86:OSF1:*:*)
 	if [ -x /usr/sbin/sysversion ] ; then
 	    echo ${UNAME_MACHINE}-unknown-osf1mk
 	else
 	    echo ${UNAME_MACHINE}-unknown-osf1
 	fi
-	exit 0 ;;
+	exit ;;
     parisc*:Lites*:*:*)
 	echo hppa1.1-hp-lites
-	exit 0 ;;
+	exit ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
-        exit 0 ;;
+	exit ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-        exit 0 ;;
+	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 	echo c34-convex-bsd
-        exit 0 ;;
+	exit ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 	echo c38-convex-bsd
-        exit 0 ;;
+	exit ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
-        exit 0 ;;
+	exit ;;
     CRAY*Y-MP:*:*:*)
 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
     CRAY*[A-Z]90:*:*:*)
 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
 	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
 	      -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
     CRAY*TS:*:*:*)
 	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
-    CRAY*T3D:*:*:*)
-	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
     CRAY*T3E:*:*:*)
 	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
     CRAY*SV1:*:*:*)
 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit 0 ;;
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit 0 ;;
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     sparc*:BSD/OS:*:*)
 	echo sparc-unknown-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:BSD/OS:*:*)
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:FreeBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit 0 ;;
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
-	exit 0 ;;
-    i*:MINGW*:*)
+	exit ;;
+    *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
-	exit 0 ;;
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
     i*:PW*:*)
 	echo ${UNAME_MACHINE}-pc-pw32
-	exit 0 ;;
-    x86:Interix*:3*)
-	echo i386-pc-interix3
-	exit 0 ;;
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
 	# UNAME_MACHINE based on the output of uname instead of i386?
-	echo i386-pc-interix
-	exit 0 ;;
+	echo i586-pc-interix
+	exit ;;
     i*:UWIN*:*)
 	echo ${UNAME_MACHINE}-pc-uwin
-	exit 0 ;;
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
     p*:CYGWIN*:*)
 	echo powerpcle-unknown-cygwin
-	exit 0 ;;
+	exit ;;
     prep*:SunOS:5.*:*)
 	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit 0 ;;
+	exit ;;
     *:GNU:*:*)
+	# the GNU system
 	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-	exit 0 ;;
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
-	exit 0 ;;
-    arm*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit 0 ;;
-    ia64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit 0 ;;
-    m68*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit 0 ;;
-    mips:Linux:*:*)
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#undef CPU
-	#undef mips
-	#undef mipsel
-	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=mipsel
-	#else
-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=mips
-	#else
-	CPU=
-	#endif
-	#endif
-EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
-	rm -f $dummy.c
-	test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
-	;;
-    ppc:Linux:*:*)
-	echo powerpc-unknown-linux-gnu
-	exit 0 ;;
-    ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-gnu
-	exit 0 ;;
+	exit ;;
     alpha:Linux:*:*)
 	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
@@ -823,11 +870,87 @@
 	  EV6)   UNAME_MACHINE=alphaev6 ;;
 	  EV67)  UNAME_MACHINE=alphaev67 ;;
 	  EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
 	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
 	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
-	exit 0 ;;
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -835,90 +958,71 @@
 	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
 	  *)    echo hppa-unknown-linux-gnu ;;
 	esac
-	exit 0 ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-gnu
-	exit 0 ;;
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux
-	exit 0 ;;
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
     sh*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit 0 ;;
+	exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit 0 ;;
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-tilera-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
     x86_64:Linux:*:*)
 	echo x86_64-unknown-linux-gnu
-	exit 0 ;;
-    i*86:Linux:*:*)
-	# The BFD linker knows what the default object file format is, so
-	# first see if it will tell us. cd to the root directory to prevent
-	# problems with other programs or directories called `ld' in the path.
-	# Set LC_ALL=C to ensure ld outputs messages in English.
-	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
-			 | sed -ne '/supported targets:/!d
-				    s/[ 	][ 	]*/ /g
-				    s/.*supported targets: *//
-				    s/ .*//
-				    p'`
-        case "$ld_supported_targets" in
-	  elf32-i386)
-		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
-		;;
-	  a.out-i386-linux)
-		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-		exit 0 ;;		
-	  coff-i386)
-		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-		exit 0 ;;
-	  "")
-		# Either a pre-BFD a.out linker (linux-gnuoldld) or
-		# one that does not give us useful --help.
-		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
-		exit 0 ;;
-	esac
-	# Determine whether the default compiler is a.out or elf
-	eval $set_cc_for_build
-	sed 's/^	//' << EOF >$dummy.c
-	#include <features.h>
-	#ifdef __ELF__
-	# ifdef __GLIBC__
-	#  if __GLIBC__ >= 2
-	LIBC=gnu
-	#  else
-	LIBC=gnulibc1
-	#  endif
-	# else
-	LIBC=gnulibc1
-	# endif
-	#else
-	#ifdef __INTEL_COMPILER
-	LIBC=gnu
-	#else
-	LIBC=gnuaout
-	#endif
-	#endif
-EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
-	rm -f $dummy.c
-	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
-	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
-	;;
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
 	# sysname and nodename.
 	echo i386-sequent-sysv4
-	exit 0 ;;
+	exit ;;
     i*86:UNIX_SV:4.2MP:2.*)
-        # Unixware is an offshoot of SVR4, but it has its own version
-        # number series starting with 2...
-        # I am not positive that other SVR4 systems won't match this,
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
-        # Use sysv4.2uw... so that sysv4* matches it.
+	# Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-	exit 0 ;;
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
     i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -926,99 +1030,113 @@
 	else
 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
 	fi
-	exit 0 ;;
-    i*86:*:5:[78]*)
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 	case `/bin/uname -X | grep "^Machine"` in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
 	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-	exit 0 ;;
+	exit ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
 		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
-		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
-		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
-		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 			&& UNAME_MACHINE=i586
-		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
 		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
 	else
 		echo ${UNAME_MACHINE}-pc-sysv32
 	fi
-	exit 0 ;;
-    i*86:*DOS:*:*)
-	echo ${UNAME_MACHINE}-pc-msdosdjgpp
-	exit 0 ;;
+	exit ;;
     pc:*:*:*)
 	# Left here for compatibility:
-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i386.
-	echo i386-pc-msdosdjgpp
-        exit 0 ;;
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
     Intel:Mach:3*:*)
 	echo i386-pc-mach3
-	exit 0 ;;
+	exit ;;
     paragon:*:*:*)
 	echo i860-intel-osf1
-	exit 0 ;;
+	exit ;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
 	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
 	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
 	fi
-	exit 0 ;;
+	exit ;;
     mini*:CTIX:SYS*5:*)
 	# "miniframe"
 	echo m68010-convergent-sysv
-	exit 0 ;;
-    M68*:*:R3V[567]*:*)
-	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
-    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && echo i486-ncr-sysv4 && exit 0 ;;
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     mc68030:UNIX_System_V:4.*:*)
 	echo m68k-atari-sysv4
-	exit 0 ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
-	echo i386-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     TSUNAMI:LynxOS:2.*:*)
 	echo sparc-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
 	echo powerpc-unknown-lynxos${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     SM[BE]S:UNIX_SV:*:*)
 	echo mips-dde-sysv${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     RM*:ReliantUNIX-*:*:*)
 	echo mips-sni-sysv4
-	exit 0 ;;
+	exit ;;
     RM*:SINIX-*:*:*)
 	echo mips-sni-sysv4
-	exit 0 ;;
+	exit ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
@@ -1026,61 +1144,94 @@
 	else
 		echo ns32k-sni-sysv
 	fi
-	exit 0 ;;
-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
-        echo i586-unisys-sysv4
-        exit 0 ;;
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes@openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
 	echo hppa1.1-stratus-sysv4
-	exit 0 ;;
+	exit ;;
     *:*:*:FTX*)
 	# From seanf@swdc.stratus.com.
 	echo i860-stratus-sysv4
-	exit 0 ;;
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
     *:VOS:*:*)
 	# From Paul.Green@stratus.com.
 	echo hppa1.1-stratus-vos
-	exit 0 ;;
+	exit ;;
     mc68*:A/UX:*:*)
 	echo m68k-apple-aux${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     news*:NEWS-OS:6*:*)
 	echo mips-sony-newsos6
-	exit 0 ;;
+	exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
-	        echo mips-nec-sysv${UNAME_RELEASE}
+		echo mips-nec-sysv${UNAME_RELEASE}
 	else
-	        echo mips-unknown-sysv${UNAME_RELEASE}
+		echo mips-unknown-sysv${UNAME_RELEASE}
 	fi
-        exit 0 ;;
+	exit ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 	echo powerpc-be-beos
-	exit 0 ;;
+	exit ;;
     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
 	echo powerpc-apple-beos
-	exit 0 ;;
+	exit ;;
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 	echo i586-pc-beos
-	exit 0 ;;
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     SX-5:SUPER-UX:*:*)
 	echo sx5-nec-superux${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:Rhapsody:*:*)
 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:Darwin:*:*)
-	echo `uname -p`-apple-darwin${UNAME_RELEASE}
-	exit 0 ;;
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
 	if test "$UNAME_PROCESSOR" = "x86"; then
@@ -1088,22 +1239,28 @@
 		UNAME_MACHINE=pc
 	fi
 	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:QNX:*:4*)
 	echo i386-pc-qnx
-	exit 0 ;;
-    NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:NonStop-UX:*:*)
 	echo mips-compaq-nonstopux
-	exit 0 ;;
+	exit ;;
     BS2000:POSIX*:*:*)
 	echo bs2000-siemens-sysv
-	exit 0 ;;
+	exit ;;
     DS/*:UNIX_System_V:*:*)
 	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-	exit 0 ;;
+	exit ;;
     *:Plan9:*:*)
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
@@ -1114,36 +1271,50 @@
 	    UNAME_MACHINE="$cputype"
 	fi
 	echo ${UNAME_MACHINE}-unknown-plan9
-	exit 0 ;;
-    i*86:OS/2:*:*)
-	# If we were able to find `uname', then EMX Unix compatibility
-	# is probably installed.
-	echo ${UNAME_MACHINE}-pc-os2-emx
-	exit 0 ;;
+	exit ;;
     *:TOPS-10:*:*)
 	echo pdp10-unknown-tops10
-	exit 0 ;;
+	exit ;;
     *:TENEX:*:*)
 	echo pdp10-unknown-tenex
-	exit 0 ;;
+	exit ;;
     KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
 	echo pdp10-dec-tops20
-	exit 0 ;;
+	exit ;;
     XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
 	echo pdp10-xkl-tops20
-	exit 0 ;;
+	exit ;;
     *:TOPS-20:*:*)
 	echo pdp10-unknown-tops20
-	exit 0 ;;
+	exit ;;
     *:ITS:*:*)
 	echo pdp10-unknown-its
-	exit 0 ;;
-    i*86:XTS-300:*:STOP)
-	echo ${UNAME_MACHINE}-unknown-stop
-	exit 0 ;;
-    i*86:atheos:*:*)
-	echo ${UNAME_MACHINE}-unknown-atheos
-	exit 0 ;;
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1166,16 +1337,16 @@
 #include <sys/param.h>
   printf ("m68k-sony-newsos%s\n",
 #ifdef NEWSOS4
-          "4"
+	"4"
 #else
-	  ""
+	""
 #endif
-         ); exit (0);
+	); exit (0);
 #endif
 #endif
 
 #if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix"); exit (0);
+  printf ("arm-acorn-riscix\n"); exit (0);
 #endif
 
 #if defined (hp300) && !defined (hpux)
@@ -1264,12 +1435,12 @@
 }
 EOF
 
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
 
 # Apollos put the system type in the environment.
 
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
 
 # Convex versions that predate uname can use getsysinfo(1)
 
@@ -1278,22 +1449,22 @@
     case `getsysinfo -f cpu_type` in
     c1*)
 	echo c1-convex-bsd
-	exit 0 ;;
+	exit ;;
     c2*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-	exit 0 ;;
+	exit ;;
     c34*)
 	echo c34-convex-bsd
-	exit 0 ;;
+	exit ;;
     c38*)
 	echo c38-convex-bsd
-	exit 0 ;;
+	exit ;;
     c4*)
 	echo c4-convex-bsd
-	exit 0 ;;
+	exit ;;
     esac
 fi
 
@@ -1304,7 +1475,9 @@
 the operating system you are using. It is advised that you
 download the most up to date version of the config scripts from
 
-    ftp://ftp.gnu.org/pub/gnu/config/
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 
 If the version you run ($0) is already up to date, please
 send the following data and any information you think might be
diff --git a/xml/expat/conftools/config.sub b/xml/expat/conftools/config.sub
index 043d45b..30fdca8 100755
--- a/xml/expat/conftools/config.sub
+++ b/xml/expat/conftools/config.sub
@@ -1,9 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002 Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
 
-timestamp='2002-03-07'
+timestamp='2011-03-23'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -21,27 +22,26 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-#####################################################################
-# This file contains changes for Apache, clearly marked below.
-# These changes are hereby donated to the public domain.
-#####################################################################
 
 # Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted ChangeLog entry.
+# diff and a properly formatted GNU ChangeLog entry.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
 # If it is invalid, we print an error message on stderr and exit with code 1.
 # Otherwise, we print the canonical config type on stdout and succeed.
 
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
 # that are meaningful with *any* GNU software.
@@ -75,8 +75,9 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -88,11 +89,11 @@
 while test $# -gt 0 ; do
   case $1 in
     --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit 0 ;;
+       echo "$timestamp" ; exit ;;
     --version | -v )
-       echo "$version" ; exit 0 ;;
+       echo "$version" ; exit ;;
     --help | --h* | -h )
-       echo "$usage"; exit 0 ;;
+       echo "$usage"; exit ;;
     -- )     # Stop option processing
        shift; break ;;
     - )	# Use stdin as input.
@@ -104,7 +105,7 @@
     *local*)
        # First pass through any local machine types.
        echo $1
-       exit 0;;
+       exit ;;
 
     * )
        break ;;
@@ -123,28 +124,14 @@
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
-########################
-# changes for Apache
-#
-  tpf | os390 | vmcms)
-    os=-$maybe_os
-    basic_machine=s390;
-    ;;
-  os400)
-    os=-$maybe_os
-    basic_machine=as400;
-    ;;
-  mvs)
-    os=-mvs
-    basic_machine=i370;
-    ;;
-#
-# end Apache changes
-########################
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -167,10 +154,13 @@
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis)
+	-apple | -axis | -knuth | -cray | -microblaze)
 		os=
 		basic_machine=$1
 		;;
+	-bluegene*)
+		os=-cnk
+		;;
 	-sim | -cisco | -oki | -wec | -winbond)
 		os=
 		basic_machine=$1
@@ -185,13 +175,17 @@
 		os=-chorusos
 		basic_machine=$1
 		;;
- 	-chorusrdb)
- 		os=-chorusrdb
+	-chorusrdb)
+		os=-chorusrdb
 		basic_machine=$1
- 		;;
+		;;
 	-hiux*)
 		os=-hiuxwe2
 		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco5)
 		os=-sco3.2v5
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -208,6 +202,10 @@
 		# Don't forget version if it is 3.2v4 or newer.
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
 	-sco*)
 		os=-sco3.2v2
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -251,41 +249,94 @@
 	| a29k \
 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
 	| c4x | clipper \
-	| d10v | d30v | dsp16xx \
-	| fr30 \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| i370 | i860 | i960 | ia64 \
-	| m32r | m68000 | m68k | m88k | mcore \
-	| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
-	| mips64vr4100 | mips64vr4100el | mips64vr4300 \
-	| mips64vr4300el | mips64vr5000 | mips64vr5000el \
-	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
-	| mipsisa32 | mipsisa64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
 	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 \
 	| ns16k | ns32k \
-	| openrisc | or32 \
+	| open8 \
+	| or32 \
 	| pdp10 | pdp11 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
-	| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
-	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
-	| strongarm \
-	| tahoe | thumb | tic80 | tron \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
 	| v850 | v850e \
 	| we32k \
-	| x86 | xscale | xstormy16 | xtensa \
-	| z8k)
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
 		basic_machine=$basic_machine-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12)
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
 		# Motorola 68HC11/12.
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
@@ -304,40 +355,72 @@
 	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
-	| arm-*  | armbe-* | armle-* | armv*-* \
-	| avr-* \
-	| bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c54x-* \
-	| clipper-* | cydra-* \
-	| d10v-* | d30v-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
 	| elxsi-* \
-	| f30[01]-* | f700-* | fr30-* | fx80-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
-	| m32r-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | mcore-* \
-	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
-	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
-	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| romp-* | rs6000-* \
-	| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
-	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
-	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
-	| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile-* | tilegx-* \
+	| tron-* \
+	| ubicom32-* \
 	| v850-* | v850e-* | vax-* \
 	| we32k-* \
-	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
-	| xtensa-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
 	| ymp-* \
-	| z8k-*)
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
 		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
@@ -355,6 +438,9 @@
 		basic_machine=a29k-amd
 		os=-udi
 		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
 	adobe68k)
 		basic_machine=m68010-adobe
 		os=-scout
@@ -369,6 +455,12 @@
 		basic_machine=a29k-none
 		os=-bsd
 		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	amdahl)
 		basic_machine=580-amdahl
 		os=-sysv
@@ -392,6 +484,10 @@
 		basic_machine=m68k-apollo
 		os=-bsd
 		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -400,10 +496,35 @@
 		basic_machine=ns32k-sequent
 		os=-dynix
 		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	c90)
 		basic_machine=c90-cray
 		os=-unicos
 		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -428,12 +549,27 @@
 		basic_machine=j90-cray
 		os=-unicos
 		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
 	crds | unos)
 		basic_machine=m68k-crds
 		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
 	cris | cris-* | etrax*)
 		basic_machine=cris-axis
 		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
 	da30 | da30-*)
 		basic_machine=m68k-da30
 		;;
@@ -456,6 +592,14 @@
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
 	dpx20 | dpx20-*)
 		basic_machine=rs6000-bull
 		os=-bosx
@@ -606,6 +750,14 @@
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	m88k-omron*)
 		basic_machine=m88k-omron
 		;;
@@ -617,10 +769,17 @@
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
+	microblaze)
+		basic_machine=microblaze-xilinx
+		;;
 	mingw32)
 		basic_machine=i386-pc
 		os=-mingw32
 		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -634,10 +793,6 @@
 	mips3*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 		;;
-	mmix*)
-		basic_machine=mmix-knuth
-		os=-mmixware
-		;;
 	monitor)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -650,6 +805,9 @@
 		basic_machine=i386-pc
 		os=-msdos
 		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
 	mvs)
 		basic_machine=i370-ibm
 		os=-mvs
@@ -718,6 +876,12 @@
 	np1)
 		basic_machine=np1-gould
 		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -725,9 +889,12 @@
 		basic_machine=hppa1.1-oki
 		os=-proelf
 		;;
-	or32 | or32-*)
+	openrisc | openrisc-*)
 		basic_machine=or32-unknown
-		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
 		;;
 	OSE68000 | ose68000)
 		basic_machine=m68000-ericsson
@@ -745,55 +912,76 @@
 		basic_machine=i860-intel
 		os=-osf
 		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
 	pbd)
 		basic_machine=sparc-tti
 		;;
 	pbb)
 		basic_machine=m68k-tti
 		;;
-        pc532 | pc532-*)
+	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
-	pentiumpro | p6 | 6x86 | athlon)
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
 		basic_machine=i686-pc
 		;;
-	pentiumii | pentium2)
+	pentiumii | pentium2 | pentiumiii | pentium3)
 		basic_machine=i686-pc
 		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
 	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	pentiumii-* | pentium2-*)
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
 		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	pn)
 		basic_machine=pn-gould
 		;;
 	power)	basic_machine=power-ibm
 		;;
-	ppc)	basic_machine=powerpc-unknown
-	        ;;
-	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppcle | powerpclittle | ppc-le | powerpc-little)
 		basic_machine=powerpcle-unknown
-	        ;;
+		;;
 	ppcle-* | powerpclittle-*)
 		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppc64)	basic_machine=powerpc64-unknown
-	        ;;
+		;;
 	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
 	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
 		basic_machine=powerpc64le-unknown
-	        ;;
+		;;
 	ppc64le-* | powerpc64little-*)
 		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
@@ -804,6 +992,10 @@
 		basic_machine=i586-unknown
 		os=-pw32
 		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -824,15 +1016,20 @@
 		basic_machine=a29k-amd
 		os=-udi
 		;;
-########################
-# changes for Apache
-#
-	as400*)
-		basic_machine=as400-ibm
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
 		;;
-# 
-# end Apache changes
-########################
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
 	sequent)
 		basic_machine=i386-sequent
 		;;
@@ -840,6 +1037,12 @@
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
 	sparclite-wrs | simso-wrs)
 		basic_machine=sparclite-wrs
 		os=-vxworks
@@ -858,6 +1061,9 @@
 		basic_machine=i860-stratus
 		os=-sysv4
 		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
 	sun2)
 		basic_machine=m68000-sun
 		;;
@@ -898,7 +1104,7 @@
 	sun386 | sun386i | roadrunner)
 		basic_machine=i386-sun
 		;;
-        sv1)
+	sv1)
 		basic_machine=sv1-cray
 		os=-unicos
 		;;
@@ -906,10 +1112,6 @@
 		basic_machine=i386-sequent
 		os=-dynix
 		;;
-	t3d)
-		basic_machine=alpha-cray
-		os=-unicos
-		;;
 	t3e)
 		basic_machine=alphaev5-cray
 		os=-unicos
@@ -918,9 +1120,14 @@
 		basic_machine=t90-cray
 		os=-unicos
 		;;
-	tic54x | c54x*)
-		basic_machine=tic54x-unknown
-		os=-coff
+	# This must be matched before tile*.
+	tilegx*)
+		basic_machine=tilegx-unknown
+		os=-linux-gnu
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
 		;;
 	tx39)
 		basic_machine=mipstx39-unknown
@@ -935,6 +1142,10 @@
 	tower | tower-32)
 		basic_machine=m68k-ncr
 		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
 	udi29k)
 		basic_machine=a29k-amd
 		os=-udi
@@ -956,8 +1167,8 @@
 		os=-vms
 		;;
 	vpp*|vx|vx-*)
-               basic_machine=f301-fujitsu
-               ;;
+		basic_machine=f301-fujitsu
+		;;
 	vxworks960)
 		basic_machine=i960-wrs
 		os=-vxworks
@@ -978,13 +1189,16 @@
 		basic_machine=hppa1.1-winbond
 		os=-proelf
 		;;
-	windows32)
-		basic_machine=i386-pc
-		os=-windows32-msvcrt
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
 		;;
-        xps | xps100)
+	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
 	ymp)
 		basic_machine=ymp-cray
 		os=-unicos
@@ -993,6 +1207,10 @@
 		basic_machine=z8k-unknown
 		os=-sim
 		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
 	none)
 		basic_machine=none-none
 		os=-none
@@ -1012,6 +1230,9 @@
 	romp)
 		basic_machine=romp-ibm
 		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
 	rs6000)
 		basic_machine=rs6000-ibm
 		;;
@@ -1028,16 +1249,13 @@
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sh3 | sh4 | sh3eb | sh4eb)
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
 		basic_machine=sh-unknown
 		;;
-	sh64)
-		basic_machine=sh64-unknown
-		;;
-	sparc | sparcv9 | sparcv9b)
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 		basic_machine=sparc-sun
 		;;
-        cydra)
+	cydra)
 		basic_machine=cydra-cydrome
 		;;
 	orion)
@@ -1052,10 +1270,6 @@
 	pmac | pmac-mpw)
 		basic_machine=powerpc-apple
 		;;
-	c4x*)
-		basic_machine=c4x-none
-		os=-coff
-		;;
 	*-unknown)
 		# Make sure to match an already-canonicalized machine name.
 		;;
@@ -1082,9 +1296,12 @@
 if [ x"$os" != x"" ]
 then
 case $os in
-        # First match some system type aliases
-        # that might get confused with valid system types.
+	# First match some system type aliases
+	# that might get confused with valid system types.
 	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
 	-solaris1 | -solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
@@ -1100,37 +1317,36 @@
 	-gnu/linux*)
 		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
 		;;
-########################
-# changes for Apache
-#
-	-os2_emx | -tpf* | -os390* | -vmcms* | -os400* )
-        	;;
-#
-# end Apache changes
-########################
 	# First accept the basic system types.
 	# The portable systems comes first.
 	# Each alternative MUST END IN A *, to match a version number.
 	# -sysv* is not here because it comes later, after sysvr4.
 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
-	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
-	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -mingw32* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1142,16 +1358,21 @@
 			;;
 		esac
 		;;
+	-nto-qnx*)
+		;;
 	-nto*)
-		os=-nto-qnx
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
 	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
 	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 		;;
 	-mac*)
 		os=`echo $os | sed -e 's|mac|macos|'`
 		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
 	-linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
@@ -1164,6 +1385,9 @@
 	-opened*)
 		os=-openedition
 		;;
+	-os400*)
+		os=-os400
+		;;
 	-wince*)
 		os=-wince
 		;;
@@ -1185,6 +1409,9 @@
 	-atheos*)
 		os=-atheos
 		;;
+	-syllable*)
+		os=-syllable
+		;;
 	-386bsd)
 		os=-bsd
 		;;
@@ -1195,7 +1422,7 @@
 		os=-rtmk-nova
 		;;
 	-ns2 )
-	        os=-nextstep2
+		os=-nextstep2
 		;;
 	-nsk*)
 		os=-nsk
@@ -1207,6 +1434,9 @@
 	-sinix*)
 		os=-sysv4
 		;;
+	-tpf*)
+		os=-tpf
+		;;
 	-triton*)
 		os=-sysv3
 		;;
@@ -1234,8 +1464,22 @@
 	-xenix)
 		os=-xenix
 		;;
-        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-	        os=-mint
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
 		;;
 	-none)
 		;;
@@ -1259,6 +1503,12 @@
 # system, and we'll never get to this point.
 
 case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1268,11 +1518,23 @@
 	arm*-semi)
 		os=-aout
 		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
 		os=-tops20
 		;;
-        pdp11-*)
+	pdp11-*)
 		os=-none
 		;;
 	*-dec | vax-*)
@@ -1293,6 +1555,9 @@
 	m68*-cisco)
 		os=-aout
 		;;
+	mep-*)
+		os=-elf
+		;;
 	mips*-cisco)
 		os=-elf
 		;;
@@ -1311,33 +1576,15 @@
 	*-be)
 		os=-beos
 		;;
-########################
-# changes for Apache
-#
-#	*-ibm)
-#		os=-aix
-#		;;
-#
+	*-haiku)
+		os=-haiku
+		;;
 	*-ibm)
-		case $basic_machine in
-			s390*)
-				os=-os390;
-				;;
-			i370*)
-				os=-mvs;
-				;;
-			as400*)
-				os=-os400;
-				;;
-			*)
-				os=-aix
-				;;
-		esac
-                ;;
-# 
-# end Apache changes
-########################
-
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
 	*-wec)
 		os=-proelf
 		;;
@@ -1389,19 +1636,19 @@
 	*-next)
 		os=-nextstep3
 		;;
-        *-gould)
+	*-gould)
 		os=-sysv
 		;;
-        *-highlevel)
+	*-highlevel)
 		os=-bsd
 		;;
 	*-encore)
 		os=-bsd
 		;;
-        *-sgi)
+	*-sgi)
 		os=-irix
 		;;
-        *-siemens)
+	*-siemens)
 		os=-sysv4
 		;;
 	*-masscomp)
@@ -1440,7 +1687,7 @@
 			-sunos*)
 				vendor=sun
 				;;
-			-aix*)
+			-cnk*|-aix*)
 				vendor=ibm
 				;;
 			-beos*)
@@ -1470,10 +1717,16 @@
 			-mvs* | -opened*)
 				vendor=ibm
 				;;
+			-os400*)
+				vendor=ibm
+				;;
 			-ptx*)
 				vendor=sequent
 				;;
-			-vxsim* | -vxworks*)
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
 				vendor=wrs
 				;;
 			-aux*)
@@ -1497,7 +1750,7 @@
 esac
 
 echo $basic_machine$os
-exit 0
+exit
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
diff --git a/xml/expat/conftools/missing b/xml/expat/conftools/missing
deleted file mode 100755
index 7789652..0000000
--- a/xml/expat/conftools/missing
+++ /dev/null
@@ -1,190 +0,0 @@
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-if test $# -eq 0; then
-  echo 1>&2 "Try \`$0 --help' for more information"
-  exit 1
-fi
-
-case "$1" in
-
-  -h|--h|--he|--hel|--help)
-    echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
-  -h, --help      display this help and exit
-  -v, --version   output version information and exit
-
-Supported PROGRAM values:
-  aclocal      touch file \`aclocal.m4'
-  autoconf     touch file \`configure'
-  autoheader   touch file \`config.h.in'
-  automake     touch all \`Makefile.in' files
-  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
-  flex         create \`lex.yy.c', if possible, from existing .c
-  lex          create \`lex.yy.c', if possible, from existing .c
-  makeinfo     touch the output file
-  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
-    ;;
-
-  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
-    echo "missing - GNU libit 0.0"
-    ;;
-
-  -*)
-    echo 1>&2 "$0: Unknown \`$1' option"
-    echo 1>&2 "Try \`$0 --help' for more information"
-    exit 1
-    ;;
-
-  aclocal)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`acinclude.m4' or \`configure.in'.  You might want
-         to install the \`Automake' and \`Perl' packages.  Grab them from
-         any GNU archive site."
-    touch aclocal.m4
-    ;;
-
-  autoconf)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`configure.in'.  You might want to install the
-         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
-         archive site."
-    touch configure
-    ;;
-
-  autoheader)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`acconfig.h' or \`configure.in'.  You might want
-         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
-         from any GNU archive site."
-    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
-    test -z "$files" && files="config.h"
-    touch_files=
-    for f in $files; do
-      case "$f" in
-      *:*) touch_files="$touch_files "`echo "$f" |
-				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
-      *) touch_files="$touch_files $f.in";;
-      esac
-    done
-    touch $touch_files
-    ;;
-
-  automake)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
-         You might want to install the \`Automake' and \`Perl' packages.
-         Grab them from any GNU archive site."
-    find . -type f -name Makefile.am -print |
-	   sed 's/\.am$/.in/' |
-	   while read f; do touch "$f"; done
-    ;;
-
-  bison|yacc)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified a \`.y' file.  You may need the \`Bison' package
-         in order for those modifications to take effect.  You can get
-         \`Bison' from any GNU archive site."
-    rm -f y.tab.c y.tab.h
-    if [ $# -ne 1 ]; then
-        eval LASTARG="\${$#}"
-	case "$LASTARG" in
-	*.y)
-	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
-	    if [ -f "$SRCFILE" ]; then
-	         cp "$SRCFILE" y.tab.c
-	    fi
-	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
-	    if [ -f "$SRCFILE" ]; then
-	         cp "$SRCFILE" y.tab.h
-	    fi
-	  ;;
-	esac
-    fi
-    if [ ! -f y.tab.h ]; then
-	echo >y.tab.h
-    fi
-    if [ ! -f y.tab.c ]; then
-	echo 'main() { return 0; }' >y.tab.c
-    fi
-    ;;
-
-  lex|flex)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified a \`.l' file.  You may need the \`Flex' package
-         in order for those modifications to take effect.  You can get
-         \`Flex' from any GNU archive site."
-    rm -f lex.yy.c
-    if [ $# -ne 1 ]; then
-        eval LASTARG="\${$#}"
-	case "$LASTARG" in
-	*.l)
-	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
-	    if [ -f "$SRCFILE" ]; then
-	         cp "$SRCFILE" lex.yy.c
-	    fi
-	  ;;
-	esac
-    fi
-    if [ ! -f lex.yy.c ]; then
-	echo 'main() { return 0; }' >lex.yy.c
-    fi
-    ;;
-
-  makeinfo)
-    echo 1>&2 "\
-WARNING: \`$1' is missing on your system.  You should only need it if
-         you modified a \`.texi' or \`.texinfo' file, or any other file
-         indirectly affecting the aspect of the manual.  The spurious
-         call might also be the consequence of using a buggy \`make' (AIX,
-         DU, IRIX).  You might want to install the \`Texinfo' package or
-         the \`GNU make' package.  Grab either from any GNU archive site."
-    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
-    if test -z "$file"; then
-      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
-      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
-    fi
-    touch $file
-    ;;
-
-  *)
-    echo 1>&2 "\
-WARNING: \`$1' is needed, and you do not seem to have it handy on your
-         system.  You might have modified some files without having the
-         proper tools for further handling them.  Check the \`README' file,
-         it often tells you about the needed prerequirements for installing
-         this package.  You may also peek at any GNU archive site, in case
-         some other package would contain this missing \`$1' program."
-    exit 1
-    ;;
-esac
-
-exit 0
diff --git a/xml/expat/lib/Makefile.in b/xml/expat/lib/Makefile.in
deleted file mode 100644
index b5e4b3d..0000000
--- a/xml/expat/lib/Makefile.in
+++ /dev/null
@@ -1,154 +0,0 @@
-################################################################
-# Process this file with top-level configure script to produce Makefile
-#
-# Copyright 2000 Clark Cooper
-#
-#  This file is part of EXPAT.
-#
-#  EXPAT is free software; you can redistribute it and/or modify it
-#  under the terms of the License (based on the MIT/X license) contained
-#  in the file COPYING that comes with this distribution.
-#
-# EXPAT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN EXPAT.
-#
-
-
-SHELL = @SHELL@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-blddir = @blddir@/lib
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-
-subdir = lib
-
-top_builddir = ..
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_DATA = @INSTALL_DATA@
-
-host_alias = @host_alias@
-host_triplet = @host@
-AS = @AS@
-CC = @CC@
-DLLTOOL = @DLLTOOL@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-OBJDUMP = @OBJDUMP@
-PACKAGE = @PACKAGE@
-RANLIB = @RANLIB@
-VERSION = @VERSION@
-
-LIBRARY = libexpat.la
-SOURCES = xmlparse.c xmltok.c xmlrole.c
-OBJECTS = $(SOURCES:.c=.o)
-LTOBJECTS = $(SOURCES:.c=.lo)
-
-TEMPLATES = xmltok_impl.c xmltok_ns.c
-APIHEADER = expat.h
-HEADERS = ascii.h iasciitab.h utf8tab.h xmltok.h asciitab.h latin1tab.h \
-          nametab.h xmldef.h xmlrole.h xmltok_impl.h
-
-mkinstalldirs = $(SHELL) $(top_srcdir)/conftools/mkinstalldirs
-CONFIG_HEADER = ../config.h
-CONFIG_CLEAN_FILES = 
-
-INCLUDES = -I$(srcdir) -I.. -I$(blddir)
-DEFS = @DEFS@ -DPACKAGE='"$(PACKAGE)"' -DVERSION='"$(PACKAGE)_$(VERSION)"'
-
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-CFLAGS = @CFLAGS@
-
-LIBREVISION = @LIBREVISION@
-LIBCURRENT  = @LIBCURRENT@
-LIBAGE      = @LIBAGE@
-
-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --mode=link  $(CCLD) -version-info $(LIBCURRENT):$(LIBREVISION):$(LIBAGE) $(CFLAGS) $(LDFLAGS) -o $@
-DIST_COMMON =  Makefile.in
-
-
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(TEMPLATES) $(APIHEADER) $(HEADERS) 
-
-TAR = gtar
-GZIP_ENV = --best
-
-all: $(LIBRARY)
-
-.SUFFIXES: .c .lo .o
-.PHONY: all clean distclean maintainer-clean
-
-.c.o:
-	$(COMPILE) -c $<
-
-.c.lo:
-	$(LTCOMPILE) -c $<
-
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
-	cd $(top_builddir) \
-	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-$(top_builddir)/config.status: $(top_builddir)/configure
-	cd $(top_builddir) && $(MAKE) config.status
-
-$(top_builddir)/config.h: $(top_builddir)/config.h.in
-	cd $(top_builddir) && $(MAKE) config.h
-
-clean:
-	rm -f $(LIBRARY) *.o *.lo *~
-	rm -rf .libs _libs
-
-distclean: clean
-	rm -f Makefile expat.h
-
-maintainer-clean: distclean
-
-install: $(LIBRARY) $(APIHEADER)
-	$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
-	$(LIBTOOL)  --mode=install $(INSTALL) $(LIBRARY) $(DESTDIR)$(libdir)/$(LIBRARY)
-	$(INSTALL_DATA) $(APIHEADER) $(DESTDIR)$(includedir)
-
-uninstall:
-	$(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(LIBRARY);
-	rm -f $(DESTDIR)$(libdir)/$(APIHEADER)
-
-$(LIBRARY): $(LTOBJECTS)
-	$(LINK) -rpath $(libdir) $(LDFLAGS) $(LTOBJECTS)
-
-xmlparse.o \
-xmlparse.lo: xmlparse.c expat.h xmlrole.h xmltok.h $(top_builddir)/config.h
-
-xmlrole.o \
-xmlrole.lo: xmlrole.c ascii.h xmlrole.h $(top_builddir)/config.h
-
-xmltok.o \
-xmltok.lo: xmltok.c xmltok_impl.c xmltok_ns.c \
-          ascii.h asciitab.h iasciitab.h latin1tab.h nametab.h utf8tab.h \
-          xmltok.h xmltok_impl.h $(top_builddir)/config.h
diff --git a/xml/expat/lib/ascii.h b/xml/expat/lib/ascii.h
index 6376b1f..337e5bb 100644
--- a/xml/expat/lib/ascii.h
+++ b/xml/expat/lib/ascii.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 #define ASCII_A 0x41
@@ -69,7 +68,7 @@
 #define ASCII_9 0x39
 
 #define ASCII_TAB 0x09
-#define ASCII_SPACE 0x20 
+#define ASCII_SPACE 0x20
 #define ASCII_EXCL 0x21
 #define ASCII_QUOT 0x22
 #define ASCII_AMP 0x26
diff --git a/xml/expat/lib/asciitab.h b/xml/expat/lib/asciitab.h
index eb445cc..79a15c2 100644
--- a/xml/expat/lib/asciitab.h
+++ b/xml/expat/lib/asciitab.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
diff --git a/xml/expat/lib/expat.dsp b/xml/expat/lib/expat.dsp
index 71aae06..9078194 100644
--- a/xml/expat/lib/expat.dsp
+++ b/xml/expat/lib/expat.dsp
@@ -107,11 +107,11 @@
 
 !IF  "$(CFG)" == "expat - Win32 Release"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ELSEIF  "$(CFG)" == "expat - Win32 Debug"
 
-# ADD CPP /EHsc- /Od /D VERSION=\"expat_1.95.2\"
+# ADD CPP /EHsc- /Od /D VERSION=\"expat_1.95.7\"
 
 !ENDIF 
 
@@ -122,11 +122,11 @@
 
 !IF  "$(CFG)" == "expat - Win32 Release"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ELSEIF  "$(CFG)" == "expat - Win32 Debug"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ENDIF 
 
@@ -137,11 +137,11 @@
 
 !IF  "$(CFG)" == "expat - Win32 Release"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ELSEIF  "$(CFG)" == "expat - Win32 Debug"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ENDIF 
 
@@ -152,12 +152,12 @@
 
 !IF  "$(CFG)" == "expat - Win32 Release"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ELSEIF  "$(CFG)" == "expat - Win32 Debug"
 
 # PROP Exclude_From_Build 1
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ENDIF 
 
@@ -168,12 +168,12 @@
 
 !IF  "$(CFG)" == "expat - Win32 Release"
 
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ELSEIF  "$(CFG)" == "expat - Win32 Debug"
 
 # PROP Exclude_From_Build 1
-# ADD CPP /D VERSION=\"expat_1.95.2\"
+# ADD CPP /D VERSION=\"expat_1.95.7\"
 
 !ENDIF 
 
diff --git a/xml/expat/lib/expat.h b/xml/expat/lib/expat.h
new file mode 100644
index 0000000..f3130d4
--- /dev/null
+++ b/xml/expat/lib/expat.h
@@ -0,0 +1,1001 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
+*/
+
+#ifndef XmlParse_INCLUDED
+#define XmlParse_INCLUDED 1
+
+#ifdef __VMS
+/*      0        1         2         3      0        1         2         3
+        1234567890123456789012345678901     1234567890123456789012345678901 */
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
+#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler
+#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler
+#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg
+#endif
+
+#include <stdlib.h>
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+   defined.  There are two macros defined to control this boundary;
+   each of these can be defined before including this header to
+   achieve some different behavior, but doing so it not recommended or
+   tested frequently.
+
+   XMLCALL    - The calling convention to use for all calls across the
+                "library boundary."  This will default to cdecl, and
+                try really hard to tell the compiler that's what we
+                want.
+
+   XMLIMPORT  - Whatever magic is needed to note that a function is
+                to be imported from a dynamically loaded library
+                (.dll, .so, or .sl, depending on your platform).
+
+   The XMLCALL macro was added in Expat 1.95.7.  The only one which is
+   expected to be directly useful in client code is XMLCALL.
+
+   Note that on at least some Unix versions, the Expat library must be
+   compiled with the cdecl calling convention as the default since
+   system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(XML_USE_MSC_EXTENSIONS)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+   one calling convention, we need to extend this definition to
+   declare the convention used on that platform, if it's possible to
+   do so.
+
+   If this is the case for your platform, please file a bug report
+   with information on how to identify your platform via the C
+   pre-processor and how to specify the same calling convention as the
+   platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif  /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif  /* not defined XML_STATIC */
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else                  /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+/* Should this be defined using stdbool.h when C99 is available? */
+typedef unsigned char XML_Bool;
+#define XML_TRUE   ((XML_Bool) 1)
+#define XML_FALSE  ((XML_Bool) 0)
+
+/* The XML_Status enum gives the possible return values for several
+   API functions.  The preprocessor #defines are included so this
+   stanza can be added to code that still needs to support older
+   versions of Expat 1.95.x:
+
+   #ifndef XML_STATUS_OK
+   #define XML_STATUS_OK    1
+   #define XML_STATUS_ERROR 0
+   #endif
+
+   Otherwise, the #define hackery is quite ugly and would have been
+   dropped.
+*/
+enum XML_Status {
+  XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+  XML_STATUS_OK = 1
+#define XML_STATUS_OK XML_STATUS_OK
+};
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE,
+  XML_ERROR_UNEXPECTED_STATE,
+  XML_ERROR_ENTITY_DECLARED_IN_PE,
+  XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+  XML_ERROR_UNBOUND_PREFIX
+};
+
+enum XML_Content_Type {
+  XML_CTYPE_EMPTY = 1,
+  XML_CTYPE_ANY,
+  XML_CTYPE_MIXED,
+  XML_CTYPE_NAME,
+  XML_CTYPE_CHOICE,
+  XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+  XML_CQUANT_NONE,
+  XML_CQUANT_OPT,
+  XML_CQUANT_REP,
+  XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+   XML_CQUANT_NONE, and the other fields will be zero or NULL.
+   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+   numchildren will contain number of elements that may be mixed in
+   and children point to an array of XML_Content cells that will be
+   all of XML_CTYPE_NAME type with no quantification.
+
+   If type == XML_CTYPE_NAME, then the name points to the name, and
+   the numchildren field will be zero and children will be NULL. The
+   quant fields indicates any quantifiers placed on the name.
+
+   CHOICE and SEQ will have name NULL, the number of children in
+   numchildren and children will point, recursively, to an array
+   of XML_Content cells.
+
+   The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  XML_Char *                    name;
+  unsigned int                  numchildren;
+  XML_Content *                 children;
+};
+
+
+/* This is called for an element declaration. See above for
+   description of the model argument. It's the caller's responsibility
+   to free model when finished with it.
+*/
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,
+                                                const XML_Char *name,
+                                                XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+   a single Attlist declaration with multiple attributes declared will
+   generate multiple calls to this handler. The "default" parameter
+   may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+   keyword. The "isrequired" parameter will be true and the default
+   value will be NULL in the case of "#REQUIRED". If "isrequired" is
+   true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void (XMLCALL *XML_AttlistDeclHandler) (
+                                    void            *userData,
+                                    const XML_Char  *elname,
+                                    const XML_Char  *attname,
+                                    const XML_Char  *att_type,
+                                    const XML_Char  *dflt,
+                                    int              isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+   and text declarations. The way to distinguish is that the version
+   parameter will be NULL for text declarations. The encoding
+   parameter may be NULL for XML declarations. The standalone
+   parameter will be -1, 0, or 1 indicating respectively that there
+   was no standalone parameter in the declaration, that it was given
+   as no, or that it was given as yes.
+*/
+typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,
+                                            const XML_Char *version,
+                                            const XML_Char *encoding,
+                                            int             standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+  void *(XMLCALL *malloc_fcn)(size_t size);
+  void *(XMLCALL *realloc_fcn)(void *ptr, size_t size);
+  void (XMLCALL *free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+   external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type
+   names and attribute names that belong to a namespace will be
+   expanded; unprefixed attribute names are never expanded; unprefixed
+   element type names are expanded only if there is a default
+   namespace. The expanded name is the concatenation of the namespace
+   URI, the namespace separator character, and the local part of the
+   name.  If the namespace separator is '\0' then the namespace URI
+   and the local part will be concatenated without any separator.
+   When a namespace is not declared, the name and prefix will be
+   passed through without expansion.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suite referred to
+   by memsuite. If memsuite is NULL, then use the standard library memory
+   suite. If namespaceSeparator is non-NULL it creates a parser with
+   namespace processing as described above. The character pointed at
+   will serve as the namespace separator.
+
+   All further memory operations used for the created parser will come from
+   the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used.  This is particularly
+   valuable when memory allocation overhead is disproportionatly high,
+   such as when a large number of small documnents need to be parsed.
+   All handlers are cleared from the parser, except for the
+   unknownEncodingHandler. The parser's external state is re-initialized
+   except for the values of ns and ns_triplets.
+
+   Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated.
+*/
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,
+                                                 const XML_Char *name,
+                                                 const XML_Char **atts);
+
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,
+                                               const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,
+                                                  const XML_Char *s,
+                                                  int len);
+
+/* target and data are 0 terminated */
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (
+                                                void *userData,
+                                                const XML_Char *target,
+                                                const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,
+                                            const XML_Char *data);
+
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);
+
+/* This is called for any characters in the XML document for which
+   there is no applicable handler.  This includes both characters that
+   are part of markup which is of a kind that is not reported
+   (comments, markup declarations), or characters that are part of a
+   construct which could be reported but for which no handler has been
+   supplied. The characters are passed exactly as they were in the XML
+   document except that they will be encoded in UTF-8 or UTF-16.
+   Line boundaries are not normalized. Note that a byte order mark
+   character is not passed to the default handler. There are no
+   guarantees about how characters are divided between calls to the
+   default handler: for example, a comment might be split between
+   multiple calls.
+*/
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,
+                                            const XML_Char *s,
+                                            int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+   any DTD or internal subset is parsed.
+*/
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (
+                                            void *userData,
+                                            const XML_Char *doctypeName,
+                                            const XML_Char *sysid,
+                                            const XML_Char *pubid,
+                                            int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+   closing > is encountered, but after processing any external
+   subset.
+*/
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+   argument will be non-zero if the entity is a parameter entity, zero
+   otherwise.
+
+   For internal entities (<!ENTITY foo "bar">), value will
+   be non-NULL and systemId, publicID, and notationName will be NULL.
+   The value string is NOT nul-terminated; the length is provided in
+   the value_length argument. Since it is legal to have zero-length
+   values, do not use this argument to test for internal entities.
+
+   For external entities, value will be NULL and systemId will be
+   non-NULL. The publicId argument will be NULL unless a public
+   identifier was provided. The notationName argument will have a
+   non-NULL value only for unparsed entity declarations.
+
+   Note that is_parameter_entity can't be changed to XML_Bool, since
+   that would break binary compatibility.
+*/
+typedef void (XMLCALL *XML_EntityDeclHandler) (
+                              void *userData,
+                              const XML_Char *entityName,
+                              int is_parameter_entity,
+                              const XML_Char *value,
+                              int value_length,
+                              const XML_Char *base,
+                              const XML_Char *systemId,
+                              const XML_Char *publicId,
+                              const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+   This handler has been superceded by the EntityDeclHandler above.
+   It is provided here for backward compatibility.
+
+   This is called for a declaration of an unparsed (NDATA) entity.
+   The base argument is whatever was set by XML_SetBase. The
+   entityName, systemId and notationName arguments will never be
+   NULL. The other arguments may be.
+*/
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId,
+                                    const XML_Char *notationName);
+
+/* This is called for a declaration of notation.  The base argument is
+   whatever was set by XML_SetBase. The notationName will never be
+   NULL.  The other arguments can be.
+*/
+typedef void (XMLCALL *XML_NotationDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *notationName,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+   each namespace declaration. The call to the start and end element
+   handlers occur between the calls to the start and end namespace
+   declaration handlers. For an xmlns attribute, prefix will be
+   NULL.  For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix,
+                                    const XML_Char *uri);
+
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (
+                                    void *userData,
+                                    const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+   external subset or a reference to a parameter entity, but does not
+   have standalone="yes". If this handler returns XML_STATUS_ERROR,
+   then processing will not continue, and the parser will return a
+   XML_ERROR_NOT_STANDALONE error.
+   If parameter entity parsing is enabled, then in addition to the
+   conditions above this handler will only be called if the referenced
+   entity was actually read.
+*/
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);
+
+/* This is called for a reference to an external parsed general
+   entity.  The referenced entity is not automatically parsed.  The
+   application can parse it immediately or later using
+   XML_ExternalEntityParserCreate.
+
+   The parser argument is the parser parsing the entity containing the
+   reference; it can be passed as the parser argument to
+   XML_ExternalEntityParserCreate.  The systemId argument is the
+   system identifier as specified in the entity declaration; it will
+   not be NULL.
+
+   The base argument is the system identifier that should be used as
+   the base for resolving systemId if systemId was relative; this is
+   set by XML_SetBase; it may be NULL.
+
+   The publicId argument is the public identifier as specified in the
+   entity declaration, or NULL if none was specified; the whitespace
+   in the public identifier will have been normalized as required by
+   the XML spec.
+
+   The context argument specifies the parsing context in the format
+   expected by the context argument to XML_ExternalEntityParserCreate;
+   context is valid only until the handler returns, so if the
+   referenced entity is to be parsed later, it must be copied.
+   context is NULL only when the entity is a parameter entity.
+
+   The handler should return XML_STATUS_ERROR if processing should not
+   continue because of a fatal error in the handling of the external
+   entity.  In this case the calling parser will return an
+   XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+   Note that unlike other handlers the first argument is the parser,
+   not userData.
+*/
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (
+                                    XML_Parser parser,
+                                    const XML_Char *context,
+                                    const XML_Char *base,
+                                    const XML_Char *systemId,
+                                    const XML_Char *publicId);
+
+/* This is called in two situations:
+   1) An entity reference is encountered for which no declaration
+      has been read *and* this is not an error.
+   2) An internal entity reference is read, but not expanded, because
+      XML_SetDefaultHandler has been called.
+   Note: skipped parameter entities in declarations and skipped general
+         entities in attribute values cannot be reported, because
+         the event would be out of sync with the reporting of the
+         declarations or attribute values
+*/
+typedef void (XMLCALL *XML_SkippedEntityHandler) (
+                                    void *userData,
+                                    const XML_Char *entityName,
+                                    int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+   provide information to the parser about encodings that are unknown
+   to the parser.
+
+   The map[b] member gives information about byte sequences whose
+   first byte is b.
+
+   If map[b] is c where c is >= 0, then b by itself encodes the
+   Unicode scalar value c.
+
+   If map[b] is -1, then the byte sequence is malformed.
+
+   If map[b] is -n, where n >= 2, then b is the first byte of an
+   n-byte sequence that encodes a single Unicode scalar value.
+
+   The data member will be passed as the first argument to the convert
+   function.
+
+   The convert function is used to convert multibyte sequences; s will
+   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The
+   convert function must return the Unicode scalar value represented
+   by this byte sequence or -1 if the byte sequence is malformed.
+
+   The convert function may be NULL if the encoding is a single-byte
+   encoding, that is if map[b] >= -1 for all bytes b.
+
+   When the parser is finished with the encoding, then if release is
+   not NULL, it will call release passing it the data member; once
+   release has been called, the convert function will not be called
+   again.
+
+   Expat places certain restrictions on the encodings that are supported
+   using this mechanism.
+
+   1. Every ASCII character that can appear in a well-formed XML document,
+      other than the characters
+
+      $@\^`{}~
+
+      must be represented by a single byte, and that byte must be the
+      same byte that represents that character in ASCII.
+
+   2. No character may require more than 4 bytes to encode.
+
+   3. All characters encoded must have Unicode scalar values <=
+      0xFFFF, (i.e., characters that would be encoded by surrogates in
+      UTF-16 are  not allowed).  Note that this restriction doesn't
+      apply to the built-in support for UTF-8 and UTF-16.
+
+   4. No Unicode character may be encoded by more than one distinct
+      sequence of bytes.
+*/
+typedef struct {
+  int map[256];
+  void *data;
+  int (XMLCALL *convert)(void *data, const char *s);
+  void (XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+   The encodingHandlerData argument is that which was passed as the
+   second argument to XML_SetUnknownEncodingHandler.
+
+   The name argument gives the name of the encoding as specified in
+   the encoding declaration.
+
+   If the callback can provide information about the encoding, it must
+   fill in the XML_Encoding structure, and return XML_STATUS_OK.
+   Otherwise it must return XML_STATUS_ERROR.
+
+   If info does not describe a suitable encoding, then the parser will
+   return an XML_UNKNOWN_ENCODING error.
+*/
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (
+                                    void *encodingHandlerData,
+                                    const XML_Char *name,
+                                    XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+   internal entities. These entity references will be passed to the
+   default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+   internal entities.  The entity reference will not be passed to the
+   default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+   passed as the first argument to the external entity ref handler
+   instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+   element, processing instruction or character data.  It causes the
+   corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+   a name has a prefix (i.e. an explicit namespace qualifier) then
+   that name is returned as a triplet in a single string separated by
+   the separator character specified when the parser was created: URI
+   + sep + local_name + sep + prefix.
+
+   If do_nst is zero, then namespace information is returned in the
+   default manner (URI + sep + local_name) whether or not the name
+   has a prefix.
+
+   Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+     XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+   XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+   zero otherwise.
+   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+     has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+   first argument to callbacks instead of userData.  The userData will
+   still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+   will assume that there is an external subset, even if none is
+   specified in the document. In such a case the parser will call the
+   externalEntityRefHandler with a value of NULL for the systemId
+   argument (the publicId and context arguments will be NULL as well).
+   Note: If this function is called, then this must be done before
+     the first call to XML_Parse or XML_ParseBuffer, since it will
+     have no effect after that.  Returns
+     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+   Note: If the document does not have a DOCTYPE declaration at all,
+     then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+     be called, despite an external subset being parsed.
+   Note: If XML_DTD is not defined when Expat is compiled, returns
+     XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+
+/* Sets the base to be used for resolving relative URIs in system
+   identifiers in declarations.  Resolving relative identifiers is
+   left to the application: this value will be passed through as the
+   base argument to the XML_ExternalEntityRefHandler,
+   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+   argument will be copied.  Returns XML_STATUS_ERROR if out of memory,
+   XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+   to the XML_StartElementHandler that were specified in the start-tag
+   rather than defaulted. Each attribute/value pair counts as 2; thus
+   this correspondds to an index into the atts array passed to the
+   XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+   XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+   attribute/value pair counts as 2; thus this correspondds to an
+   index into the atts array passed to the XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+   detected.  The last call to XML_Parse must have isFinal true; len
+   may be zero for this call (or any other).
+
+   Though the return values for these functions has always been
+   described as a Boolean value, the implementation, at least for the
+   1.95.x series, has always returned exactly one of the XML_Status
+   values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Creates an XML_Parser object that can parse an external general
+   entity; context is a '\0'-terminated string specifying the parse
+   context; encoding is a '\0'-terminated string giving the name of
+   the externally specified encoding, or NULL if there is no
+   externally specified encoding.  The context string consists of a
+   sequence of tokens separated by formfeeds (\f); a token consisting
+   of a name specifies that the general entity of the name is open; a
+   token of the form prefix=uri specifies the namespace for a
+   particular prefix; a token of the form =uri specifies the default
+   namespace.  This can be called at any point after the first call to
+   an ExternalEntityRefHandler so longer as the parser has not yet
+   been freed.  The new parser is completely independent and may
+   safely be used in a separate thread.  The handlers and userData are
+   initialized from the parser argument.  Returns NULL if out of memory.
+   Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+                               const XML_Char *context,
+                               const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+   subset). If parsing of parameter entities is enabled, then
+   references to external parameter entities (including the external
+   DTD subset) will be passed to the handler set with
+   XML_SetExternalEntityRefHandler.  The context passed will be 0.
+
+   Unlike external general entities, external parameter entities can
+   only be parsed synchronously.  If the external parameter entity is
+   to be parsed, it must be parsed during the call to the external
+   entity ref handler: the complete sequence of
+   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+   XML_ParserFree calls must be made during this call.  After
+   XML_ExternalEntityParserCreate has been called to create the parser
+   for the external parameter entity (context must be 0 for this
+   call), it is illegal to make any calls on the old parser until
+   XML_ParserFree has been called on the newly created parser.
+   If the library has been compiled without support for parameter
+   entity parsing (ie without XML_DTD being defined), then
+   XML_SetParamEntityParsing will return 0 if parsing of parameter
+   entities is requested; otherwise it will return non-zero.
+   Note: If XML_SetParamEntityParsing is called after XML_Parse or
+      XML_ParseBuffer, then it has no effect and will always return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing parsing);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+   XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+   location.  They may be called from any callback called to report
+   some parse event; in this case the location is the location of the
+   first of the sequence of characters that generated the event.  When
+   called from callbacks generated by declarations in the document
+   prologue, the location identified isn't as neatly defined, but will
+   be within the relevant markup.  When called outside of the callback
+   functions, the position indicated will be just past the last parse
+   event (regardless of whether there was an associated callback).
+   
+   They may also be called after returning from a call to XML_Parse
+   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
+   the location is the location of the character at which the error
+   was detected; otherwise the location is the location of the last
+   parse event, as described above.
+*/
+XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+   Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+   the integer pointed to by offset to the offset within this buffer
+   of the current parse position, and sets the integer pointed to by size
+   to the size of this buffer (the number of input bytes). Otherwise
+   returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+   active.
+
+   NOTE: The character pointer returned should not be used outside
+   the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+                    int *offset,
+                    int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+  int major;
+  int minor;
+  int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+   number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+  XML_FEATURE_END = 0,
+  XML_FEATURE_UNICODE,
+  XML_FEATURE_UNICODE_WCHAR_T,
+  XML_FEATURE_DTD,
+  XML_FEATURE_CONTEXT_BYTES,
+  XML_FEATURE_MIN_SIZE,
+  XML_FEATURE_SIZEOF_XML_CHAR,
+  XML_FEATURE_SIZEOF_XML_LCHAR
+  /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+  enum XML_FeatureEnum  feature;
+  const XML_LChar       *name;
+  long int              value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+
+/* Expat follows the GNU/Linux convention of odd number minor version for
+   beta/development releases and even number minor version for stable
+   releases. Micro is bumped with each release, and set to 0 with each
+   change to major or minor version.
+*/
+#define XML_MAJOR_VERSION 1
+#define XML_MINOR_VERSION 95
+#define XML_MICRO_VERSION 7
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlParse_INCLUDED */
diff --git a/xml/expat/lib/expat.h.in b/xml/expat/lib/expat.h.in
deleted file mode 100644
index 9e440e2..0000000
--- a/xml/expat/lib/expat.h.in
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
-*/
-
-#ifndef XmlParse_INCLUDED
-#define XmlParse_INCLUDED 1
-
-#include <stdlib.h>
-
-#ifndef XMLPARSEAPI
-#  if defined(__declspec) && !defined(__CYGWIN__)
-#    define XMLPARSEAPI __declspec(dllimport)
-#  else
-#    define XMLPARSEAPI /* nothing */
-#  endif
-#endif  /* not defined XMLPARSEAPI */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *XML_Parser;
-
-/* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-
-enum XML_Content_Type {
-  XML_CTYPE_EMPTY = 1,
-  XML_CTYPE_ANY,
-  XML_CTYPE_MIXED,
-  XML_CTYPE_NAME,
-  XML_CTYPE_CHOICE,
-  XML_CTYPE_SEQ
-};
-
-enum XML_Content_Quant {
-  XML_CQUANT_NONE,
-  XML_CQUANT_OPT,
-  XML_CQUANT_REP,
-  XML_CQUANT_PLUS
-};
-
-/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
-   XML_CQUANT_NONE, and the other fields will be zero or NULL.
-   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
-   numchildren will contain number of elements that may be mixed in
-   and children point to an array of XML_Content cells that will be
-   all of XML_CTYPE_NAME type with no quantification.
-
-   If type == XML_CTYPE_NAME, then the name points to the name, and
-   the numchildren field will be zero and children will be NULL. The
-   quant fields indicates any quantifiers placed on the name.
-
-   CHOICE and SEQ will have name NULL, the number of children in
-   numchildren and children will point, recursively, to an array
-   of XML_Content cells.
-
-   The EMPTY, ANY, and MIXED types will only occur at top level.
-*/
-
-typedef struct XML_cp XML_Content;
-
-struct XML_cp {
-  enum XML_Content_Type		type;
-  enum XML_Content_Quant	quant;
-  const XML_Char *		name;
-  unsigned int			numchildren;
-  XML_Content *			children;
-};
-
-
-/* This is called for an element declaration. See above for
-   description of the model argument. It's the caller's responsibility
-   to free model when finished with it.
-*/
-
-typedef void (*XML_ElementDeclHandler) (void *userData,
-					const XML_Char *name,
-					XML_Content *model);
-
-void XMLPARSEAPI
-XML_SetElementDeclHandler(XML_Parser parser,
-			  XML_ElementDeclHandler eldecl);
-
-/*
-  The Attlist declaration handler is called for *each* attribute. So
-  a single Attlist declaration with multiple attributes declared will
-  generate multiple calls to this handler. The "default" parameter
-  may be NULL in the case of the "#IMPLIED" or "#REQUIRED" keyword.
-  The "isrequired" parameter will be true and the default value will
-  be NULL in the case of "#REQUIRED". If "isrequired" is true and
-  default is non-NULL, then this is a "#FIXED" default.
- */
-
-typedef void (*XML_AttlistDeclHandler) (void		*userData,
-					const XML_Char	*elname,
-					const XML_Char	*attname,
-					const XML_Char	*att_type,
-					const XML_Char	*dflt,
-					int		isrequired);
-
-void XMLPARSEAPI
-XML_SetAttlistDeclHandler(XML_Parser parser,
-			  XML_AttlistDeclHandler attdecl);
-
-
-  /* The XML declaration handler is called for *both* XML declarations and
-     text declarations. The way to distinguish is that the version parameter
-     will be null for text declarations. The encoding parameter may be null
-     for XML declarations. The standalone parameter will be -1, 0, or 1
-     indicating respectively that there was no standalone parameter in
-     the declaration, that it was given as no, or that it was given as yes.
-  */
-
-typedef void (*XML_XmlDeclHandler) (void		*userData,
-				    const XML_Char	*version,
-				    const XML_Char	*encoding,
-				    int			standalone);
-
-void XMLPARSEAPI
-XML_SetXmlDeclHandler(XML_Parser parser,
-		      XML_XmlDeclHandler xmldecl);
-
-
-typedef struct {
-  void *(*malloc_fcn)(size_t size);
-  void *(*realloc_fcn)(void *ptr, size_t size);
-  void (*free_fcn)(void *ptr);
-} XML_Memory_Handling_Suite;
-
-/* Constructs a new parser; encoding is the encoding specified by the
-external protocol or null if there is none specified. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreate(const XML_Char *encoding);
-
-/* Constructs a new parser and namespace processor.  Element type
-names and attribute names that belong to a namespace will be expanded;
-unprefixed attribute names are never expanded; unprefixed element type
-names are expanded only if there is a default namespace. The expanded
-name is the concatenation of the namespace URI, the namespace
-separator character, and the local part of the name.  If the namespace
-separator is '\0' then the namespace URI and the local part will be
-concatenated without any separator.  When a namespace is not declared,
-the name and prefix will be passed through without expansion. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
-
-/* Constructs a new parser using the memory management suit referred to
-   by memsuite. If memsuite is NULL, then use the standard library memory
-   suite. If namespaceSeparator is non-NULL it creates a parser with
-   namespace processing as described above. The character pointed at
-   will serve as the namespace separator.
-
-   All further memory operations used for the created parser will come from
-   the given suite.
-*/
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreate_MM(const XML_Char *encoding,
-		    const XML_Memory_Handling_Suite *memsuite,
-		    const XML_Char *namespaceSeparator);
-
-/* atts is array of name/value pairs, terminated by 0;
-   names and values are 0 terminated. */
-
-typedef void (*XML_StartElementHandler)(void *userData,
-					const XML_Char *name,
-					const XML_Char **atts);
-
-typedef void (*XML_EndElementHandler)(void *userData,
-				      const XML_Char *name);
-
-
-/* s is not 0 terminated. */
-typedef void (*XML_CharacterDataHandler)(void *userData,
-					 const XML_Char *s,
-					 int len);
-
-/* target and data are 0 terminated */
-typedef void (*XML_ProcessingInstructionHandler)(void *userData,
-						 const XML_Char *target,
-						 const XML_Char *data);
-
-/* data is 0 terminated */
-typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
-
-typedef void (*XML_StartCdataSectionHandler)(void *userData);
-typedef void (*XML_EndCdataSectionHandler)(void *userData);
-
-/* This is called for any characters in the XML document for
-which there is no applicable handler.  This includes both
-characters that are part of markup which is of a kind that is
-not reported (comments, markup declarations), or characters
-that are part of a construct which could be reported but
-for which no handler has been supplied. The characters are passed
-exactly as they were in the XML document except that
-they will be encoded in UTF-8.  Line boundaries are not normalized.
-Note that a byte order mark character is not passed to the default handler.
-There are no guarantees about how characters are divided between calls
-to the default handler: for example, a comment might be split between
-multiple calls. */
-
-typedef void (*XML_DefaultHandler)(void *userData,
-				   const XML_Char *s,
-				   int len);
-
-/* This is called for the start of the DOCTYPE declaration, before
-   any DTD or internal subset is parsed. */
-
-typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
-					    const XML_Char *doctypeName,
-					    const XML_Char *sysid,
-					    const XML_Char *pubid,
-					    int has_internal_subset
-					    );
-
-/* This is called for the start of the DOCTYPE declaration when the
-closing > is encountered, but after processing any external subset. */
-typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
-
-/* This is called for entity declarations. The is_parameter_entity
-   argument will be non-zero if the entity is a parameter entity, zero
-   otherwise.
-
-   For internal entities (<!ENTITY foo "bar">), value will
-   be non-null and systemId, publicID, and notationName will be null.
-   The value string is NOT null terminated; the length is provided in
-   the value_length argument. Since it is legal to have zero-length
-   values, do not use this argument to test for internal entities.
-
-   For external entities, value will be null and systemId will be non-null.
-   The publicId argument will be null unless a public identifier was
-   provided. The notationName argument will have a non-null value only
-   for unparsed entity declarations.
-*/
-
-typedef void (*XML_EntityDeclHandler) (void *userData,
-				       const XML_Char *entityName,
-				       int is_parameter_entity,
-				       const XML_Char *value,
-				       int value_length,
-				       const XML_Char *base,
-				       const XML_Char *systemId,
-				       const XML_Char *publicId,
-				       const XML_Char *notationName);
-				       
-void XMLPARSEAPI
-XML_SetEntityDeclHandler(XML_Parser parser,
-			 XML_EntityDeclHandler handler);
-
-/* OBSOLETE -- OBSOLETE -- OBSOLETE
-   This handler has been superceded by the EntityDeclHandler above.
-   It is provided here for backward compatibility.
-This is called for a declaration of an unparsed (NDATA)
-entity.  The base argument is whatever was set by XML_SetBase.
-The entityName, systemId and notationName arguments will never be null.
-The other arguments may be. */
-
-typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
-					      const XML_Char *entityName,
-					      const XML_Char *base,
-					      const XML_Char *systemId,
-					      const XML_Char *publicId,
-					      const XML_Char *notationName);
-
-/* This is called for a declaration of notation.
-The base argument is whatever was set by XML_SetBase.
-The notationName will never be null.  The other arguments can be. */
-
-typedef void (*XML_NotationDeclHandler)(void *userData,
-					const XML_Char *notationName,
-					const XML_Char *base,
-					const XML_Char *systemId,
-					const XML_Char *publicId);
-
-/* When namespace processing is enabled, these are called once for
-each namespace declaration. The call to the start and end element
-handlers occur between the calls to the start and end namespace
-declaration handlers. For an xmlns attribute, prefix will be null.
-For an xmlns="" attribute, uri will be null. */
-
-typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
-					      const XML_Char *prefix,
-					      const XML_Char *uri);
-
-typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
-					    const XML_Char *prefix);
-
-/* This is called if the document is not standalone (it has an
-external subset or a reference to a parameter entity, but does not
-have standalone="yes"). If this handler returns 0, then processing
-will not continue, and the parser will return a
-XML_ERROR_NOT_STANDALONE error. */
-
-typedef int (*XML_NotStandaloneHandler)(void *userData);
-
-/* This is called for a reference to an external parsed general entity.
-The referenced entity is not automatically parsed.
-The application can parse it immediately or later using
-XML_ExternalEntityParserCreate.
-The parser argument is the parser parsing the entity containing the reference;
-it can be passed as the parser argument to XML_ExternalEntityParserCreate.
-The systemId argument is the system identifier as specified in the entity
-declaration; it will not be null.
-The base argument is the system identifier that should be used as the base for
-resolving systemId if systemId was relative; this is set by XML_SetBase;
-it may be null.
-The publicId argument is the public identifier as specified in the entity
-declaration, or null if none was specified; the whitespace in the public
-identifier will have been normalized as required by the XML spec.
-The context argument specifies the parsing context in the format
-expected by the context argument to
-XML_ExternalEntityParserCreate; context is valid only until the handler
-returns, so if the referenced entity is to be parsed later, it must be copied.
-The handler should return 0 if processing should not continue because of
-a fatal error in the handling of the external entity.
-In this case the calling parser will return an
-XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
-Note that unlike other handlers the first argument is the parser, not
-userData. */
-
-typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
-					    const XML_Char *context,
-					    const XML_Char *base,
-					    const XML_Char *systemId,
-					    const XML_Char *publicId);
-
-/* This structure is filled in by the XML_UnknownEncodingHandler
-to provide information to the parser about encodings that are unknown
-to the parser.
-The map[b] member gives information about byte sequences
-whose first byte is b.
-If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar
-value c.
-If map[b] is -1, then the byte sequence is malformed.
-If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
-sequence that encodes a single Unicode scalar value.
-The data member will be passed as the first argument to the convert function.
-The convert function is used to convert multibyte sequences;
-s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
-The convert function must return the Unicode scalar value
-represented by this byte sequence or -1 if the byte sequence is malformed.
-The convert function may be null if the encoding is a single-byte encoding,
-that is if map[b] >= -1 for all bytes b.
-When the parser is finished with the encoding, then if release is not null,
-it will call release passing it the data member;
-once release has been called, the convert function will not be called again.
-
-Expat places certain restrictions on the encodings that are supported
-using this mechanism.
-
-1. Every ASCII character that can appear in a well-formed XML document,
-other than the characters
-
-  $@\^`{}~
-
-must be represented by a single byte, and that byte must be the
-same byte that represents that character in ASCII.
-
-2. No character may require more than 4 bytes to encode.
-
-3. All characters encoded must have Unicode scalar values <= 0xFFFF,
-(ie characters that would be encoded by surrogates in UTF-16
-are  not allowed).  Note that this restriction doesn't apply to
-the built-in support for UTF-8 and UTF-16.
-
-4. No Unicode character may be encoded by more than one distinct sequence
-of bytes. */
-
-typedef struct {
-  int map[256];
-  void *data;
-  int (*convert)(void *data, const char *s);
-  void (*release)(void *data);
-} XML_Encoding;
-
-/* This is called for an encoding that is unknown to the parser.
-The encodingHandlerData argument is that which was passed as the
-second argument to XML_SetUnknownEncodingHandler.
-The name argument gives the name of the encoding as specified in
-the encoding declaration.
-If the callback can provide information about the encoding,
-it must fill in the XML_Encoding structure, and return 1.
-Otherwise it must return 0.
-If info does not describe a suitable encoding,
-then the parser will return an XML_UNKNOWN_ENCODING error. */
-
-typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
-					  const XML_Char *name,
-					  XML_Encoding *info);
-
-void XMLPARSEAPI
-XML_SetElementHandler(XML_Parser parser,
-		      XML_StartElementHandler start,
-		      XML_EndElementHandler end);
-
-void XMLPARSEAPI
-XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler);
-
-void XMLPARSEAPI
-XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
-
-void XMLPARSEAPI
-XML_SetCharacterDataHandler(XML_Parser parser,
-			    XML_CharacterDataHandler handler);
-
-void XMLPARSEAPI
-XML_SetProcessingInstructionHandler(XML_Parser parser,
-				    XML_ProcessingInstructionHandler handler);
-void XMLPARSEAPI
-XML_SetCommentHandler(XML_Parser parser,
-                      XML_CommentHandler handler);
-
-void XMLPARSEAPI
-XML_SetCdataSectionHandler(XML_Parser parser,
-			   XML_StartCdataSectionHandler start,
-			   XML_EndCdataSectionHandler end);
-
-void XMLPARSEAPI
-XML_SetStartCdataSectionHandler(XML_Parser parser,
-                                XML_StartCdataSectionHandler start);
-
-void XMLPARSEAPI
-XML_SetEndCdataSectionHandler(XML_Parser parser,
-                              XML_EndCdataSectionHandler end);
-
-/* This sets the default handler and also inhibits expansion of
-internal entities.  The entity reference will be passed to the default
-handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandler(XML_Parser parser,
-		      XML_DefaultHandler handler);
-
-/* This sets the default handler but does not inhibit expansion of
-internal entities.  The entity reference will not be passed to the
-default handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandlerExpand(XML_Parser parser,
-		            XML_DefaultHandler handler);
-
-void XMLPARSEAPI
-XML_SetDoctypeDeclHandler(XML_Parser parser,
-			  XML_StartDoctypeDeclHandler start,
-			  XML_EndDoctypeDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetStartDoctypeDeclHandler(XML_Parser parser,
-			       XML_StartDoctypeDeclHandler start);
-
-void XMLPARSEAPI
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
-			     XML_EndDoctypeDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-				 XML_UnparsedEntityDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNotationDeclHandler(XML_Parser parser,
-			   XML_NotationDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNamespaceDeclHandler(XML_Parser parser,
-			    XML_StartNamespaceDeclHandler start,
-			    XML_EndNamespaceDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetStartNamespaceDeclHandler(XML_Parser parser,
-				 XML_StartNamespaceDeclHandler start);
-
-void XMLPARSEAPI
-XML_SetEndNamespaceDeclHandler(XML_Parser parser,
-			       XML_EndNamespaceDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetNotStandaloneHandler(XML_Parser parser,
-			    XML_NotStandaloneHandler handler);
-
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandler(XML_Parser parser,
-				XML_ExternalEntityRefHandler handler);
-
-/* If a non-null value for arg is specified here, then it will be passed
-as the first argument to the external entity ref handler instead
-of the parser object. */
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
-
-void XMLPARSEAPI
-XML_SetUnknownEncodingHandler(XML_Parser parser,
-			      XML_UnknownEncodingHandler handler,
-			      void *encodingHandlerData);
-
-/* This can be called within a handler for a start element, end element,
-processing instruction or character data.  It causes the corresponding
-markup to be passed to the default handler. */
-void XMLPARSEAPI
-XML_DefaultCurrent(XML_Parser parser);
-
-/* If do_nst is non-zero, and namespace processing is in effect, and
-   a name has a prefix (i.e. an explicit namespace qualifier) then
-   that name is returned as a triplet in a single
-   string separated by the separator character specified when the parser
-   was created: URI + sep + local_name + sep + prefix.
-
-   If do_nst is zero, then namespace information is returned in the
-   default manner (URI + sep + local_name) whether or not the names
-   has a prefix.
-*/
-
-void XMLPARSEAPI
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
-
-/* This value is passed as the userData argument to callbacks. */
-void XMLPARSEAPI
-XML_SetUserData(XML_Parser parser, void *userData);
-
-/* Returns the last value set by XML_SetUserData or null. */
-#define XML_GetUserData(parser) (*(void **)(parser))
-
-/* This is equivalent to supplying an encoding argument
-to XML_ParserCreate. It must not be called after XML_Parse
-or XML_ParseBuffer. */
-
-int XMLPARSEAPI
-XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
-
-/* If this function is called, then the parser will be passed
-as the first argument to callbacks instead of userData.
-The userData will still be accessible using XML_GetUserData. */
-
-void XMLPARSEAPI 
-XML_UseParserAsHandlerArg(XML_Parser parser);
-
-/* Sets the base to be used for resolving relative URIs in system
-identifiers in declarations.  Resolving relative identifiers is left
-to the application: this value will be passed through as the base
-argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler
-and XML_UnparsedEntityDeclHandler. The base argument will be copied.
-Returns zero if out of memory, non-zero otherwise. */
-
-int XMLPARSEAPI
-XML_SetBase(XML_Parser parser, const XML_Char *base);
-
-const XML_Char  XMLPARSEAPI *
-XML_GetBase(XML_Parser parser);
-
-/* Returns the number of the attribute/value pairs passed in last call
-to the XML_StartElementHandler that were specified in the start-tag
-rather than defaulted. Each attribute/value pair counts as 2; thus
-this correspondds to an index into the atts array passed to the
-XML_StartElementHandler. */
-
-int XMLPARSEAPI
-XML_GetSpecifiedAttributeCount(XML_Parser parser);
-
-/* Returns the index of the ID attribute passed in the last call to
-XML_StartElementHandler, or -1 if there is no ID attribute.  Each
-attribute/value pair counts as 2; thus this correspondds to an index
-into the atts array passed to the XML_StartElementHandler. */
-
-int XMLPARSEAPI
-XML_GetIdAttributeIndex(XML_Parser parser);
-
-/* Parses some input. Returns 0 if a fatal error is detected.
-The last call to XML_Parse must have isFinal true;
-len may be zero for this call (or any other). */
-int XMLPARSEAPI
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
-
-void XMLPARSEAPI *
-XML_GetBuffer(XML_Parser parser, int len);
-
-int XMLPARSEAPI
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
-
-/* Creates an XML_Parser object that can parse an external general
-entity; context is a '\0'-terminated string specifying the parse
-context; encoding is a '\0'-terminated string giving the name of the
-externally specified encoding, or null if there is no externally
-specified encoding.  The context string consists of a sequence of
-tokens separated by formfeeds (\f); a token consisting of a name
-specifies that the general entity of the name is open; a token of the
-form prefix=uri specifies the namespace for a particular prefix; a
-token of the form =uri specifies the default namespace.  This can be
-called at any point after the first call to an
-ExternalEntityRefHandler so longer as the parser has not yet been
-freed.  The new parser is completely independent and may safely be
-used in a separate thread.  The handlers and userData are initialized
-from the parser argument.  Returns 0 if out of memory.  Otherwise
-returns a new XML_Parser object. */
-XML_Parser XMLPARSEAPI
-XML_ExternalEntityParserCreate(XML_Parser parser,
-			       const XML_Char *context,
-			       const XML_Char *encoding);
-
-enum XML_ParamEntityParsing {
-  XML_PARAM_ENTITY_PARSING_NEVER,
-  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
-  XML_PARAM_ENTITY_PARSING_ALWAYS
-};
-
-/* Controls parsing of parameter entities (including the external DTD
-subset). If parsing of parameter entities is enabled, then references
-to external parameter entities (including the external DTD subset)
-will be passed to the handler set with
-XML_SetExternalEntityRefHandler.  The context passed will be 0.
-Unlike external general entities, external parameter entities can only
-be parsed synchronously.  If the external parameter entity is to be
-parsed, it must be parsed during the call to the external entity ref
-handler: the complete sequence of XML_ExternalEntityParserCreate,
-XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
-this call.  After XML_ExternalEntityParserCreate has been called to
-create the parser for the external parameter entity (context must be 0
-for this call), it is illegal to make any calls on the old parser
-until XML_ParserFree has been called on the newly created parser.  If
-the library has been compiled without support for parameter entity
-parsing (ie without XML_DTD being defined), then
-XML_SetParamEntityParsing will return 0 if parsing of parameter
-entities is requested; otherwise it will return non-zero. */
-
-int XMLPARSEAPI
-XML_SetParamEntityParsing(XML_Parser parser,
-			  enum XML_ParamEntityParsing parsing);
-
-enum XML_Error {
-  XML_ERROR_NONE,
-  XML_ERROR_NO_MEMORY,
-  XML_ERROR_SYNTAX,
-  XML_ERROR_NO_ELEMENTS,
-  XML_ERROR_INVALID_TOKEN,
-  XML_ERROR_UNCLOSED_TOKEN,
-  XML_ERROR_PARTIAL_CHAR,
-  XML_ERROR_TAG_MISMATCH,
-  XML_ERROR_DUPLICATE_ATTRIBUTE,
-  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
-  XML_ERROR_PARAM_ENTITY_REF,
-  XML_ERROR_UNDEFINED_ENTITY,
-  XML_ERROR_RECURSIVE_ENTITY_REF,
-  XML_ERROR_ASYNC_ENTITY,
-  XML_ERROR_BAD_CHAR_REF,
-  XML_ERROR_BINARY_ENTITY_REF,
-  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
-  XML_ERROR_MISPLACED_XML_PI,
-  XML_ERROR_UNKNOWN_ENCODING,
-  XML_ERROR_INCORRECT_ENCODING,
-  XML_ERROR_UNCLOSED_CDATA_SECTION,
-  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
-  XML_ERROR_NOT_STANDALONE,
-  XML_ERROR_UNEXPECTED_STATE
-};
-
-/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
-returns information about the error. */
-
-enum XML_Error  XMLPARSEAPI
-XML_GetErrorCode(XML_Parser parser);
-
-/* These functions return information about the current parse location.
-They may be called when XML_Parse or XML_ParseBuffer return 0;
-in this case the location is the location of the character at which
-the error was detected.
-They may also be called from any other callback called to report
-some parse event; in this the location is the location of the first
-of the sequence of characters that generated the event. */
-
-int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
-int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
-long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
-
-/* Return the number of bytes in the current event.
-Returns 0 if the event is in an internal entity. */
-
-int XMLPARSEAPI
-XML_GetCurrentByteCount(XML_Parser parser);
-
-/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
-   the integer pointed to by offset to the offset within this buffer
-   of the current parse position, and sets the integer pointed to by size
-   to the size of this buffer (the number of input bytes). Otherwise
-   returns a null pointer. Also returns a null pointer if a parse isn't
-   active.
-
-   NOTE: The character pointer returned should not be used outside
-   the handler that makes the call. */
-
-const char XMLPARSEAPI *
-XML_GetInputContext(XML_Parser parser,
-		    int *offset,
-		    int *size);
-
-/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
-
-/* Frees memory used by the parser. */
-void XMLPARSEAPI
-XML_ParserFree(XML_Parser parser);
-
-/* Returns a string describing the error. */
-const XML_LChar XMLPARSEAPI *
-XML_ErrorString(int code);
-
-/* Return a string containing the version number of this expat */
-const XML_LChar XMLPARSEAPI *
-XML_ExpatVersion(void);
-
-typedef struct {
-  int major;
-  int minor;
-  int micro;
-} XML_Expat_Version;
-
-/* Return an XML_Expat_Version structure containing numeric version
-   number information for this version of expat */
-
-XML_Expat_Version XMLPARSEAPI
-XML_ExpatVersionInfo(void);
-
-#ifndef XML_MAJOR_VERSION
-#define XML_MAJOR_VERSION 1
-#endif
-#ifndef XML_MINOR_VERSION
-#define XML_MINOR_VERSION 95
-#endif
-#ifndef XML_MICRO_VERSION
-#define XML_MICRO_VERSION 2
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlParse_INCLUDED */
diff --git a/xml/expat/lib/config.hnw b/xml/expat/lib/expat_config.hnw
similarity index 80%
rename from xml/expat/lib/config.hnw
rename to xml/expat/lib/expat_config.hnw
index de129d3..e45f570 100644
--- a/xml/expat/lib/config.hnw
+++ b/xml/expat/lib/expat_config.hnw
@@ -9,15 +9,16 @@
 **
 */
 
-#ifndef CONFIG_HNW
-#define CONFIG_HNW
+#ifndef EXPAT_CONFIG_HNW
+#define EXPAT_CONFIG_HNW
 
-#include <memory.h>
 #include <string.h>
 
+#define HAVE_MEMMOVE
+
 #define XML_NS 1
 #define XML_DTD 1
 #define XML_BYTE_ORDER 12
 #define XML_CONTEXT_BYTES 1024
 
-#endif /* ndef CONFIG_HNW */
+#endif /* ndef EXPAT_CONFIG_HNW */
diff --git a/xml/expat/lib/iasciitab.h b/xml/expat/lib/iasciitab.h
index 55dbc39..24a1d5c 100644
--- a/xml/expat/lib/iasciitab.h
+++ b/xml/expat/lib/iasciitab.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
diff --git a/xml/expat/lib/internal.h b/xml/expat/lib/internal.h
new file mode 100644
index 0000000..ff056c6
--- /dev/null
+++ b/xml/expat/lib/internal.h
@@ -0,0 +1,73 @@
+/* internal.h
+
+   Internal definitions used by Expat.  This is not needed to compile
+   client code.
+
+   The following calling convention macros are defined for frequently
+   called functions:
+
+   FASTCALL    - Used for those internal functions that have a simple
+                 body and a low number of arguments and local variables.
+
+   PTRCALL     - Used for functions called though function pointers.
+
+   PTRFASTCALL - Like PTRCALL, but for low number of arguments.
+
+   inline      - Used for selected internal functions for which inlining
+                 may improve performance on some platforms.
+
+   Note: Use of these macros is based on judgement, not hard rules,
+         and therefore subject to change.
+*/
+
+#if defined(__GNUC__) && defined(__i386__)
+/* We'll use this version by default only where we know it helps.
+
+   regparm() generates warnings on Solaris boxes.   See SF bug #692878.
+
+   Instability reported with egcs on a RedHat Linux 7.3.
+   Let's comment out:
+   #define FASTCALL __attribute__((stdcall, regparm(3)))
+   and let's try this:
+*/
+#define FASTCALL __attribute__((regparm(3)))
+#define PTRFASTCALL __attribute__((regparm(3)))
+#endif
+
+/* Using __fastcall seems to have an unexpected negative effect under
+   MS VC++, especially for function pointers, so we won't use it for
+   now on that platform. It may be reconsidered for a future release
+   if it can be made more effective.
+   Likely reason: __fastcall on Windows is like stdcall, therefore
+   the compiler cannot perform stack optimizations for call clusters.
+*/
+
+/* Make sure all of these are defined if they aren't already. */
+
+#ifndef FASTCALL
+#define FASTCALL
+#endif
+
+#ifndef PTRCALL
+#define PTRCALL
+#endif
+
+#ifndef PTRFASTCALL
+#define PTRFASTCALL
+#endif
+
+#ifndef XML_MIN_SIZE
+#if !defined(__cplusplus) && !defined(inline)
+#ifdef __GNUC__
+#define inline __inline
+#endif /* __GNUC__ */
+#endif
+#endif /* XML_MIN_SIZE */
+
+#ifdef __cplusplus
+#define inline inline
+#else
+#ifndef inline
+#define inline
+#endif
+#endif
diff --git a/xml/expat/lib/latin1tab.h b/xml/expat/lib/latin1tab.h
index 178b1d1..53c25d7 100644
--- a/xml/expat/lib/latin1tab.h
+++ b/xml/expat/lib/latin1tab.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/xml/expat/lib/utf8tab.h b/xml/expat/lib/utf8tab.h
index 9e3b6b8..7bb3e77 100644
--- a/xml/expat/lib/utf8tab.h
+++ b/xml/expat/lib/utf8tab.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 
diff --git a/xml/expat/lib/winconfig.h b/xml/expat/lib/winconfig.h
index 77b1ece..c1b791d 100644
--- a/xml/expat/lib/winconfig.h
+++ b/xml/expat/lib/winconfig.h
@@ -5,8 +5,6 @@
 ** This is free software. You are permitted to copy, distribute, or modify
 ** it under the terms of the MIT/X license (contained in the COPYING file
 ** with this distribution.)
-**
-**
 */
 
 #ifndef WINCONFIG_H
@@ -21,7 +19,12 @@
 
 #define XML_NS 1
 #define XML_DTD 1
-#define XML_BYTE_ORDER 12
 #define XML_CONTEXT_BYTES 1024
 
+/* we will assume all Windows platforms are little endian */
+#define BYTEORDER 1234
+
+/* Windows has memmove() available. */
+#define HAVE_MEMMOVE
+
 #endif /* ndef WINCONFIG_H */
diff --git a/xml/expat/lib/xml.dsp b/xml/expat/lib/xml.dsp
index 1c5b067..c8772f0 100644
--- a/xml/expat/lib/xml.dsp
+++ b/xml/expat/lib/xml.dsp
@@ -43,7 +43,7 @@
 # PROP Intermediate_Dir "LibR"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D VERSION=\"expat_1.95.2\" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "COMPILED_FROM_DSP" /D "XML_STATIC" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
 BSC32=bscmake.exe
@@ -67,7 +67,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /EHsc /c
-# ADD CPP /nologo /MDd /W3 /Zi /Od /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D VERSION=\"expat_1.95.2\" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /EHsc /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "COMPILED_FROM_DSP" /D "XML_STATIC" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /EHsc /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
 BSC32=bscmake.exe
@@ -90,7 +90,7 @@
 # PROP Intermediate_Dir "x64\LibR"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D VERSION=\"expat_1.95.2\" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "COMPILED_FROM_DSP" /D "XML_STATIC" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
 BSC32=bscmake.exe
@@ -114,7 +114,7 @@
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /EHsc /c
-# ADD CPP /nologo /MDd /W3 /Zi /Od /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D VERSION=\"expat_1.95.2\" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /EHsc /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "COMPILED_FROM_DSP" /D "XML_STATIC" /Fo"$(INTDIR)\" /Fd"$(OUTDIR)\xml" /FD /EHsc /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
 BSC32=bscmake.exe
@@ -171,10 +171,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=.\config.h
-# End Source File
-# Begin Source File
-
 SOURCE=.\expat.h
 # End Source File
 # Begin Source File
@@ -195,6 +191,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=.\winconfig.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\xmlrole.h
 # End Source File
 # Begin Source File
@@ -206,104 +206,6 @@
 SOURCE=.\xmltok_impl.h
 # End Source File
 # End Group
-# Begin Group "Generated Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\expat.h.in
-
-!IF  "$(CFG)" == "xml - Win32 Release"
-
-# Begin Custom Build - Creating expat.h from expat.h.in 
-InputPath=.\expat.h.in
-
-".\expat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\expat.h.in > .\expat.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - Win32 Debug"
-
-# Begin Custom Build - Creating expat.h from expat.h.in 
-InputPath=.\expat.h.in
-
-".\expat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\expat.h.in > .\expat.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - x64 Release"
-
-# Begin Custom Build - Creating expat.h from expat.h.in 
-InputPath=.\expat.h.in
-
-".\expat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\expat.h.in > .\expat.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - x64 Debug"
-
-# Begin Custom Build - Creating expat.h from expat.h.in 
-InputPath=.\expat.h.in
-
-".\expat.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\expat.h.in > .\expat.h
-	
-# End Custom Build
-
-!ENDIF 
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\winconfig.h
-
-!IF  "$(CFG)" == "xml - Win32 Release"
-
-# Begin Custom Build - Creating config.h from winconfig.h 
-InputPath=.\winconfig.h
-
-".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\winconfig.h > .\config.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - Win32 Debug"
-
-# Begin Custom Build - Creating config.h from winconfig.h 
-InputPath=.\winconfig.h
-
-".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\winconfig.h > .\config.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - x64 Release"
-
-# Begin Custom Build - Creating config.h from winconfig.h 
-InputPath=.\winconfig.h
-
-".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\winconfig.h > .\config.h
-	
-# End Custom Build
-
-!ELSEIF  "$(CFG)" == "xml - x64 Debug"
-
-# Begin Custom Build - Creating config.h from winconfig.h 
-InputPath=.\winconfig.h
-
-".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
-	type .\winconfig.h > .\config.h
-	
-# End Custom Build
-
-!ENDIF 
-
-# End Source File
-# End Group
 # Begin Source File
 
 SOURCE=.\ReadMe.txt
diff --git a/xml/expat/lib/xmlparse.c b/xml/expat/lib/xmlparse.c
index 43eb307..4a86edc 100644
--- a/xml/expat/lib/xmlparse.c
+++ b/xml/expat/lib/xmlparse.c
@@ -1,37 +1,23 @@
-/*
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
-static char RCSId[]
-  = "$Header: /home/cvs/apr-util/xml/expat/lib/xmlparse.c,v 1.4 2001/08/30 05:44:18 wrowe Exp $";
+#include <stddef.h>
+#include <string.h>                     /* memset(), memcpy() */
+
+#define XML_BUILDING_EXPAT 1
 
 #ifdef COMPILED_FROM_DSP
-#  include "winconfig.h"
-#  define XMLPARSEAPI __declspec(dllexport)
-#  include "expat.h"
-#  undef XMLPARSEAPI
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
 #else
-#include <config.h>
-
-#ifdef HAVE_STRING_H
-#  include <string.h>
-#endif
-
-#ifndef __CYGWIN__
-#ifdef __declspec
-#  define XMLPARSEAPI __declspec(dllexport)
-#endif
-#endif
-
-#include "expat.h"
-
-#ifdef __declspec
-#  undef XMLPARSEAPI
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
 #endif
 #endif /* ndef COMPILED_FROM_DSP */
 
-#include <stddef.h>
+#include "expat.h"
 
 #ifdef XML_UNICODE
 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
@@ -62,15 +48,36 @@
 
 #endif
 
+#ifdef XML_UNICODE
+
 #ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) L ## x
+#define XML_T(x) (const wchar_t)x
+#define XML_L(x) L ## x
 #else
+#define XML_T(x) (const unsigned short)x
+#define XML_L(x) x
+#endif
+
+#else
+
 #define XML_T(x) x
+#define XML_L(x) x
+
 #endif
 
 /* Round up n to be a multiple of sz, where sz is a power of 2. */
 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
 
+/* Handle the case where memmove() doesn't exist. */
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#error memmove does not exist on this platform, nor is a substitute available
+#endif /* HAVE_BCOPY */
+#endif /* HAVE_MEMMOVE */
+
+#include "internal.h"
 #include "xmltok.h"
 #include "xmlrole.h"
 
@@ -82,12 +89,37 @@
 
 typedef struct {
   NAMED **v;
+  unsigned char power;
   size_t size;
   size_t used;
-  size_t usedLim;
-  XML_Memory_Handling_Suite *mem;
+  const XML_Memory_Handling_Suite *mem;
 } HASH_TABLE;
 
+/* Basic character hash algorithm, taken from Python's string hash:
+   h = h * 1000003 ^ character, the constant being a prime number.
+
+*/
+#ifdef XML_UNICODE
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned short)(c))
+#else
+#define CHAR_HASH(h, c) \
+  (((h) * 0xF4243) ^ (unsigned char)(c))
+#endif
+
+/* For probing (after a collision) we need a step size relative prime
+   to the hash table size, which is a power of 2. We use double-hashing,
+   since we can calculate a second hash value cheaply by taking those bits
+   of the first hash value that were discarded (masked out) when the table
+   index was calculated: index = hash & mask, where mask = table->size - 1.
+   We limit the maximum step size to table->size / 4 (mask >> 2) and make
+   it odd, since odd numbers are always relative prime to a power of 2.
+*/
+#define SECOND_HASH(hash, mask, power) \
+  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
+#define PROBE_STEP(hash, mask, power) \
+  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
+
 typedef struct {
   NAMED **p;
   NAMED **end;
@@ -96,6 +128,7 @@
 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
 #define INIT_DATA_BUF_SIZE 1024
 #define INIT_ATTS_SIZE 16
+#define INIT_ATTS_VERSION 0xFFFFFFFF
 #define INIT_BLOCK_SIZE 1024
 #define INIT_BUFFER_SIZE 1024
 
@@ -119,16 +152,32 @@
 typedef struct {
   const XML_Char *str;
   const XML_Char *localPart;
+  const XML_Char *prefix;
+  int strLen;
   int uriLen;
+  int prefixLen;
 } TAG_NAME;
 
+/* TAG represents an open element.
+   The name of the element is stored in both the document and API
+   encodings.  The memory buffer 'buf' is a separately-allocated
+   memory area which stores the name.  During the XML_Parse()/
+   XMLParseBuffer() when the element is open, the memory for the 'raw'
+   version of the name (in the document encoding) is shared with the
+   document buffer.  If the element is open across calls to
+   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
+   contain the 'raw' name as well.
+
+   A parser re-uses these structures, maintaining a list of allocated
+   TAG objects in a free list.
+*/
 typedef struct tag {
-  struct tag *parent;
-  const char *rawName;
+  struct tag *parent;           /* parent of this element */
+  const char *rawName;          /* tagName in the original encoding */
   int rawNameLength;
-  TAG_NAME name;
-  char *buf;
-  char *bufEnd;
+  TAG_NAME name;                /* tagName in the API encoding */
+  char *buf;                    /* buffer for name components */
+  char *bufEnd;                 /* end of the buffer */
   BINDING *bindings;
 } TAG;
 
@@ -140,20 +189,23 @@
   const XML_Char *base;
   const XML_Char *publicId;
   const XML_Char *notation;
-  char open;
-  char is_param;
+  XML_Bool open;
+  XML_Bool is_param;
+  XML_Bool is_internal; /* true if declared in internal subset outside PE */
 } ENTITY;
 
 typedef struct {
-  enum XML_Content_Type		type;
-  enum XML_Content_Quant	quant;
-  const XML_Char *		name;
-  int				firstchild;
-  int				lastchild;
-  int				childcnt;
-  int				nextsib;
+  enum XML_Content_Type         type;
+  enum XML_Content_Quant        quant;
+  const XML_Char *              name;
+  int                           firstchild;
+  int                           lastchild;
+  int                           childcnt;
+  int                           nextsib;
 } CONTENT_SCAFFOLD;
 
+#define INIT_SCAFFOLD_ELEMENTS 32
+
 typedef struct block {
   struct block *next;
   int size;
@@ -166,25 +218,31 @@
   const XML_Char *end;
   XML_Char *ptr;
   XML_Char *start;
-  XML_Memory_Handling_Suite *mem;
+  const XML_Memory_Handling_Suite *mem;
 } STRING_POOL;
 
 /* The XML_Char before the name is used to determine whether
-an attribute has been specified. */
+   an attribute has been specified. */
 typedef struct attribute_id {
   XML_Char *name;
   PREFIX *prefix;
-  char maybeTokenized;
-  char xmlns;
+  XML_Bool maybeTokenized;
+  XML_Bool xmlns;
 } ATTRIBUTE_ID;
 
 typedef struct {
   const ATTRIBUTE_ID *id;
-  char isCdata;
+  XML_Bool isCdata;
   const XML_Char *value;
 } DEFAULT_ATTRIBUTE;
 
 typedef struct {
+  unsigned long version;
+  unsigned long hash;
+  const XML_Char *uriName;
+} NS_ATT;
+
+typedef struct {
   const XML_Char *name;
   PREFIX *prefix;
   const ATTRIBUTE_ID *idAtt;
@@ -199,14 +257,21 @@
   HASH_TABLE attributeIds;
   HASH_TABLE prefixes;
   STRING_POOL pool;
-  int complete;
-  int standalone;
+  STRING_POOL entityValuePool;
+  /* false once a parameter entity reference has been skipped */
+  XML_Bool keepProcessing;
+  /* true once an internal or external PE reference has been encountered;
+     this includes the reference to an external subset */
+  XML_Bool hasParamEntityRefs;
+  XML_Bool standalone;
 #ifdef XML_DTD
+  /* indicates if external PE has been read */
+  XML_Bool paramEntityRead;
   HASH_TABLE paramEntities;
 #endif /* XML_DTD */
   PREFIX defaultPrefix;
   /* === scaffolding for building content model === */
-  int in_eldecl;
+  XML_Bool in_eldecl;
   CONTENT_SCAFFOLD *scaffold;
   unsigned contentStringLen;
   unsigned scaffSize;
@@ -222,10 +287,10 @@
   ENTITY *entity;
 } OPEN_INTERNAL_ENTITY;
 
-typedef enum XML_Error Processor(XML_Parser parser,
-				 const char *start,
-				 const char *end,
-				 const char **endPtr);
+typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
+                                         const char *start,
+                                         const char *end,
+                                         const char **endPtr);
 
 static Processor prologProcessor;
 static Processor prologInitProcessor;
@@ -233,6 +298,10 @@
 static Processor cdataSectionProcessor;
 #ifdef XML_DTD
 static Processor ignoreSectionProcessor;
+static Processor externalParEntProcessor;
+static Processor externalParEntInitProcessor;
+static Processor entityValueProcessor;
+static Processor entityValueInitProcessor;
 #endif /* XML_DTD */
 static Processor epilogProcessor;
 static Processor errorProcessor;
@@ -244,94 +313,118 @@
 static enum XML_Error
 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
 static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+               const char *, const char *);
 static enum XML_Error
 initializeEncoding(XML_Parser parser);
 static enum XML_Error
 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
-	 const char *end, int tok, const char *next, const char **nextPtr);
+         const char *end, int tok, const char *next, const char **nextPtr);
 static enum XML_Error
 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
 static enum XML_Error
 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-	  const char *start, const char *end, const char **endPtr);
+          const char *start, const char *end, const char **endPtr);
 static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+               const char *end, const char **nextPtr);
 #ifdef XML_DTD
 static enum XML_Error
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
+                const char *end, const char **nextPtr);
 #endif /* XML_DTD */
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
-				TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
 
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+           const XML_Char *uri, BINDING **bindingsPtr);
 static int
 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
-		int isCdata, int isId, const XML_Char *dfltValue,
-		XML_Parser parser);
-
+                XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
+                XML_Parser parser);
 static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-		    STRING_POOL *);
+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                    const char *, const char *, STRING_POOL *);
 static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-		    STRING_POOL *);
+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
+                     const char *, const char *, STRING_POOL *);
 static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
+               const char *end);
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
 static enum XML_Error
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
+                 const char *end);
 static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                            const char *start, const char *end);
 static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
 static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
+              const char *end);
 
-static const XML_Char *getContext(XML_Parser parser);
-static int setContext(XML_Parser parser, const XML_Char *context);
-static void normalizePublicId(XML_Char *s);
-static int dtdInit(DTD *, XML_Parser parser);
+static const XML_Char * getContext(XML_Parser parser);
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context);
 
-static void dtdDestroy(DTD *, XML_Parser parser);
+static void FASTCALL normalizePublicId(XML_Char *s);
 
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
+static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
+/* do not call if parentParser != NULL */
+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
+static int
+copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
 
-static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
-			   XML_Parser parser);
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void FASTCALL
+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL hashTableClear(HASH_TABLE *);
+static void FASTCALL hashTableDestroy(HASH_TABLE *);
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
 
-#ifdef XML_DTD
-static void dtdSwap(DTD *, DTD *);
-#endif /* XML_DTD */
+static void FASTCALL
+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
+static void FASTCALL poolClear(STRING_POOL *);
+static void FASTCALL poolDestroy(STRING_POOL *);
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+           const char *ptr, const char *end);
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                const char *ptr, const char *end);
+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s);
 
-static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static int FASTCALL nextScaffoldPart(XML_Parser parser);
+static XML_Content * build_model(XML_Parser parser);
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser, const ENCODING *enc,
+               const char *ptr, const char *end);
 
-static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
-
-static void hashTableDestroy(HASH_TABLE *);
-static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
-static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
-static void poolClear(STRING_POOL *);
-static void poolDestroy(STRING_POOL *);
-static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-			    const char *ptr, const char *end);
-static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-				  const char *ptr, const char *end);
-
-static int poolGrow(STRING_POOL *pool);
-
-static int nextScaffoldPart(XML_Parser parser);
-static XML_Content *build_model(XML_Parser parser);
-
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
-static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
-				     const ENCODING *enc,
-				     const char *ptr,
-				     const char *end);
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd);
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName);
 
 #define poolStart(pool) ((pool)->start)
 #define poolEnd(pool) ((pool)->ptr)
@@ -345,12 +438,13 @@
    ? 0 \
    : ((*((pool)->ptr)++ = c), 1))
 
-typedef struct {
-  /* The first member must be userData so that the XML_GetUserData macro works. */
+struct XML_ParserStruct {
+  /* The first member must be userData so that the XML_GetUserData
+     macro works. */
   void *m_userData;
   void *m_handlerArg;
   char *m_buffer;
-  XML_Memory_Handling_Suite m_mem;
+  const XML_Memory_Handling_Suite m_mem;
   /* first character to be parsed */
   const char *m_bufferPtr;
   /* past last character to be parsed */
@@ -377,7 +471,8 @@
   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
   XML_NotStandaloneHandler m_notStandaloneHandler;
   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
-  void *m_externalEntityRefHandlerArg;
+  XML_Parser m_externalEntityRefHandlerArg;
+  XML_SkippedEntityHandler m_skippedEntityHandler;
   XML_UnknownEncodingHandler m_unknownEncodingHandler;
   XML_ElementDeclHandler m_elementDeclHandler;
   XML_AttlistDeclHandler m_attlistDeclHandler;
@@ -387,8 +482,8 @@
   INIT_ENCODING m_initEncoding;
   const ENCODING *m_internalEncoding;
   const XML_Char *m_protocolEncodingName;
-  int m_ns;
-  int m_ns_triplets;
+  XML_Bool m_ns;
+  XML_Bool m_ns_triplets;
   void *m_unknownEncodingMem;
   void *m_unknownEncodingData;
   void *m_unknownEncodingHandlerData;
@@ -400,7 +495,7 @@
   const char *m_eventEndPtr;
   const char *m_positionPtr;
   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
-  int m_defaultExpandInternalEntities;
+  XML_Bool m_defaultExpandInternalEntities;
   int m_tagLevel;
   ENTITY *m_declEntity;
   const XML_Char *m_doctypeName;
@@ -411,9 +506,9 @@
   const XML_Char *m_declNotationPublicId;
   ELEMENT_TYPE *m_declElementType;
   ATTRIBUTE_ID *m_declAttributeId;
-  char m_declAttributeIsCdata;
-  char m_declAttributeIsId;
-  DTD m_dtd;
+  XML_Bool m_declAttributeIsCdata;
+  XML_Bool m_declAttributeIsId;
+  DTD *m_dtd;
   const XML_Char *m_curBase;
   TAG *m_tagStack;
   TAG *m_freeTagList;
@@ -423,308 +518,446 @@
   int m_nSpecifiedAtts;
   int m_idAttIndex;
   ATTRIBUTE *m_atts;
+  NS_ATT *m_nsAtts;
+  unsigned long m_nsAttsVersion;
+  unsigned char m_nsAttsPower;
   POSITION m_position;
   STRING_POOL m_tempPool;
   STRING_POOL m_temp2Pool;
   char *m_groupConnector;
-  unsigned m_groupSize;
-  int m_hadExternalDoctype;
+  unsigned int m_groupSize;
   XML_Char m_namespaceSeparator;
-#ifdef XML_DTD
-  enum XML_ParamEntityParsing m_paramEntityParsing;
   XML_Parser m_parentParser;
-#endif
-} Parser;
-
-#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
-#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
-#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
-
-#define userData (((Parser *)parser)->m_userData)
-#define handlerArg (((Parser *)parser)->m_handlerArg)
-#define startElementHandler (((Parser *)parser)->m_startElementHandler)
-#define endElementHandler (((Parser *)parser)->m_endElementHandler)
-#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
-#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
-#define commentHandler (((Parser *)parser)->m_commentHandler)
-#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
-#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
-#define defaultHandler (((Parser *)parser)->m_defaultHandler)
-#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
-#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
-#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
-#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
-#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
-#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
-#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
-#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
-#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
-#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
-#define encoding (((Parser *)parser)->m_encoding)
-#define initEncoding (((Parser *)parser)->m_initEncoding)
-#define internalEncoding (((Parser *)parser)->m_internalEncoding)
-#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
-#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
-  (((Parser *)parser)->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
-#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
-#define ns (((Parser *)parser)->m_ns)
-#define ns_triplets (((Parser *)parser)->m_ns_triplets)
-#define prologState (((Parser *)parser)->m_prologState)
-#define processor (((Parser *)parser)->m_processor)
-#define errorCode (((Parser *)parser)->m_errorCode)
-#define eventPtr (((Parser *)parser)->m_eventPtr)
-#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
-#define positionPtr (((Parser *)parser)->m_positionPtr)
-#define position (((Parser *)parser)->m_position)
-#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
-#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
-#define tagLevel (((Parser *)parser)->m_tagLevel)
-#define buffer (((Parser *)parser)->m_buffer)
-#define bufferPtr (((Parser *)parser)->m_bufferPtr)
-#define bufferEnd (((Parser *)parser)->m_bufferEnd)
-#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
-#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
-#define bufferLim (((Parser *)parser)->m_bufferLim)
-#define dataBuf (((Parser *)parser)->m_dataBuf)
-#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
-#define dtd (((Parser *)parser)->m_dtd)
-#define curBase (((Parser *)parser)->m_curBase)
-#define declEntity (((Parser *)parser)->m_declEntity)
-#define doctypeName (((Parser *)parser)->m_doctypeName)
-#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
-#define doctypePubid (((Parser *)parser)->m_doctypePubid)
-#define declAttributeType (((Parser *)parser)->m_declAttributeType)
-#define declNotationName (((Parser *)parser)->m_declNotationName)
-#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
-#define declElementType (((Parser *)parser)->m_declElementType)
-#define declAttributeId (((Parser *)parser)->m_declAttributeId)
-#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
-#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
-#define freeTagList (((Parser *)parser)->m_freeTagList)
-#define freeBindingList (((Parser *)parser)->m_freeBindingList)
-#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
-#define tagStack (((Parser *)parser)->m_tagStack)
-#define atts (((Parser *)parser)->m_atts)
-#define attsSize (((Parser *)parser)->m_attsSize)
-#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
-#define idAttIndex (((Parser *)parser)->m_idAttIndex)
-#define tempPool (((Parser *)parser)->m_tempPool)
-#define temp2Pool (((Parser *)parser)->m_temp2Pool)
-#define groupConnector (((Parser *)parser)->m_groupConnector)
-#define groupSize (((Parser *)parser)->m_groupSize)
-#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
-#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
 #ifdef XML_DTD
-#define parentParser (((Parser *)parser)->m_parentParser)
-#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+  XML_Bool m_isParamEntity;
+  XML_Bool m_useForeignDTD;
+  enum XML_ParamEntityParsing m_paramEntityParsing;
+#endif
+};
+
+#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (parser->m_mem.free_fcn((p)))
+
+#define userData (parser->m_userData)
+#define handlerArg (parser->m_handlerArg)
+#define startElementHandler (parser->m_startElementHandler)
+#define endElementHandler (parser->m_endElementHandler)
+#define characterDataHandler (parser->m_characterDataHandler)
+#define processingInstructionHandler \
+        (parser->m_processingInstructionHandler)
+#define commentHandler (parser->m_commentHandler)
+#define startCdataSectionHandler \
+        (parser->m_startCdataSectionHandler)
+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
+#define defaultHandler (parser->m_defaultHandler)
+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler \
+        (parser->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (parser->m_notationDeclHandler)
+#define startNamespaceDeclHandler \
+        (parser->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (parser->m_notStandaloneHandler)
+#define externalEntityRefHandler \
+        (parser->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg \
+        (parser->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler \
+        (parser->m_internalEntityRefHandler)
+#define skippedEntityHandler (parser->m_skippedEntityHandler)
+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
+#define elementDeclHandler (parser->m_elementDeclHandler)
+#define attlistDeclHandler (parser->m_attlistDeclHandler)
+#define entityDeclHandler (parser->m_entityDeclHandler)
+#define xmlDeclHandler (parser->m_xmlDeclHandler)
+#define encoding (parser->m_encoding)
+#define initEncoding (parser->m_initEncoding)
+#define internalEncoding (parser->m_internalEncoding)
+#define unknownEncodingMem (parser->m_unknownEncodingMem)
+#define unknownEncodingData (parser->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+  (parser->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
+#define protocolEncodingName (parser->m_protocolEncodingName)
+#define ns (parser->m_ns)
+#define ns_triplets (parser->m_ns_triplets)
+#define prologState (parser->m_prologState)
+#define processor (parser->m_processor)
+#define errorCode (parser->m_errorCode)
+#define eventPtr (parser->m_eventPtr)
+#define eventEndPtr (parser->m_eventEndPtr)
+#define positionPtr (parser->m_positionPtr)
+#define position (parser->m_position)
+#define openInternalEntities (parser->m_openInternalEntities)
+#define defaultExpandInternalEntities \
+        (parser->m_defaultExpandInternalEntities)
+#define tagLevel (parser->m_tagLevel)
+#define buffer (parser->m_buffer)
+#define bufferPtr (parser->m_bufferPtr)
+#define bufferEnd (parser->m_bufferEnd)
+#define parseEndByteIndex (parser->m_parseEndByteIndex)
+#define parseEndPtr (parser->m_parseEndPtr)
+#define bufferLim (parser->m_bufferLim)
+#define dataBuf (parser->m_dataBuf)
+#define dataBufEnd (parser->m_dataBufEnd)
+#define _dtd (parser->m_dtd)
+#define curBase (parser->m_curBase)
+#define declEntity (parser->m_declEntity)
+#define doctypeName (parser->m_doctypeName)
+#define doctypeSysid (parser->m_doctypeSysid)
+#define doctypePubid (parser->m_doctypePubid)
+#define declAttributeType (parser->m_declAttributeType)
+#define declNotationName (parser->m_declNotationName)
+#define declNotationPublicId (parser->m_declNotationPublicId)
+#define declElementType (parser->m_declElementType)
+#define declAttributeId (parser->m_declAttributeId)
+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
+#define declAttributeIsId (parser->m_declAttributeIsId)
+#define freeTagList (parser->m_freeTagList)
+#define freeBindingList (parser->m_freeBindingList)
+#define inheritedBindings (parser->m_inheritedBindings)
+#define tagStack (parser->m_tagStack)
+#define atts (parser->m_atts)
+#define attsSize (parser->m_attsSize)
+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
+#define idAttIndex (parser->m_idAttIndex)
+#define nsAtts (parser->m_nsAtts)
+#define nsAttsVersion (parser->m_nsAttsVersion)
+#define nsAttsPower (parser->m_nsAttsPower)
+#define tempPool (parser->m_tempPool)
+#define temp2Pool (parser->m_temp2Pool)
+#define groupConnector (parser->m_groupConnector)
+#define groupSize (parser->m_groupSize)
+#define namespaceSeparator (parser->m_namespaceSeparator)
+#define parentParser (parser->m_parentParser)
+#ifdef XML_DTD
+#define isParamEntity (parser->m_isParamEntity)
+#define useForeignDTD (parser->m_useForeignDTD)
+#define paramEntityParsing (parser->m_paramEntityParsing)
 #endif /* XML_DTD */
 
-#ifdef COMPILED_FROM_DSP
-BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
-  return TRUE;
-}
-#endif /* def COMPILED_FROM_DSP */
+#ifdef XML_DTD
+#define parsing \
+  (parentParser \
+    ? \
+    (isParamEntity \
+      ? \
+      (processor != externalParEntInitProcessor) \
+      : \
+      (processor != externalEntityInitProcessor)) \
+    : \
+    (processor != prologInitProcessor))
+#else
+#define parsing \
+  (parentParser \
+    ? \
+    (processor != externalEntityInitProcessor) \
+    : \
+    (processor != prologInitProcessor))
+#endif /* XML_DTD */
 
-#ifdef _MSC_VER
-#ifdef _DEBUG
-Parser *asParser(XML_Parser parser)
-{
-  return parser;
-}
-#endif
-#endif
-
-XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+XML_Parser XMLCALL
+XML_ParserCreate(const XML_Char *encodingName)
 {
   return XML_ParserCreate_MM(encodingName, NULL, NULL);
 }
 
-XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+XML_Parser XMLCALL
+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
 {
   XML_Char tmp[2];
   *tmp = nsSep;
   return XML_ParserCreate_MM(encodingName, NULL, tmp);
 }
 
-XML_Parser
-XML_ParserCreate_MM(const XML_Char *encodingName,
-		    const XML_Memory_Handling_Suite *memsuite,
-		    const XML_Char *nameSep) {
-  
-  XML_Parser parser;
-  static
-  const XML_Char implicitContext[] = {
-    XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
-    XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
-    XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
-    XML_T('.'), XML_T('w'), XML_T('3'),
-    XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
-    XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
-    XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
-    XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
-    XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
-    XML_T('\0')
-  };
+static const XML_Char implicitContext[] = {
+  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
+  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+};
 
+XML_Parser XMLCALL
+XML_ParserCreate_MM(const XML_Char *encodingName,
+                    const XML_Memory_Handling_Suite *memsuite,
+                    const XML_Char *nameSep)
+{
+  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
+  if (parser != NULL && ns) {
+    /* implicit context only set for root parser, since child
+       parsers (i.e. external entity parsers) will inherit it
+    */
+    if (!setContext(parser, implicitContext)) {
+      XML_ParserFree(parser);
+      return NULL;
+    }
+  }
+  return parser;
+}
+
+static XML_Parser
+parserCreate(const XML_Char *encodingName,
+             const XML_Memory_Handling_Suite *memsuite,
+             const XML_Char *nameSep,
+             DTD *dtd)
+{
+  XML_Parser parser;
 
   if (memsuite) {
     XML_Memory_Handling_Suite *mtemp;
-    parser = memsuite->malloc_fcn(sizeof(Parser));
-    mtemp = &(((Parser *) parser)->m_mem);
-    mtemp->malloc_fcn = memsuite->malloc_fcn;
-    mtemp->realloc_fcn = memsuite->realloc_fcn;
-    mtemp->free_fcn = memsuite->free_fcn;
+    parser = (XML_Parser)
+      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = memsuite->malloc_fcn;
+      mtemp->realloc_fcn = memsuite->realloc_fcn;
+      mtemp->free_fcn = memsuite->free_fcn;
+    }
   }
   else {
     XML_Memory_Handling_Suite *mtemp;
-    parser = malloc(sizeof(Parser));
-    mtemp = &(((Parser *) parser)->m_mem);
-    mtemp->malloc_fcn = malloc;
-    mtemp->realloc_fcn = realloc;
-    mtemp->free_fcn = free;
+    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
+    if (parser != NULL) {
+      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
+      mtemp->malloc_fcn = malloc;
+      mtemp->realloc_fcn = realloc;
+      mtemp->free_fcn = free;
+    }
   }
 
   if (!parser)
     return parser;
-  processor = prologInitProcessor;
-  XmlPrologStateInit(&prologState);
-  userData = 0;
-  handlerArg = 0;
-  startElementHandler = 0;
-  endElementHandler = 0;
-  characterDataHandler = 0;
-  processingInstructionHandler = 0;
-  commentHandler = 0;
-  startCdataSectionHandler = 0;
-  endCdataSectionHandler = 0;
-  defaultHandler = 0;
-  startDoctypeDeclHandler = 0;
-  endDoctypeDeclHandler = 0;
-  unparsedEntityDeclHandler = 0;
-  notationDeclHandler = 0;
-  startNamespaceDeclHandler = 0;
-  endNamespaceDeclHandler = 0;
-  notStandaloneHandler = 0;
-  externalEntityRefHandler = 0;
-  externalEntityRefHandlerArg = parser;
-  unknownEncodingHandler = 0;
-  elementDeclHandler = 0;
-  attlistDeclHandler = 0;
-  entityDeclHandler = 0;
-  xmlDeclHandler = 0;
-  buffer = 0;
-  bufferPtr = 0;
-  bufferEnd = 0;
-  parseEndByteIndex = 0;
-  parseEndPtr = 0;
-  bufferLim = 0;
-  declElementType = 0;
-  declAttributeId = 0;
-  declEntity = 0;
-  doctypeName = 0;
-  doctypeSysid = 0;
-  doctypePubid = 0;
-  declAttributeType = 0;
-  declNotationName = 0;
-  declNotationPublicId = 0;
-  memset(&position, 0, sizeof(POSITION));
-  errorCode = XML_ERROR_NONE;
-  eventPtr = 0;
-  eventEndPtr = 0;
-  positionPtr = 0;
-  openInternalEntities = 0;
-  tagLevel = 0;
-  tagStack = 0;
-  freeTagList = 0;
-  freeBindingList = 0;
-  inheritedBindings = 0;
+
+  buffer = NULL;
+  bufferLim = NULL;
+
   attsSize = INIT_ATTS_SIZE;
-  atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
-  nSpecifiedAtts = 0;
-  dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
-  groupSize = 0;
-  groupConnector = 0;
-  hadExternalDoctype = 0;
-  unknownEncodingMem = 0;
-  unknownEncodingRelease = 0;
-  unknownEncodingData = 0;
-  unknownEncodingHandlerData = 0;
-  namespaceSeparator = '!';
-#ifdef XML_DTD
-  parentParser = 0;
-  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
-  ns = 0;
-  ns_triplets = 0;
-  poolInit(&tempPool, &(((Parser *) parser)->m_mem));
-  poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
-  protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
-  curBase = 0;
-  if (!dtdInit(&dtd, parser) || !atts || !dataBuf
-      || (encodingName && !protocolEncodingName)) {
-    XML_ParserFree(parser);
-    return 0;
+  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
+  if (atts == NULL) {
+    FREE(parser);
+    return NULL;
+  }
+  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  if (dataBuf == NULL) {
+    FREE(atts);
+    FREE(parser);
+    return NULL;
   }
   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
 
-  if (nameSep) {
-    XmlInitEncodingNS(&initEncoding, &encoding, 0);
-    ns = 1;
-    internalEncoding = XmlGetInternalEncodingNS();
-    namespaceSeparator = *nameSep;
-
-    if (! setContext(parser, implicitContext)) {
-      XML_ParserFree(parser);
-      return 0;
+  if (dtd)
+    _dtd = dtd;
+  else {
+    _dtd = dtdCreate(&parser->m_mem);
+    if (_dtd == NULL) {
+      FREE(dataBuf);
+      FREE(atts);
+      FREE(parser);
+      return NULL;
     }
   }
+
+  freeBindingList = NULL;
+  freeTagList = NULL;
+
+  groupSize = 0;
+  groupConnector = NULL;
+
+  unknownEncodingHandler = NULL;
+  unknownEncodingHandlerData = NULL;
+
+  namespaceSeparator = '!';
+  ns = XML_FALSE;
+  ns_triplets = XML_FALSE;
+
+  nsAtts = NULL;
+  nsAttsVersion = 0;
+  nsAttsPower = 0;
+
+  poolInit(&tempPool, &(parser->m_mem));
+  poolInit(&temp2Pool, &(parser->m_mem));
+  parserInit(parser, encodingName);
+
+  if (encodingName && !protocolEncodingName) {
+    XML_ParserFree(parser);
+    return NULL;
+  }
+
+  if (nameSep) {
+    ns = XML_TRUE;
+    internalEncoding = XmlGetInternalEncodingNS();
+    namespaceSeparator = *nameSep;
+  }
   else {
-    XmlInitEncoding(&initEncoding, &encoding, 0);
     internalEncoding = XmlGetInternalEncoding();
   }
 
   return parser;
-}  /* End XML_ParserCreate_MM */
+}
 
-int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+static void
+parserInit(XML_Parser parser, const XML_Char *encodingName)
 {
-  if (!encodingName)
-    protocolEncodingName = 0;
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  protocolEncodingName = (encodingName != NULL
+                          ? poolCopyString(&tempPool, encodingName)
+                          : NULL);
+  curBase = NULL;
+  XmlInitEncoding(&initEncoding, &encoding, 0);
+  userData = NULL;
+  handlerArg = NULL;
+  startElementHandler = NULL;
+  endElementHandler = NULL;
+  characterDataHandler = NULL;
+  processingInstructionHandler = NULL;
+  commentHandler = NULL;
+  startCdataSectionHandler = NULL;
+  endCdataSectionHandler = NULL;
+  defaultHandler = NULL;
+  startDoctypeDeclHandler = NULL;
+  endDoctypeDeclHandler = NULL;
+  unparsedEntityDeclHandler = NULL;
+  notationDeclHandler = NULL;
+  startNamespaceDeclHandler = NULL;
+  endNamespaceDeclHandler = NULL;
+  notStandaloneHandler = NULL;
+  externalEntityRefHandler = NULL;
+  externalEntityRefHandlerArg = parser;
+  skippedEntityHandler = NULL;
+  elementDeclHandler = NULL;
+  attlistDeclHandler = NULL;
+  entityDeclHandler = NULL;
+  xmlDeclHandler = NULL;
+  bufferPtr = buffer;
+  bufferEnd = buffer;
+  parseEndByteIndex = 0;
+  parseEndPtr = NULL;
+  declElementType = NULL;
+  declAttributeId = NULL;
+  declEntity = NULL;
+  doctypeName = NULL;
+  doctypeSysid = NULL;
+  doctypePubid = NULL;
+  declAttributeType = NULL;
+  declNotationName = NULL;
+  declNotationPublicId = NULL;
+  declAttributeIsCdata = XML_FALSE;
+  declAttributeIsId = XML_FALSE;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = NULL;
+  eventEndPtr = NULL;
+  positionPtr = NULL;
+  openInternalEntities = 0;
+  defaultExpandInternalEntities = XML_TRUE;
+  tagLevel = 0;
+  tagStack = NULL;
+  inheritedBindings = NULL;
+  nSpecifiedAtts = 0;
+  unknownEncodingMem = NULL;
+  unknownEncodingRelease = NULL;
+  unknownEncodingData = NULL;
+  parentParser = NULL;
+#ifdef XML_DTD
+  isParamEntity = XML_FALSE;
+  useForeignDTD = XML_FALSE;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+/* moves list of bindings to freeBindingList */
+static void FASTCALL
+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
+{
+  while (bindings) {
+    BINDING *b = bindings;
+    bindings = bindings->nextTagBinding;
+    b->nextTagBinding = freeBindingList;
+    freeBindingList = b;
+  }
+}
+
+XML_Bool XMLCALL
+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
+{
+  TAG *tStk;
+  if (parentParser)
+    return XML_FALSE;
+  /* move tagStack to freeTagList */
+  tStk = tagStack;
+  while (tStk) {
+    TAG *tag = tStk;
+    tStk = tStk->parent;
+    tag->parent = freeTagList;
+    moveToFreeBindingList(parser, tag->bindings);
+    tag->bindings = NULL;
+    freeTagList = tag;
+  }
+  moveToFreeBindingList(parser, inheritedBindings);
+  FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  poolClear(&tempPool);
+  poolClear(&temp2Pool);
+  parserInit(parser, encodingName);
+  dtdReset(_dtd, &parser->m_mem);
+  return setContext(parser, implicitContext);
+}
+
+enum XML_Status XMLCALL
+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
+     XXX There's no way for the caller to determine which of the
+     XXX possible error cases caused the XML_STATUS_ERROR return.
+  */
+  if (parsing)
+    return XML_STATUS_ERROR;
+  if (encodingName == NULL)
+    protocolEncodingName = NULL;
   else {
     protocolEncodingName = poolCopyString(&tempPool, encodingName);
     if (!protocolEncodingName)
-      return 0;
+      return XML_STATUS_ERROR;
   }
-  return 1;
+  return XML_STATUS_OK;
 }
 
-XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
-					  const XML_Char *context,
-					  const XML_Char *encodingName)
+XML_Parser XMLCALL
+XML_ExternalEntityParserCreate(XML_Parser oldParser,
+                               const XML_Char *context,
+                               const XML_Char *encodingName)
 {
   XML_Parser parser = oldParser;
-  DTD *oldDtd = &dtd;
+  DTD *newDtd = NULL;
+  DTD *oldDtd = _dtd;
   XML_StartElementHandler oldStartElementHandler = startElementHandler;
   XML_EndElementHandler oldEndElementHandler = endElementHandler;
   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
+      = processingInstructionHandler;
   XML_CommentHandler oldCommentHandler = commentHandler;
-  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
-  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler
+      = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler
+      = endCdataSectionHandler;
   XML_DefaultHandler oldDefaultHandler = defaultHandler;
-  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
+      = unparsedEntityDeclHandler;
   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
-  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
-  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
+      = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
+      = endNamespaceDeclHandler;
   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
-  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
+      = externalEntityRefHandler;
+  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler
+      = unknownEncodingHandler;
   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
@@ -733,27 +966,35 @@
 
   void *oldUserData = userData;
   void *oldHandlerArg = handlerArg;
-  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
 #ifdef XML_DTD
-  int oldParamEntityParsing = paramEntityParsing;
+  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+  int oldInEntityValue = prologState.inEntityValue;
 #endif
-  int oldns_triplets = ns_triplets;
+  XML_Bool oldns_triplets = ns_triplets;
 
+#ifdef XML_DTD
+  if (!context)
+    newDtd = oldDtd;
+#endif /* XML_DTD */
+
+  /* Note that the magical uses of the pre-processor to make field
+     access look more like C++ require that `parser' be overwritten
+     here.  This makes this function more painful to follow than it
+     would be otherwise.
+  */
   if (ns) {
     XML_Char tmp[2];
-
     *tmp = namespaceSeparator;
-    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
-				 tmp);
+    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
   }
   else {
-    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
-				 NULL);
+    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
   }
 
   if (!parser)
-    return 0;
+    return NULL;
 
   startElementHandler = oldStartElementHandler;
   endElementHandler = oldEndElementHandler;
@@ -769,6 +1010,7 @@
   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
   notStandaloneHandler = oldNotStandaloneHandler;
   externalEntityRefHandler = oldExternalEntityRefHandler;
+  skippedEntityHandler = oldSkippedEntityHandler;
   unknownEncodingHandler = oldUnknownEncodingHandler;
   elementDeclHandler = oldElementDeclHandler;
   attlistDeclHandler = oldAttlistDeclHandler;
@@ -784,30 +1026,38 @@
     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
   ns_triplets = oldns_triplets;
+  parentParser = oldParser;
 #ifdef XML_DTD
   paramEntityParsing = oldParamEntityParsing;
+  prologState.inEntityValue = oldInEntityValue;
   if (context) {
 #endif /* XML_DTD */
-    if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
+    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
+      || !setContext(parser, context)) {
       XML_ParserFree(parser);
-      return 0;
+      return NULL;
     }
     processor = externalEntityInitProcessor;
 #ifdef XML_DTD
   }
   else {
-    dtdSwap(&dtd, oldDtd);
-    parentParser = oldParser;
+    /* The DTD instance referenced by _dtd is shared between the document's
+       root parser and external PE parsers, therefore one does not need to
+       call setContext. In addition, one also *must* not call setContext,
+       because this would overwrite existing prefix->binding pointers in
+       _dtd with ones that get destroyed with the external PE parser.
+       This would leave those prefixes with dangling pointers.
+    */
+    isParamEntity = XML_TRUE;
     XmlPrologStateInitExternalEntity(&prologState);
-    dtd.complete = 1;
-    hadExternalDoctype = 1;
+    processor = externalParEntInitProcessor;
   }
 #endif /* XML_DTD */
   return parser;
 }
 
-static
-void destroyBindings(BINDING *bindings, XML_Parser parser)
+static void FASTCALL
+destroyBindings(BINDING *bindings, XML_Parser parser)
 {
   for (;;) {
     BINDING *b = bindings;
@@ -819,15 +1069,16 @@
   }
 }
 
-void XML_ParserFree(XML_Parser parser)
+void XMLCALL
+XML_ParserFree(XML_Parser parser)
 {
   for (;;) {
     TAG *p;
-    if (tagStack == 0) {
-      if (freeTagList == 0)
-	break;
+    if (tagStack == NULL) {
+      if (freeTagList == NULL)
+        break;
       tagStack = freeTagList;
-      freeTagList = 0;
+      freeTagList = NULL;
     }
     p = tagStack;
     tagStack = tagStack->parent;
@@ -840,37 +1091,56 @@
   poolDestroy(&tempPool);
   poolDestroy(&temp2Pool);
 #ifdef XML_DTD
-  if (parentParser) {
-    if (hadExternalDoctype)
-      dtd.complete = 0;
-    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
-  }
+  /* external parameter entity parsers share the DTD structure
+     parser->m_dtd with the root parser, so we must not destroy it
+  */
+  if (!isParamEntity && _dtd)
+#else
+  if (_dtd)
 #endif /* XML_DTD */
-  dtdDestroy(&dtd, parser);
+    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
   FREE((void *)atts);
-  if (groupConnector)
-    FREE(groupConnector);
-  if (buffer)
-    FREE(buffer);
+  FREE(groupConnector);
+  FREE(buffer);
   FREE(dataBuf);
-  if (unknownEncodingMem)
-    FREE(unknownEncodingMem);
+  FREE(nsAtts);
+  FREE(unknownEncodingMem);
   if (unknownEncodingRelease)
     unknownEncodingRelease(unknownEncodingData);
   FREE(parser);
 }
 
-void XML_UseParserAsHandlerArg(XML_Parser parser)
+void XMLCALL
+XML_UseParserAsHandlerArg(XML_Parser parser)
 {
   handlerArg = parser;
 }
 
-void
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
-  ns_triplets = do_nst;
+enum XML_Error XMLCALL
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
+{
+#ifdef XML_DTD
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
+  useForeignDTD = useDTD;
+  return XML_ERROR_NONE;
+#else
+  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
+#endif
 }
 
-void XML_SetUserData(XML_Parser parser, void *p)
+void XMLCALL
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
+{
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return;
+  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
+}
+
+void XMLCALL
+XML_SetUserData(XML_Parser parser, void *p)
 {
   if (handlerArg == userData)
     handlerArg = userData = p;
@@ -878,225 +1148,267 @@
     userData = p;
 }
 
-int XML_SetBase(XML_Parser parser, const XML_Char *p)
+enum XML_Status XMLCALL
+XML_SetBase(XML_Parser parser, const XML_Char *p)
 {
   if (p) {
-    p = poolCopyString(&dtd.pool, p);
+    p = poolCopyString(&_dtd->pool, p);
     if (!p)
-      return 0;
+      return XML_STATUS_ERROR;
     curBase = p;
   }
   else
-    curBase = 0;
-  return 1;
+    curBase = NULL;
+  return XML_STATUS_OK;
 }
 
-const XML_Char *XML_GetBase(XML_Parser parser)
+const XML_Char * XMLCALL
+XML_GetBase(XML_Parser parser)
 {
   return curBase;
 }
 
-int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+int XMLCALL
+XML_GetSpecifiedAttributeCount(XML_Parser parser)
 {
   return nSpecifiedAtts;
 }
 
-int XML_GetIdAttributeIndex(XML_Parser parser)
+int XMLCALL
+XML_GetIdAttributeIndex(XML_Parser parser)
 {
   return idAttIndex;
 }
 
-void XML_SetElementHandler(XML_Parser parser,
-			   XML_StartElementHandler start,
-			   XML_EndElementHandler end)
+void XMLCALL
+XML_SetElementHandler(XML_Parser parser,
+                      XML_StartElementHandler start,
+                      XML_EndElementHandler end)
 {
   startElementHandler = start;
   endElementHandler = end;
 }
 
-void XML_SetStartElementHandler(XML_Parser parser,
-				XML_StartElementHandler start) {
+void XMLCALL
+XML_SetStartElementHandler(XML_Parser parser,
+                           XML_StartElementHandler start) {
   startElementHandler = start;
 }
 
-void XML_SetEndElementHandler(XML_Parser parser,
-			      XML_EndElementHandler end) {
+void XMLCALL
+XML_SetEndElementHandler(XML_Parser parser,
+                         XML_EndElementHandler end) {
   endElementHandler = end;
 }
 
-void XML_SetCharacterDataHandler(XML_Parser parser,
-				 XML_CharacterDataHandler handler)
+void XMLCALL
+XML_SetCharacterDataHandler(XML_Parser parser,
+                            XML_CharacterDataHandler handler)
 {
   characterDataHandler = handler;
 }
 
-void XML_SetProcessingInstructionHandler(XML_Parser parser,
-					 XML_ProcessingInstructionHandler handler)
+void XMLCALL
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                    XML_ProcessingInstructionHandler handler)
 {
   processingInstructionHandler = handler;
 }
 
-void XML_SetCommentHandler(XML_Parser parser,
-			   XML_CommentHandler handler)
+void XMLCALL
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler)
 {
   commentHandler = handler;
 }
 
-void XML_SetCdataSectionHandler(XML_Parser parser,
-				XML_StartCdataSectionHandler start,
-			        XML_EndCdataSectionHandler end)
+void XMLCALL
+XML_SetCdataSectionHandler(XML_Parser parser,
+                           XML_StartCdataSectionHandler start,
+                           XML_EndCdataSectionHandler end)
 {
   startCdataSectionHandler = start;
   endCdataSectionHandler = end;
 }
 
-void XML_SetStartCdataSectionHandler(XML_Parser parser,
-                                     XML_StartCdataSectionHandler start) {
+void XMLCALL
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start) {
   startCdataSectionHandler = start;
 }
 
-void XML_SetEndCdataSectionHandler(XML_Parser parser,
-                                   XML_EndCdataSectionHandler end) {
+void XMLCALL
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end) {
   endCdataSectionHandler = end;
 }
 
-void XML_SetDefaultHandler(XML_Parser parser,
-			   XML_DefaultHandler handler)
+void XMLCALL
+XML_SetDefaultHandler(XML_Parser parser,
+                      XML_DefaultHandler handler)
 {
   defaultHandler = handler;
-  defaultExpandInternalEntities = 0;
+  defaultExpandInternalEntities = XML_FALSE;
 }
 
-void XML_SetDefaultHandlerExpand(XML_Parser parser,
-				 XML_DefaultHandler handler)
+void XMLCALL
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                            XML_DefaultHandler handler)
 {
   defaultHandler = handler;
-  defaultExpandInternalEntities = 1;
+  defaultExpandInternalEntities = XML_TRUE;
 }
 
-void XML_SetDoctypeDeclHandler(XML_Parser parser,
-			       XML_StartDoctypeDeclHandler start,
-			       XML_EndDoctypeDeclHandler end)
+void XMLCALL
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                          XML_StartDoctypeDeclHandler start,
+                          XML_EndDoctypeDeclHandler end)
 {
   startDoctypeDeclHandler = start;
   endDoctypeDeclHandler = end;
 }
 
-void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
-				    XML_StartDoctypeDeclHandler start) {
+void XMLCALL
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+                               XML_StartDoctypeDeclHandler start) {
   startDoctypeDeclHandler = start;
 }
 
-void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
-				  XML_EndDoctypeDeclHandler end) {
+void XMLCALL
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+                             XML_EndDoctypeDeclHandler end) {
   endDoctypeDeclHandler = end;
 }
 
-void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-				      XML_UnparsedEntityDeclHandler handler)
+void XMLCALL
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                 XML_UnparsedEntityDeclHandler handler)
 {
   unparsedEntityDeclHandler = handler;
 }
 
-void XML_SetNotationDeclHandler(XML_Parser parser,
-				XML_NotationDeclHandler handler)
+void XMLCALL
+XML_SetNotationDeclHandler(XML_Parser parser,
+                           XML_NotationDeclHandler handler)
 {
   notationDeclHandler = handler;
 }
 
-void XML_SetNamespaceDeclHandler(XML_Parser parser,
-				 XML_StartNamespaceDeclHandler start,
-				 XML_EndNamespaceDeclHandler end)
+void XMLCALL
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                            XML_StartNamespaceDeclHandler start,
+                            XML_EndNamespaceDeclHandler end)
 {
   startNamespaceDeclHandler = start;
   endNamespaceDeclHandler = end;
 }
 
-void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
-				      XML_StartNamespaceDeclHandler start) {
+void XMLCALL
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+                                 XML_StartNamespaceDeclHandler start) {
   startNamespaceDeclHandler = start;
 }
 
-void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
-				    XML_EndNamespaceDeclHandler end) {
+void XMLCALL
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+                               XML_EndNamespaceDeclHandler end) {
   endNamespaceDeclHandler = end;
 }
 
-
-void XML_SetNotStandaloneHandler(XML_Parser parser,
-				 XML_NotStandaloneHandler handler)
+void XMLCALL
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                            XML_NotStandaloneHandler handler)
 {
   notStandaloneHandler = handler;
 }
 
-void XML_SetExternalEntityRefHandler(XML_Parser parser,
-				     XML_ExternalEntityRefHandler handler)
+void XMLCALL
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                XML_ExternalEntityRefHandler handler)
 {
   externalEntityRefHandler = handler;
 }
 
-void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+void XMLCALL
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
 {
   if (arg)
-    externalEntityRefHandlerArg = arg;
+    externalEntityRefHandlerArg = (XML_Parser)arg;
   else
     externalEntityRefHandlerArg = parser;
 }
 
-void XML_SetUnknownEncodingHandler(XML_Parser parser,
-				   XML_UnknownEncodingHandler handler,
-				   void *data)
+void XMLCALL
+XML_SetSkippedEntityHandler(XML_Parser parser,
+                            XML_SkippedEntityHandler handler)
+{
+  skippedEntityHandler = handler;
+}
+
+void XMLCALL
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                              XML_UnknownEncodingHandler handler,
+                              void *data)
 {
   unknownEncodingHandler = handler;
   unknownEncodingHandlerData = data;
 }
 
-void XML_SetElementDeclHandler(XML_Parser parser,
-			       XML_ElementDeclHandler eldecl)
+void XMLCALL
+XML_SetElementDeclHandler(XML_Parser parser,
+                          XML_ElementDeclHandler eldecl)
 {
   elementDeclHandler = eldecl;
 }
 
-void XML_SetAttlistDeclHandler(XML_Parser parser,
-			       XML_AttlistDeclHandler attdecl)
+void XMLCALL
+XML_SetAttlistDeclHandler(XML_Parser parser,
+                          XML_AttlistDeclHandler attdecl)
 {
   attlistDeclHandler = attdecl;
 }
 
-void XML_SetEntityDeclHandler(XML_Parser parser,
-			      XML_EntityDeclHandler handler)
+void XMLCALL
+XML_SetEntityDeclHandler(XML_Parser parser,
+                         XML_EntityDeclHandler handler)
 {
   entityDeclHandler = handler;
 }
 
-void XML_SetXmlDeclHandler(XML_Parser parser,
-			   XML_XmlDeclHandler handler) {
+void XMLCALL
+XML_SetXmlDeclHandler(XML_Parser parser,
+                      XML_XmlDeclHandler handler) {
   xmlDeclHandler = handler;
 }
 
-int XML_SetParamEntityParsing(XML_Parser parser,
-			      enum XML_ParamEntityParsing parsing)
+int XMLCALL
+XML_SetParamEntityParsing(XML_Parser parser,
+                          enum XML_ParamEntityParsing peParsing)
 {
+  /* block after XML_Parse()/XML_ParseBuffer() has been called */
+  if (parsing)
+    return 0;
 #ifdef XML_DTD
-  paramEntityParsing = parsing;
+  paramEntityParsing = peParsing;
   return 1;
 #else
-  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
 #endif
 }
 
-int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+enum XML_Status XMLCALL
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
 {
   if (len == 0) {
     if (!isFinal)
-      return 1;
+      return XML_STATUS_OK;
     positionPtr = bufferPtr;
     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
     if (errorCode == XML_ERROR_NONE)
-      return 1;
+      return XML_STATUS_OK;
     eventEndPtr = eventPtr;
     processor = errorProcessor;
-    return 0;
+    return XML_STATUS_ERROR;
   }
 #ifndef XML_CONTEXT_BYTES
   else if (bufferPtr == bufferEnd) {
@@ -1107,66 +1419,83 @@
     if (isFinal) {
       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
       if (errorCode == XML_ERROR_NONE)
-	return 1;
+        return XML_STATUS_OK;
       eventEndPtr = eventPtr;
       processor = errorProcessor;
-      return 0;
+      return XML_STATUS_ERROR;
     }
     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
     if (errorCode != XML_ERROR_NONE) {
       eventEndPtr = eventPtr;
       processor = errorProcessor;
-      return 0;
+      return XML_STATUS_ERROR;
     }
     XmlUpdatePosition(encoding, positionPtr, end, &position);
+    positionPtr = end;
     nLeftOver = s + len - end;
     if (nLeftOver) {
-      if (buffer == 0 || nLeftOver > bufferLim - buffer) {
-	/* FIXME avoid integer overflow */
-	buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
-	/* FIXME storage leak if realloc fails */
-	if (!buffer) {
-	  errorCode = XML_ERROR_NO_MEMORY;
-	  eventPtr = eventEndPtr = 0;
-	  processor = errorProcessor;
-	  return 0;
-	}
-	bufferLim = buffer + len * 2;
+      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
+        /* FIXME avoid integer overflow */
+        char *temp;
+        temp = (buffer == NULL
+                ? (char *)MALLOC(len * 2)
+                : (char *)REALLOC(buffer, len * 2));
+        if (temp == NULL) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          return XML_STATUS_ERROR;
+        }
+        buffer = temp;
+        if (!buffer) {
+          errorCode = XML_ERROR_NO_MEMORY;
+          eventPtr = eventEndPtr = NULL;
+          processor = errorProcessor;
+          return XML_STATUS_ERROR;
+        }
+        bufferLim = buffer + len * 2;
       }
       memcpy(buffer, end, nLeftOver);
       bufferPtr = buffer;
       bufferEnd = buffer + nLeftOver;
     }
-    return 1;
+    return XML_STATUS_OK;
   }
 #endif  /* not defined XML_CONTEXT_BYTES */
   else {
-    memcpy(XML_GetBuffer(parser, len), s, len);
-    return XML_ParseBuffer(parser, len, isFinal);
+    void *buff = XML_GetBuffer(parser, len);
+    if (buff == NULL)
+      return XML_STATUS_ERROR;
+    else {
+      memcpy(buff, s, len);
+      return XML_ParseBuffer(parser, len, isFinal);
+    }
   }
 }
 
-int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+enum XML_Status XMLCALL
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
 {
   const char *start = bufferPtr;
   positionPtr = start;
   bufferEnd += len;
   parseEndByteIndex += len;
   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
-			isFinal ? (const char **)0 : &bufferPtr);
+                        isFinal ? (const char **)NULL : &bufferPtr);
   if (errorCode == XML_ERROR_NONE) {
-    if (!isFinal)
+    if (!isFinal) {
       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
-    return 1;
+      positionPtr = bufferPtr;
+    }
+    return XML_STATUS_OK;
   }
   else {
     eventEndPtr = eventPtr;
     processor = errorProcessor;
-    return 0;
+    return XML_STATUS_ERROR;
   }
 }
 
-void *XML_GetBuffer(XML_Parser parser, int len)
+void * XMLCALL
+XML_GetBuffer(XML_Parser parser, int len)
 {
   if (len > bufferLim - bufferEnd) {
     /* FIXME avoid integer overflow */
@@ -1181,10 +1510,10 @@
     if (neededSize  <= bufferLim - buffer) {
 #ifdef XML_CONTEXT_BYTES
       if (keep < bufferPtr - buffer) {
-	int offset = (bufferPtr - buffer) - keep;
-	memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
-	bufferEnd -= offset;
-	bufferPtr -= offset;
+        int offset = (bufferPtr - buffer) - keep;
+        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+        bufferEnd -= offset;
+        bufferPtr -= offset;
       }
 #else
       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
@@ -1196,35 +1525,35 @@
       char *newBuf;
       int bufferSize = bufferLim - bufferPtr;
       if (bufferSize == 0)
-	bufferSize = INIT_BUFFER_SIZE;
+        bufferSize = INIT_BUFFER_SIZE;
       do {
-	bufferSize *= 2;
+        bufferSize *= 2;
       } while (bufferSize < neededSize);
-      newBuf = MALLOC(bufferSize);
+      newBuf = (char *)MALLOC(bufferSize);
       if (newBuf == 0) {
-	errorCode = XML_ERROR_NO_MEMORY;
-	return 0;
+        errorCode = XML_ERROR_NO_MEMORY;
+        return NULL;
       }
       bufferLim = newBuf + bufferSize;
 #ifdef XML_CONTEXT_BYTES
       if (bufferPtr) {
-	int keep = bufferPtr - buffer;
-	if (keep > XML_CONTEXT_BYTES)
-	  keep = XML_CONTEXT_BYTES;
-	memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
-	FREE(buffer);
-	buffer = newBuf;
-	bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
-	bufferPtr = buffer + keep;
+        int keep = bufferPtr - buffer;
+        if (keep > XML_CONTEXT_BYTES)
+          keep = XML_CONTEXT_BYTES;
+        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+        FREE(buffer);
+        buffer = newBuf;
+        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+        bufferPtr = buffer + keep;
       }
       else {
-	bufferEnd = newBuf + (bufferEnd - bufferPtr);
-	bufferPtr = buffer = newBuf;
+        bufferEnd = newBuf + (bufferEnd - bufferPtr);
+        bufferPtr = buffer = newBuf;
       }
 #else
       if (bufferPtr) {
-	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
-	FREE(buffer);
+        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+        FREE(buffer);
       }
       bufferEnd = newBuf + (bufferEnd - bufferPtr);
       bufferPtr = buffer = newBuf;
@@ -1234,26 +1563,30 @@
   return bufferEnd;
 }
 
-enum XML_Error XML_GetErrorCode(XML_Parser parser)
+enum XML_Error XMLCALL
+XML_GetErrorCode(XML_Parser parser)
 {
   return errorCode;
 }
 
-long XML_GetCurrentByteIndex(XML_Parser parser)
+long XMLCALL
+XML_GetCurrentByteIndex(XML_Parser parser)
 {
   if (eventPtr)
     return parseEndByteIndex - (parseEndPtr - eventPtr);
   return -1;
 }
 
-int XML_GetCurrentByteCount(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentByteCount(XML_Parser parser)
 {
   if (eventEndPtr && eventPtr)
     return eventEndPtr - eventPtr;
   return 0;
 }
 
-const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+const char * XMLCALL
+XML_GetInputContext(XML_Parser parser, int *offset, int *size)
 {
 #ifdef XML_CONTEXT_BYTES
   if (eventPtr && buffer) {
@@ -1265,7 +1598,8 @@
   return (char *) 0;
 }
 
-int XML_GetCurrentLineNumber(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentLineNumber(XML_Parser parser)
 {
   if (eventPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
@@ -1274,7 +1608,8 @@
   return position.lineNumber + 1;
 }
 
-int XML_GetCurrentColumnNumber(XML_Parser parser)
+int XMLCALL
+XML_GetCurrentColumnNumber(XML_Parser parser)
 {
   if (eventPtr) {
     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
@@ -1283,59 +1618,105 @@
   return position.columnNumber;
 }
 
-void XML_DefaultCurrent(XML_Parser parser)
+void XMLCALL
+XML_FreeContentModel(XML_Parser parser, XML_Content *model)
+{
+  FREE(model);
+}
+
+void * XMLCALL
+XML_MemMalloc(XML_Parser parser, size_t size)
+{
+  return MALLOC(size);
+}
+
+void * XMLCALL
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
+{
+  return REALLOC(ptr, size);
+}
+
+void XMLCALL
+XML_MemFree(XML_Parser parser, void *ptr)
+{
+  FREE(ptr);
+}
+
+void XMLCALL
+XML_DefaultCurrent(XML_Parser parser)
 {
   if (defaultHandler) {
     if (openInternalEntities)
       reportDefault(parser,
-	            internalEncoding,
-		    openInternalEntities->internalEventPtr,
-		    openInternalEntities->internalEventEndPtr);
+                    internalEncoding,
+                    openInternalEntities->internalEventPtr,
+                    openInternalEntities->internalEventEndPtr);
     else
       reportDefault(parser, encoding, eventPtr, eventEndPtr);
   }
 }
 
-const XML_LChar *XML_ErrorString(int code)
+const XML_LChar * XMLCALL
+XML_ErrorString(enum XML_Error code)
 {
   static const XML_LChar *message[] = {
     0,
-    XML_T("out of memory"),
-    XML_T("syntax error"),
-    XML_T("no element found"),
-    XML_T("not well-formed (invalid token)"),
-    XML_T("unclosed token"),
-    XML_T("unclosed token"),
-    XML_T("mismatched tag"),
-    XML_T("duplicate attribute"),
-    XML_T("junk after document element"),
-    XML_T("illegal parameter entity reference"),
-    XML_T("undefined entity"),
-    XML_T("recursive entity reference"),
-    XML_T("asynchronous entity"),
-    XML_T("reference to invalid character number"),
-    XML_T("reference to binary entity"),
-    XML_T("reference to external entity in attribute"),
-    XML_T("xml processing instruction not at start of external entity"),
-    XML_T("unknown encoding"),
-    XML_T("encoding specified in XML declaration is incorrect"),
-    XML_T("unclosed CDATA section"),
-    XML_T("error in processing external entity reference"),
-    XML_T("document is not standalone"),
-    XML_T("unexpected parser state - please send a bug report")
+    XML_L("out of memory"),
+    XML_L("syntax error"),
+    XML_L("no element found"),
+    XML_L("not well-formed (invalid token)"),
+    XML_L("unclosed token"),
+    XML_L("partial character"),
+    XML_L("mismatched tag"),
+    XML_L("duplicate attribute"),
+    XML_L("junk after document element"),
+    XML_L("illegal parameter entity reference"),
+    XML_L("undefined entity"),
+    XML_L("recursive entity reference"),
+    XML_L("asynchronous entity"),
+    XML_L("reference to invalid character number"),
+    XML_L("reference to binary entity"),
+    XML_L("reference to external entity in attribute"),
+    XML_L("xml declaration not at start of external entity"),
+    XML_L("unknown encoding"),
+    XML_L("encoding specified in XML declaration is incorrect"),
+    XML_L("unclosed CDATA section"),
+    XML_L("error in processing external entity reference"),
+    XML_L("document is not standalone"),
+    XML_L("unexpected parser state - please send a bug report"),
+    XML_L("entity declared in parameter entity"),
+    XML_L("requested feature requires XML_DTD support in Expat"),
+    XML_L("cannot change setting once parsing has begun"),
+    XML_L("unbound prefix")
   };
   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
     return message[code];
-  return 0;
+  return NULL;
 }
 
-const XML_LChar *
+const XML_LChar * XMLCALL
 XML_ExpatVersion(void) {
-  return VERSION;
+
+  /* V1 is used to string-ize the version number. However, it would
+     string-ize the actual version macro *names* unless we get them
+     substituted before being passed to V1. CPP is defined to expand
+     a macro, then rescan for more expansions. Thus, we use V2 to expand
+     the version macros, then CPP will expand the resulting V1() macro
+     with the correct numerals. */
+  /* ### I'm assuming cpp is portable in this respect... */
+
+#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
+
+  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
+
+#undef V1
+#undef V2
 }
 
-XML_Expat_Version
-XML_ExpatVersionInfo(void) {
+XML_Expat_Version XMLCALL
+XML_ExpatVersionInfo(void)
+{
   XML_Expat_Version version;
 
   version.major = XML_MAJOR_VERSION;
@@ -1345,20 +1726,106 @@
   return version;
 }
 
-static
-enum XML_Error contentProcessor(XML_Parser parser,
-				const char *start,
-				const char *end,
-				const char **endPtr)
+const XML_Feature * XMLCALL
+XML_GetFeatureList(void)
 {
-  return doContent(parser, 0, encoding, start, end, endPtr);
+  static XML_Feature features[] = {
+    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"), 0},
+    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 0},
+#ifdef XML_UNICODE
+    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
+#endif
+#ifdef XML_UNICODE_WCHAR_T
+    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
+#endif
+#ifdef XML_DTD
+    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
+#endif
+#ifdef XML_CONTEXT_BYTES
+    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
+     XML_CONTEXT_BYTES},
+#endif
+#ifdef XML_MIN_SIZE
+    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
+#endif
+    {XML_FEATURE_END,              NULL, 0}
+  };
+
+  features[0].value = sizeof(XML_Char);
+  features[1].value = sizeof(XML_LChar);
+  return features;
 }
 
-static
-enum XML_Error externalEntityInitProcessor(XML_Parser parser,
-					   const char *start,
-					   const char *end,
-					   const char **endPtr)
+/* Initially tag->rawName always points into the parse buffer;
+   for those TAG instances opened while the current parse buffer was
+   processed, and not yet closed, we need to store tag->rawName in a more
+   permanent location, since the parse buffer is about to be discarded.
+*/
+static XML_Bool
+storeRawNames(XML_Parser parser)
+{
+  TAG *tag = tagStack;
+  while (tag) {
+    int bufSize;
+    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
+    char *rawNameBuf = tag->buf + nameLen;
+    /* Stop if already stored.  Since tagStack is a stack, we can stop
+       at the first entry that has already been copied; everything
+       below it in the stack is already been accounted for in a
+       previous call to this function.
+    */
+    if (tag->rawName == rawNameBuf)
+      break;
+    /* For re-use purposes we need to ensure that the
+       size of tag->buf is a multiple of sizeof(XML_Char).
+    */
+    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
+    if (bufSize > tag->bufEnd - tag->buf) {
+      char *temp = (char *)REALLOC(tag->buf, bufSize);
+      if (temp == NULL)
+        return XML_FALSE;
+      /* if tag->name.str points to tag->buf (only when namespace
+         processing is off) then we have to update it
+      */
+      if (tag->name.str == (XML_Char *)tag->buf)
+        tag->name.str = (XML_Char *)temp;
+      /* if tag->name.localPart is set (when namespace processing is on)
+         then update it as well, since it will always point into tag->buf
+      */
+      if (tag->name.localPart)
+        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
+                                                  (XML_Char *)tag->buf);
+      tag->buf = temp;
+      tag->bufEnd = temp + bufSize;
+      rawNameBuf = temp + nameLen;
+    }
+    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
+    tag->rawName = rawNameBuf;
+    tag = tag->parent;
+  }
+  return XML_TRUE;
+}
+
+static enum XML_Error PTRCALL
+contentProcessor(XML_Parser parser,
+                 const char *start,
+                 const char *end,
+                 const char **endPtr)
+{
+  enum XML_Error result =
+    doContent(parser, 0, encoding, start, end, endPtr);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (!storeRawNames(parser))
+    return XML_ERROR_NO_MEMORY;
+  return result;
+}
+
+static enum XML_Error PTRCALL
+externalEntityInitProcessor(XML_Parser parser,
+                            const char *start,
+                            const char *end,
+                            const char **endPtr)
 {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
@@ -1367,16 +1834,25 @@
   return externalEntityInitProcessor2(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
-					    const char *start,
-					    const char *end,
-					    const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityInitProcessor2(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
 {
-  const char *next;
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
   int tok = XmlContentTok(encoding, start, end, &next);
   switch (tok) {
   case XML_TOK_BOM:
+    /* If we are at the end of the buffer, this would cause the next stage,
+       i.e. externalEntityInitProcessor3, to pass control directly to
+       doContent (by detecting XML_TOK_NONE) without processing any xml text
+       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
+    */
+    if (next == end && endPtr) {
+      *endPtr = next;
+      return XML_ERROR_NONE;
+    }
     start = next;
     break;
   case XML_TOK_PARTIAL:
@@ -1398,20 +1874,20 @@
   return externalEntityInitProcessor3(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
-					    const char *start,
-					    const char *end,
-					    const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityInitProcessor3(XML_Parser parser,
+                             const char *start,
+                             const char *end,
+                             const char **endPtr)
 {
-  const char *next;
+  const char *next = start; /* XmlContentTok doesn't always set the last arg */
   int tok = XmlContentTok(encoding, start, end, &next);
   switch (tok) {
   case XML_TOK_XML_DECL:
     {
       enum XML_Error result = processXmlDecl(parser, 1, start, next);
       if (result != XML_ERROR_NONE)
-	return result;
+        return result;
       start = next;
     }
     break;
@@ -1432,26 +1908,33 @@
   }
   processor = externalEntityContentProcessor;
   tagLevel = 1;
-  return doContent(parser, 1, encoding, start, end, endPtr);
+  return externalEntityContentProcessor(parser, start, end, endPtr);
 }
 
-static
-enum XML_Error externalEntityContentProcessor(XML_Parser parser,
-					      const char *start,
-					      const char *end,
-					      const char **endPtr)
+static enum XML_Error PTRCALL
+externalEntityContentProcessor(XML_Parser parser,
+                               const char *start,
+                               const char *end,
+                               const char **endPtr)
 {
-  return doContent(parser, 1, encoding, start, end, endPtr);
+  enum XML_Error result =
+    doContent(parser, 1, encoding, start, end, endPtr);
+  if (result != XML_ERROR_NONE)
+    return result;
+  if (!storeRawNames(parser))
+    return XML_ERROR_NO_MEMORY;
+  return result;
 }
 
 static enum XML_Error
 doContent(XML_Parser parser,
-	  int startTagLevel,
-	  const ENCODING *enc,
-	  const char *s,
-	  const char *end,
-	  const char **nextPtr)
+          int startTagLevel,
+          const ENCODING *enc,
+          const char *s,
+          const char *end,
+          const char **nextPtr)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   const char **eventPP;
   const char **eventEndPP;
   if (enc == encoding) {
@@ -1470,30 +1953,30 @@
     switch (tok) {
     case XML_TOK_TRAILING_CR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       *eventEndPP = end;
       if (characterDataHandler) {
-	XML_Char c = 0xA;
-	characterDataHandler(handlerArg, &c, 1);
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, end);
+        reportDefault(parser, enc, s, end);
       if (startTagLevel == 0)
-	return XML_ERROR_NO_ELEMENTS;
+        return XML_ERROR_NO_ELEMENTS;
       if (tagLevel != startTagLevel)
-	return XML_ERROR_ASYNC_ENTITY;
+        return XML_ERROR_ASYNC_ENTITY;
       return XML_ERROR_NONE;
     case XML_TOK_NONE:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       if (startTagLevel > 0) {
-	if (tagLevel != startTagLevel)
-	  return XML_ERROR_ASYNC_ENTITY;
-	return XML_ERROR_NONE;
+        if (tagLevel != startTagLevel)
+          return XML_ERROR_ASYNC_ENTITY;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_NO_ELEMENTS;
     case XML_TOK_INVALID:
@@ -1501,374 +1984,386 @@
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_UNCLOSED_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_PARTIAL_CHAR;
     case XML_TOK_ENTITY_REF:
       {
-	const XML_Char *name;
-	ENTITY *entity;
-	XML_Char ch = XmlPredefinedEntityName(enc,
-					      s + enc->minBytesPerChar,
-					      next - enc->minBytesPerChar);
-	if (ch) {
-	  if (characterDataHandler)
-	    characterDataHandler(handlerArg, &ch, 1);
-	  else if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	  break;
-	}
-	name = poolStoreString(&dtd.pool, enc,
-				s + enc->minBytesPerChar,
-				next - enc->minBytesPerChar);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-	poolDiscard(&dtd.pool);
-	if (!entity) {
-	  if (dtd.complete || dtd.standalone)
-	    return XML_ERROR_UNDEFINED_ENTITY;
-	  if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	  break;
-	}
-	if (entity->open)
-	  return XML_ERROR_RECURSIVE_ENTITY_REF;
-	if (entity->notation)
-	  return XML_ERROR_BINARY_ENTITY_REF;
-	if (entity) {
-	  if (entity->textPtr) {
-	    enum XML_Error result;
-	    OPEN_INTERNAL_ENTITY openEntity;
-	    if (defaultHandler && !defaultExpandInternalEntities) {
-	      reportDefault(parser, enc, s, next);
-	      break;
-	    }
-	    entity->open = 1;
-	    openEntity.next = openInternalEntities;
-	    openInternalEntities = &openEntity;
-	    openEntity.entity = entity;
-	    openEntity.internalEventPtr = 0;
-	    openEntity.internalEventEndPtr = 0;
-	    result = doContent(parser,
-			       tagLevel,
-			       internalEncoding,
-			       (char *)entity->textPtr,
-			       (char *)(entity->textPtr + entity->textLen),
-			       0);
-	    entity->open = 0;
-	    openInternalEntities = openEntity.next;
-	    if (result)
-	      return result;
-	  }
-	  else if (externalEntityRefHandler) {
-	    const XML_Char *context;
-	    entity->open = 1;
-	    context = getContext(parser);
-	    entity->open = 0;
-	    if (!context)
-	      return XML_ERROR_NO_MEMORY;
-	    if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-				          context,
-					  entity->base,
-					  entity->systemId,
-					  entity->publicId))
-	      return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-	    poolDiscard(&tempPool);
-	  }
-	  else if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	}
-	break;
+        const XML_Char *name;
+        ENTITY *entity;
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+                                              s + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+        if (ch) {
+          if (characterDataHandler)
+            characterDataHandler(handlerArg, &ch, 1);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        name = poolStoreString(&dtd->pool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        poolDiscard(&dtd->pool);
+        /* First, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the skipped entity or default handler.
+        */
+        if (!dtd->hasParamEntityRefs || dtd->standalone) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          else if (defaultHandler)
+            reportDefault(parser, enc, s, next);
+          break;
+        }
+        if (entity->open)
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        if (entity->notation)
+          return XML_ERROR_BINARY_ENTITY_REF;
+        if (entity->textPtr) {
+          enum XML_Error result;
+          OPEN_INTERNAL_ENTITY openEntity;
+          if (!defaultExpandInternalEntities) {
+            if (skippedEntityHandler)
+              skippedEntityHandler(handlerArg, entity->name, 0);
+            else if (defaultHandler)
+              reportDefault(parser, enc, s, next);
+            break;
+          }
+          entity->open = XML_TRUE;
+          openEntity.next = openInternalEntities;
+          openInternalEntities = &openEntity;
+          openEntity.entity = entity;
+          openEntity.internalEventPtr = NULL;
+          openEntity.internalEventEndPtr = NULL;
+          result = doContent(parser,
+                             tagLevel,
+                             internalEncoding,
+                             (char *)entity->textPtr,
+                             (char *)(entity->textPtr + entity->textLen),
+                             0);
+          entity->open = XML_FALSE;
+          openInternalEntities = openEntity.next;
+          if (result)
+            return result;
+        }
+        else if (externalEntityRefHandler) {
+          const XML_Char *context;
+          entity->open = XML_TRUE;
+          context = getContext(parser);
+          entity->open = XML_FALSE;
+          if (!context)
+            return XML_ERROR_NO_MEMORY;
+          if (!externalEntityRefHandler((XML_Parser)externalEntityRefHandlerArg,
+                                        context,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          poolDiscard(&tempPool);
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        break;
       }
-    case XML_TOK_START_TAG_WITH_ATTS:
-      if (!startElementHandler) {
-	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-	if (result)
-	  return result;
-      }
-      /* fall through */
     case XML_TOK_START_TAG_NO_ATTS:
-      {
-	TAG *tag;
-	if (freeTagList) {
-	  tag = freeTagList;
-	  freeTagList = freeTagList->parent;
-	}
-	else {
-	  tag = MALLOC(sizeof(TAG));
-	  if (!tag)
-	    return XML_ERROR_NO_MEMORY;
-	  tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
-	  if (!tag->buf)
-	    return XML_ERROR_NO_MEMORY;
-	  tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
-	}
-	tag->bindings = 0;
-	tag->parent = tagStack;
-	tagStack = tag;
-	tag->name.localPart = 0;
-	tag->rawName = s + enc->minBytesPerChar;
-	tag->rawNameLength = XmlNameLength(enc, tag->rawName);
-	if (nextPtr) {
-	  /* Need to guarantee that:
-	     tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
-	  if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
-	    int bufSize = tag->rawNameLength * 4;
-	    bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
-	    tag->buf = REALLOC(tag->buf, bufSize);
-	    if (!tag->buf)
-	      return XML_ERROR_NO_MEMORY;
-	    tag->bufEnd = tag->buf + bufSize;
-	  }
-	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);
-	  tag->rawName = tag->buf;
-	}
-	++tagLevel;
-	if (startElementHandler) {
-	  enum XML_Error result;
-	  XML_Char *toPtr;
-	  for (;;) {
-	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;
-	    const char *fromPtr = tag->rawName;
-	    int bufSize;
-	    if (nextPtr)
-	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
-	    else
-	      toPtr = (XML_Char *)tag->buf;
-	    tag->name.str = toPtr;
-	    XmlConvert(enc,
-		       &fromPtr, rawNameEnd,
-		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
-	    if (fromPtr == rawNameEnd)
-	      break;
-	    bufSize = (tag->bufEnd - tag->buf) << 1;
-	    tag->buf = REALLOC(tag->buf, bufSize);
-	    if (!tag->buf)
-	      return XML_ERROR_NO_MEMORY;
-	    tag->bufEnd = tag->buf + bufSize;
-	    if (nextPtr)
-	      tag->rawName = tag->buf;
-	  }
-	  *toPtr = XML_T('\0');
-	  result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-	  if (result)
-	    return result;
-	  startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
-	  poolClear(&tempPool);
-	}
-	else {
-	  tag->name.str = 0;
-	  if (defaultHandler)
-	    reportDefault(parser, enc, s, next);
-	}
-	break;
-      }
-    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
-      if (!startElementHandler) {
-	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-	if (result)
-	  return result;
-      }
       /* fall through */
-    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
-      if (startElementHandler || endElementHandler) {
-	const char *rawName = s + enc->minBytesPerChar;
-	enum XML_Error result;
-	BINDING *bindings = 0;
-	TAG_NAME name;
-	name.str = poolStoreString(&tempPool, enc, rawName,
-				   rawName + XmlNameLength(enc, rawName));
-	if (!name.str)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&tempPool);
-	result = storeAtts(parser, enc, s, &name, &bindings);
-	if (result)
-	  return result;
-	poolFinish(&tempPool);
-	if (startElementHandler)
-	  startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
-	if (endElementHandler) {
-	  if (startElementHandler)
-	    *eventPP = *eventEndPP;
-	  endElementHandler(handlerArg, name.str);
-	}
-	poolClear(&tempPool);
-	while (bindings) {
-	  BINDING *b = bindings;
-	  if (endNamespaceDeclHandler)
-	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
-	  bindings = bindings->nextTagBinding;
-	  b->nextTagBinding = freeBindingList;
-	  freeBindingList = b;
-	  b->prefix->binding = b->prevPrefixBinding;
-	}
+    case XML_TOK_START_TAG_WITH_ATTS:
+      {
+        TAG *tag;
+        enum XML_Error result;
+        XML_Char *toPtr;
+        if (freeTagList) {
+          tag = freeTagList;
+          freeTagList = freeTagList->parent;
+        }
+        else {
+          tag = (TAG *)MALLOC(sizeof(TAG));
+          if (!tag)
+            return XML_ERROR_NO_MEMORY;
+          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
+          if (!tag->buf) {
+            FREE(tag);
+            return XML_ERROR_NO_MEMORY;
+          }
+          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+        }
+        tag->bindings = NULL;
+        tag->parent = tagStack;
+        tagStack = tag;
+        tag->name.localPart = NULL;
+        tag->name.prefix = NULL;
+        tag->rawName = s + enc->minBytesPerChar;
+        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+        ++tagLevel;
+        {
+          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+          const char *fromPtr = tag->rawName;
+          toPtr = (XML_Char *)tag->buf;
+          for (;;) {
+            int bufSize;
+            int convLen;
+            XmlConvert(enc,
+                       &fromPtr, rawNameEnd,
+                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+            convLen = toPtr - (XML_Char *)tag->buf;
+            if (fromPtr == rawNameEnd) {
+              tag->name.strLen = convLen;
+              break;
+            }
+            bufSize = (tag->bufEnd - tag->buf) << 1;
+            {
+              char *temp = (char *)REALLOC(tag->buf, bufSize);
+              if (temp == NULL)
+                return XML_ERROR_NO_MEMORY;
+              tag->buf = temp;
+              tag->bufEnd = temp + bufSize;
+              toPtr = (XML_Char *)temp + convLen;
+            }
+          }
+        }
+        tag->name.str = (XML_Char *)tag->buf;
+        *toPtr = XML_T('\0');
+        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+        if (result)
+          return result;
+        if (startElementHandler)
+          startElementHandler(handlerArg, tag->name.str,
+                              (const XML_Char **)atts);
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        poolClear(&tempPool);
+        break;
       }
-      else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      {
+        const char *rawName = s + enc->minBytesPerChar;
+        enum XML_Error result;
+        BINDING *bindings = NULL;
+        XML_Bool noElmHandlers = XML_TRUE;
+        TAG_NAME name;
+        name.str = poolStoreString(&tempPool, enc, rawName,
+                                   rawName + XmlNameLength(enc, rawName));
+        if (!name.str)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        result = storeAtts(parser, enc, s, &name, &bindings);
+        if (result)
+          return result;
+        poolFinish(&tempPool);
+        if (startElementHandler) {
+          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+          noElmHandlers = XML_FALSE;
+        }
+        if (endElementHandler) {
+          if (startElementHandler)
+            *eventPP = *eventEndPP;
+          endElementHandler(handlerArg, name.str);
+          noElmHandlers = XML_FALSE;
+        }
+        if (noElmHandlers && defaultHandler)
+          reportDefault(parser, enc, s, next);
+        poolClear(&tempPool);
+        while (bindings) {
+          BINDING *b = bindings;
+          if (endNamespaceDeclHandler)
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);
+          bindings = bindings->nextTagBinding;
+          b->nextTagBinding = freeBindingList;
+          freeBindingList = b;
+          b->prefix->binding = b->prevPrefixBinding;
+        }
+      }
       if (tagLevel == 0)
-	return epilogProcessor(parser, next, end, nextPtr);
+        return epilogProcessor(parser, next, end, nextPtr);
       break;
     case XML_TOK_END_TAG:
       if (tagLevel == startTagLevel)
         return XML_ERROR_ASYNC_ENTITY;
       else {
-	int len;
-	const char *rawName;
-	TAG *tag = tagStack;
-	tagStack = tag->parent;
-	tag->parent = freeTagList;
-	freeTagList = tag;
-	rawName = s + enc->minBytesPerChar*2;
-	len = XmlNameLength(enc, rawName);
-	if (len != tag->rawNameLength
-	    || memcmp(tag->rawName, rawName, len) != 0) {
-	  *eventPP = rawName;
-	  return XML_ERROR_TAG_MISMATCH;
-	}
-	--tagLevel;
-	if (endElementHandler && tag->name.str) {
-	  if (tag->name.localPart) {
-	    XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
-	    const XML_Char *from = tag->name.localPart;
-	    while ((*to++ = *from++) != 0)
-	      ;
-	  }
-	  endElementHandler(handlerArg, tag->name.str);
-	}
-	else if (defaultHandler)
-	  reportDefault(parser, enc, s, next);
-	while (tag->bindings) {
-	  BINDING *b = tag->bindings;
-	  if (endNamespaceDeclHandler)
-	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
-	  tag->bindings = tag->bindings->nextTagBinding;
-	  b->nextTagBinding = freeBindingList;
-	  freeBindingList = b;
-	  b->prefix->binding = b->prevPrefixBinding;
-	}
-	if (tagLevel == 0)
-	  return epilogProcessor(parser, next, end, nextPtr);
+        int len;
+        const char *rawName;
+        TAG *tag = tagStack;
+        tagStack = tag->parent;
+        tag->parent = freeTagList;
+        freeTagList = tag;
+        rawName = s + enc->minBytesPerChar*2;
+        len = XmlNameLength(enc, rawName);
+        if (len != tag->rawNameLength
+            || memcmp(tag->rawName, rawName, len) != 0) {
+          *eventPP = rawName;
+          return XML_ERROR_TAG_MISMATCH;
+        }
+        --tagLevel;
+        if (endElementHandler) {
+          const XML_Char *localPart;
+          const XML_Char *prefix;
+          XML_Char *uri;
+          localPart = tag->name.localPart;
+          if (ns && localPart) {
+            /* localPart and prefix may have been overwritten in
+               tag->name.str, since this points to the binding->uri
+               buffer which gets re-used; so we have to add them again
+            */
+            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
+            /* don't need to check for space - already done in storeAtts() */
+            while (*localPart) *uri++ = *localPart++;
+            prefix = (XML_Char *)tag->name.prefix;
+            if (ns_triplets && prefix) {
+              *uri++ = namespaceSeparator;
+              while (*prefix) *uri++ = *prefix++;
+             }
+            *uri = XML_T('\0');
+          }
+          endElementHandler(handlerArg, tag->name.str);
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        while (tag->bindings) {
+          BINDING *b = tag->bindings;
+          if (endNamespaceDeclHandler)
+            endNamespaceDeclHandler(handlerArg, b->prefix->name);
+          tag->bindings = tag->bindings->nextTagBinding;
+          b->nextTagBinding = freeBindingList;
+          freeBindingList = b;
+          b->prefix->binding = b->prevPrefixBinding;
+        }
+        if (tagLevel == 0)
+          return epilogProcessor(parser, next, end, nextPtr);
       }
       break;
     case XML_TOK_CHAR_REF:
       {
-	int n = XmlCharRefNumber(enc, s);
-	if (n < 0)
-	  return XML_ERROR_BAD_CHAR_REF;
-	if (characterDataHandler) {
-	  XML_Char buf[XML_ENCODE_MAX];
-	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
-	}
-	else if (defaultHandler)
-	  reportDefault(parser, enc, s, next);
+        int n = XmlCharRefNumber(enc, s);
+        if (n < 0)
+          return XML_ERROR_BAD_CHAR_REF;
+        if (characterDataHandler) {
+          XML_Char buf[XML_ENCODE_MAX];
+          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+        }
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
       }
       break;
     case XML_TOK_XML_DECL:
       return XML_ERROR_MISPLACED_XML_PI;
     case XML_TOK_DATA_NEWLINE:
       if (characterDataHandler) {
-	XML_Char c = 0xA;
-	characterDataHandler(handlerArg, &c, 1);
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_CDATA_SECT_OPEN:
       {
-	enum XML_Error result;
-	if (startCdataSectionHandler)
-  	  startCdataSectionHandler(handlerArg);
+        enum XML_Error result;
+        if (startCdataSectionHandler)
+          startCdataSectionHandler(handlerArg);
 #if 0
-	/* Suppose you doing a transformation on a document that involves
-	   changing only the character data.  You set up a defaultHandler
-	   and a characterDataHandler.  The defaultHandler simply copies
-	   characters through.  The characterDataHandler does the transformation
-	   and writes the characters out escaping them as necessary.  This case
-	   will fail to work if we leave out the following two lines (because &
-	   and < inside CDATA sections will be incorrectly escaped).
+        /* Suppose you doing a transformation on a document that involves
+           changing only the character data.  You set up a defaultHandler
+           and a characterDataHandler.  The defaultHandler simply copies
+           characters through.  The characterDataHandler does the
+           transformation and writes the characters out escaping them as
+           necessary.  This case will fail to work if we leave out the
+           following two lines (because & and < inside CDATA sections will
+           be incorrectly escaped).
 
-	   However, now we have a start/endCdataSectionHandler, so it seems
-	   easier to let the user deal with this. */
-
-	else if (characterDataHandler)
-  	  characterDataHandler(handlerArg, dataBuf, 0);
+           However, now we have a start/endCdataSectionHandler, so it seems
+           easier to let the user deal with this.
+        */
+        else if (characterDataHandler)
+          characterDataHandler(handlerArg, dataBuf, 0);
 #endif
-	else if (defaultHandler)
-	  reportDefault(parser, enc, s, next);
-	result = doCdataSection(parser, enc, &next, end, nextPtr);
-	if (!next) {
-	  processor = cdataSectionProcessor;
-	  return result;
-	}
+        else if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        result = doCdataSection(parser, enc, &next, end, nextPtr);
+        if (!next) {
+          processor = cdataSectionProcessor;
+          return result;
+        }
       }
       break;
     case XML_TOK_TRAILING_RSQB:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       if (characterDataHandler) {
-	if (MUST_CONVERT(enc, s)) {
-	  ICHAR *dataPtr = (ICHAR *)dataBuf;
-	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
-	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-	}
-	else
-	  characterDataHandler(handlerArg,
-		  	       (XML_Char *)s,
-			       (XML_Char *)end - (XML_Char *)s);
+        if (MUST_CONVERT(enc, s)) {
+          ICHAR *dataPtr = (ICHAR *)dataBuf;
+          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+          characterDataHandler(handlerArg, dataBuf,
+                               dataPtr - (ICHAR *)dataBuf);
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (XML_Char *)end - (XML_Char *)s);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, end);
+        reportDefault(parser, enc, s, end);
       if (startTagLevel == 0) {
         *eventPP = end;
-	return XML_ERROR_NO_ELEMENTS;
+        return XML_ERROR_NO_ELEMENTS;
       }
       if (tagLevel != startTagLevel) {
-	*eventPP = end;
-	return XML_ERROR_ASYNC_ENTITY;
+        *eventPP = end;
+        return XML_ERROR_ASYNC_ENTITY;
       }
       return XML_ERROR_NONE;
     case XML_TOK_DATA_CHARS:
       if (characterDataHandler) {
-	if (MUST_CONVERT(enc, s)) {
-	  for (;;) {
-	    ICHAR *dataPtr = (ICHAR *)dataBuf;
-	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-	    *eventEndPP = s;
-	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-	    if (s == next)
-	      break;
-	    *eventPP = s;
-	  }
-	}
-	else
-	  characterDataHandler(handlerArg,
-			       (XML_Char *)s,
-			       (XML_Char *)next - (XML_Char *)s);
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)dataBuf;
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+            *eventEndPP = s;
+            characterDataHandler(handlerArg, dataBuf,
+                                 dataPtr - (ICHAR *)dataBuf);
+            if (s == next)
+              break;
+            *eventPP = s;
+          }
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (XML_Char *)next - (XML_Char *)s);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_PI:
       if (!reportProcessingInstruction(parser, enc, s, next))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_COMMENT:
       if (!reportComment(parser, enc, s, next))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     default:
       if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       break;
     }
     *eventPP = s = next;
@@ -1876,110 +2371,126 @@
   /* not reached */
 }
 
-/* If tagNamePtr is non-null, build a real list of attributes,
-otherwise just check the attributes for well-formedness. */
-
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
-				const char *attStr, TAG_NAME *tagNamePtr,
-				BINDING **bindingsPtr)
+/* Precondition: all arguments must be non-NULL;
+   Purpose:
+   - normalize attributes
+   - check attributes for well-formedness
+   - generate namespace aware attribute names (URI, prefix)
+   - build list of attributes for startElementHandler
+   - default attributes
+   - process namespace declarations (check and report them)
+   - generate namespace aware element name (URI, prefix)
+*/
+static enum XML_Error
+storeAtts(XML_Parser parser, const ENCODING *enc,
+          const char *attStr, TAG_NAME *tagNamePtr,
+          BINDING **bindingsPtr)
 {
-  ELEMENT_TYPE *elementType = 0;
-  int nDefaultAtts = 0;
-  const XML_Char **appAtts;   /* the attribute list to pass to the application */
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  ELEMENT_TYPE *elementType;
+  int nDefaultAtts;
+  const XML_Char **appAtts;   /* the attribute list for the application */
   int attIndex = 0;
+  int prefixLen;
   int i;
   int n;
+  XML_Char *uri;
   int nPrefixes = 0;
   BINDING *binding;
   const XML_Char *localPart;
 
   /* lookup the element type name */
-  if (tagNamePtr) {
-    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
-    if (!elementType) {
-      tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
-      if (!tagNamePtr->str)
-	return XML_ERROR_NO_MEMORY;
-      elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
-      if (!elementType)
-        return XML_ERROR_NO_MEMORY;
-      if (ns && !setElementTypePrefix(parser, elementType))
-        return XML_ERROR_NO_MEMORY;
-    }
-    nDefaultAtts = elementType->nDefaultAtts;
+  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
+  if (!elementType) {
+    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
+    if (!name)
+      return XML_ERROR_NO_MEMORY;
+    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
+                                         sizeof(ELEMENT_TYPE));
+    if (!elementType)
+      return XML_ERROR_NO_MEMORY;
+    if (ns && !setElementTypePrefix(parser, elementType))
+      return XML_ERROR_NO_MEMORY;
   }
+  nDefaultAtts = elementType->nDefaultAtts;
+
   /* get the attributes from the tokenizer */
   n = XmlGetAttributes(enc, attStr, attsSize, atts);
   if (n + nDefaultAtts > attsSize) {
     int oldAttsSize = attsSize;
+    ATTRIBUTE *temp;
     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
-    atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
-    if (!atts)
+    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (temp == NULL)
       return XML_ERROR_NO_MEMORY;
+    atts = temp;
     if (n > oldAttsSize)
       XmlGetAttributes(enc, attStr, n, atts);
   }
+
   appAtts = (const XML_Char **)atts;
   for (i = 0; i < n; i++) {
     /* add the name and value to the attribute list */
     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
-					 atts[i].name
-					 + XmlNameLength(enc, atts[i].name));
+                                         atts[i].name
+                                         + XmlNameLength(enc, atts[i].name));
     if (!attId)
       return XML_ERROR_NO_MEMORY;
-    /* detect duplicate attributes */
+    /* Detect duplicate attributes by their QNames. This does not work when
+       namespace processing is turned on and different prefixes for the same
+       namespace are used. For this case we have a check further down.
+    */
     if ((attId->name)[-1]) {
       if (enc == encoding)
-	eventPtr = atts[i].name;
+        eventPtr = atts[i].name;
       return XML_ERROR_DUPLICATE_ATTRIBUTE;
     }
     (attId->name)[-1] = 1;
     appAtts[attIndex++] = attId->name;
     if (!atts[i].normalized) {
       enum XML_Error result;
-      int isCdata = 1;
+      XML_Bool isCdata = XML_TRUE;
 
       /* figure out whether declared as other than CDATA */
       if (attId->maybeTokenized) {
-	int j;
-	for (j = 0; j < nDefaultAtts; j++) {
-	  if (attId == elementType->defaultAtts[j].id) {
-	    isCdata = elementType->defaultAtts[j].isCdata;
-	    break;
-	  }
-	}
+        int j;
+        for (j = 0; j < nDefaultAtts; j++) {
+          if (attId == elementType->defaultAtts[j].id) {
+            isCdata = elementType->defaultAtts[j].isCdata;
+            break;
+          }
+        }
       }
 
       /* normalize the attribute value */
       result = storeAttributeValue(parser, enc, isCdata,
-				   atts[i].valuePtr, atts[i].valueEnd,
-			           &tempPool);
+                                   atts[i].valuePtr, atts[i].valueEnd,
+                                   &tempPool);
       if (result)
-	return result;
-      if (tagNamePtr) {
-	appAtts[attIndex] = poolStart(&tempPool);
-	poolFinish(&tempPool);
-      }
-      else
-	poolDiscard(&tempPool);
+        return result;
+      appAtts[attIndex] = poolStart(&tempPool);
+      poolFinish(&tempPool);
     }
-    else if (tagNamePtr) {
+    else {
       /* the value did not need normalizing */
-      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
+                                          atts[i].valueEnd);
       if (appAtts[attIndex] == 0)
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       poolFinish(&tempPool);
     }
     /* handle prefixed attribute names */
-    if (attId->prefix && tagNamePtr) {
+    if (attId->prefix) {
       if (attId->xmlns) {
-	/* deal with namespace declarations here */
-        if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
-          return XML_ERROR_NO_MEMORY;
+        /* deal with namespace declarations here */
+        enum XML_Error result = addBinding(parser, attId->prefix, attId,
+                                           appAtts[attIndex], bindingsPtr);
+        if (result)
+          return result;
         --attIndex;
       }
       else {
-	/* deal with other prefixed names later */
+        /* deal with other prefixed names later */
         attIndex++;
         nPrefixes++;
         (attId->name)[-1] = 2;
@@ -1988,134 +2499,227 @@
     else
       attIndex++;
   }
-  if (tagNamePtr) {
-    int j;
-    nSpecifiedAtts = attIndex;
-    if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
-      for (i = 0; i < attIndex; i += 2)
-	if (appAtts[i] == elementType->idAtt->name) {
-	  idAttIndex = i;
-	  break;
-	}
-    }
-    else
-      idAttIndex = -1;
-    /* do attribute defaulting */
-    for (j = 0; j < nDefaultAtts; j++) {
-      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
-      if (!(da->id->name)[-1] && da->value) {
-        if (da->id->prefix) {
-          if (da->id->xmlns) {
-	    if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
-	      return XML_ERROR_NO_MEMORY;
-	  }
-          else {
-	    (da->id->name)[-1] = 2;
-	    nPrefixes++;
-  	    appAtts[attIndex++] = da->id->name;
-	    appAtts[attIndex++] = da->value;
-	  }
-	}
-	else {
-	  (da->id->name)[-1] = 1;
-	  appAtts[attIndex++] = da->id->name;
-	  appAtts[attIndex++] = da->value;
-	}
+
+  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
+  nSpecifiedAtts = attIndex;
+  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+    for (i = 0; i < attIndex; i += 2)
+      if (appAtts[i] == elementType->idAtt->name) {
+        idAttIndex = i;
+        break;
+      }
+  }
+  else
+    idAttIndex = -1;
+
+  /* do attribute defaulting */
+  for (i = 0; i < nDefaultAtts; i++) {
+    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
+    if (!(da->id->name)[-1] && da->value) {
+      if (da->id->prefix) {
+        if (da->id->xmlns) {
+          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
+                                             da->value, bindingsPtr);
+          if (result)
+            return result;
+        }
+        else {
+          (da->id->name)[-1] = 2;
+          nPrefixes++;
+          appAtts[attIndex++] = da->id->name;
+          appAtts[attIndex++] = da->value;
+        }
+      }
+      else {
+        (da->id->name)[-1] = 1;
+        appAtts[attIndex++] = da->id->name;
+        appAtts[attIndex++] = da->value;
       }
     }
-    appAtts[attIndex] = 0;
   }
+  appAtts[attIndex] = 0;
+
+  /* expand prefixed attribute names, check for duplicates,
+     and clear flags that say whether attributes were specified */
   i = 0;
   if (nPrefixes) {
-    /* expand prefixed attribute names */
-    for (; i < attIndex; i += 2) {
-      if (appAtts[i][-1] == 2) {
-        ATTRIBUTE_ID *id;
-        ((XML_Char *)(appAtts[i]))[-1] = 0;
-	id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
-	if (id->prefix->binding) {
-	  int j;
-	  const BINDING *b = id->prefix->binding;
-	  const XML_Char *s = appAtts[i];
-	  for (j = 0; j < b->uriLen; j++) {
-	    if (!poolAppendChar(&tempPool, b->uri[j]))
-	      return XML_ERROR_NO_MEMORY;
-	  }
-	  while (*s++ != ':')
-	    ;
-	  do {
-	    if (!poolAppendChar(&tempPool, *s))
-	      return XML_ERROR_NO_MEMORY;
-	  } while (*s++);
-	  if (ns_triplets) {
-	    tempPool.ptr[-1] = namespaceSeparator;
-	    s = b->prefix->name;
-	    do {
-	      if (!poolAppendChar(&tempPool, *s))
-		return XML_ERROR_NO_MEMORY;
-	    } while (*s++);
-	  }
+    int j;  /* hash table index */
+    unsigned long version = nsAttsVersion;
+    int nsAttsSize = (int)1 << nsAttsPower;
+    /* size of hash table must be at least 2 * (# of prefixed attributes) */
+    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
+      NS_ATT *temp;
+      /* hash table size must also be a power of 2 and >= 8 */
+      while (nPrefixes >> nsAttsPower++);
+      if (nsAttsPower < 3)
+        nsAttsPower = 3;
+      nsAttsSize = (int)1 << nsAttsPower;
+      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
+      if (!temp)
+        return XML_ERROR_NO_MEMORY;
+      nsAtts = temp;
+      version = 0;  /* force re-initialization of nsAtts hash table */
+    }
+    /* using a version flag saves us from initializing nsAtts every time */
+    if (!version) {  /* initialize version flags when version wraps around */
+      version = INIT_ATTS_VERSION;
+      for (j = nsAttsSize; j != 0; )
+        nsAtts[--j].version = version;
+    }
+    nsAttsVersion = --version;
 
-	  appAtts[i] = poolStart(&tempPool);
-	  poolFinish(&tempPool);
-	}
-	if (!--nPrefixes)
-	  break;
+    /* expand prefixed names and check for duplicates */
+    for (; i < attIndex; i += 2) {
+      const XML_Char *s = appAtts[i];
+      if (s[-1] == 2) {  /* prefixed */
+        ATTRIBUTE_ID *id;
+        const BINDING *b;
+        unsigned long uriHash = 0;
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */
+        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
+        b = id->prefix->binding;
+        if (!b)
+          return XML_ERROR_UNBOUND_PREFIX;
+
+        /* as we expand the name we also calculate its hash value */
+        for (j = 0; j < b->uriLen; j++) {
+          const XML_Char c = b->uri[j];
+          if (!poolAppendChar(&tempPool, c))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = CHAR_HASH(uriHash, c);
+        }
+        while (*s++ != XML_T(':'))
+          ;
+        do {  /* copies null terminator */
+          const XML_Char c = *s;
+          if (!poolAppendChar(&tempPool, *s))
+            return XML_ERROR_NO_MEMORY;
+          uriHash = CHAR_HASH(uriHash, c);
+        } while (*s++);
+
+        { /* Check hash table for duplicate of expanded name (uriName).
+             Derived from code in lookup(HASH_TABLE *table, ...).
+          */
+          unsigned char step = 0;
+          unsigned long mask = nsAttsSize - 1;
+          j = uriHash & mask;  /* index into hash table */
+          while (nsAtts[j].version == version) {
+            /* for speed we compare stored hash values first */
+            if (uriHash == nsAtts[j].hash) {
+              const XML_Char *s1 = poolStart(&tempPool);
+              const XML_Char *s2 = nsAtts[j].uriName;
+              /* s1 is null terminated, but not s2 */
+              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
+              if (*s1 == 0)
+                return XML_ERROR_DUPLICATE_ATTRIBUTE;
+            }
+            if (!step)
+              step = PROBE_STEP(uriHash, mask, nsAttsPower);
+            j < step ? ( j += nsAttsSize - step) : (j -= step);
+          }
+        }
+
+        if (ns_triplets) {  /* append namespace separator and prefix */
+          tempPool.ptr[-1] = namespaceSeparator;
+          s = b->prefix->name;
+          do {
+            if (!poolAppendChar(&tempPool, *s))
+              return XML_ERROR_NO_MEMORY;
+          } while (*s++);
+        }
+
+        /* store expanded name in attribute list */
+        s = poolStart(&tempPool);
+        poolFinish(&tempPool);
+        appAtts[i] = s;
+
+        /* fill empty slot with new version, uriName and hash value */
+        nsAtts[j].version = version;
+        nsAtts[j].hash = uriHash;
+        nsAtts[j].uriName = s;
+
+        if (!--nPrefixes)
+          break;
       }
-      else
-	((XML_Char *)(appAtts[i]))[-1] = 0;
+      else  /* not prefixed */
+        ((XML_Char *)s)[-1] = 0;  /* clear flag */
     }
   }
-  /* clear the flags that say whether attributes were specified */
+  /* clear flags for the remaining attributes */
   for (; i < attIndex; i += 2)
     ((XML_Char *)(appAtts[i]))[-1] = 0;
-  if (!tagNamePtr)
-    return XML_ERROR_NONE;
   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
     binding->attId->name[-1] = 0;
+
+  if (!ns)
+    return XML_ERROR_NONE;
+
   /* expand the element type name */
   if (elementType->prefix) {
     binding = elementType->prefix->binding;
     if (!binding)
-      return XML_ERROR_NONE;
+      return XML_ERROR_UNBOUND_PREFIX;
     localPart = tagNamePtr->str;
     while (*localPart++ != XML_T(':'))
       ;
   }
-  else if (dtd.defaultPrefix.binding) {
-    binding = dtd.defaultPrefix.binding;
+  else if (dtd->defaultPrefix.binding) {
+    binding = dtd->defaultPrefix.binding;
     localPart = tagNamePtr->str;
   }
   else
     return XML_ERROR_NONE;
+  prefixLen = 0;
+  if (ns_triplets && binding->prefix->name) {
+    for (; binding->prefix->name[prefixLen++];)
+      ;
+  }
   tagNamePtr->localPart = localPart;
   tagNamePtr->uriLen = binding->uriLen;
+  tagNamePtr->prefix = binding->prefix->name;
+  tagNamePtr->prefixLen = prefixLen;
   for (i = 0; localPart[i++];)
     ;
-  n = i + binding->uriLen;
+  n = i + binding->uriLen + prefixLen;
   if (n > binding->uriAlloc) {
     TAG *p;
-    XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
     if (!uri)
       return XML_ERROR_NO_MEMORY;
     binding->uriAlloc = n + EXPAND_SPARE;
     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
     for (p = tagStack; p; p = p->parent)
       if (p->name.str == binding->uri)
-	p->name.str = uri;
+        p->name.str = uri;
     FREE(binding->uri);
     binding->uri = uri;
   }
-  memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+  uri = binding->uri + binding->uriLen;
+  memcpy(uri, localPart, i * sizeof(XML_Char));
+  if (prefixLen) {
+    uri = uri + (i - 1);
+    if (namespaceSeparator)
+      *uri = namespaceSeparator;
+    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
+  }
   tagNamePtr->str = binding->uri;
   return XML_ERROR_NONE;
 }
 
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+/* addBinding() overwrites the value of prefix->binding without checking.
+   Therefore one must keep track of the old value outside of addBinding().
+*/
+static enum XML_Error
+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
+           const XML_Char *uri, BINDING **bindingsPtr)
 {
   BINDING *b;
   int len;
+
+  /* empty string is only valid when there is no prefix per XML NS 1.0 */
+  if (*uri == XML_T('\0') && prefix->name)
+    return XML_ERROR_SYNTAX;
+
   for (len = 0; uri[len]; len++)
     ;
   if (namespaceSeparator)
@@ -2123,21 +2727,23 @@
   if (freeBindingList) {
     b = freeBindingList;
     if (len > b->uriAlloc) {
-      b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
-      if (!b->uri)
-	return 0;
+      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
+                          sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (temp == NULL)
+        return XML_ERROR_NO_MEMORY;
+      b->uri = temp;
       b->uriAlloc = len + EXPAND_SPARE;
     }
     freeBindingList = b->nextTagBinding;
   }
   else {
-    b = MALLOC(sizeof(BINDING));
+    b = (BINDING *)MALLOC(sizeof(BINDING));
     if (!b)
-      return 0;
-    b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+      return XML_ERROR_NO_MEMORY;
+    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
     if (!b->uri) {
       FREE(b);
-      return 0;
+      return XML_ERROR_NO_MEMORY;
     }
     b->uriAlloc = len + EXPAND_SPARE;
   }
@@ -2148,44 +2754,52 @@
   b->prefix = prefix;
   b->attId = attId;
   b->prevPrefixBinding = prefix->binding;
-  if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
-    prefix->binding = 0;
+  /* NULL binding when default namespace undeclared */
+  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
+    prefix->binding = NULL;
   else
     prefix->binding = b;
   b->nextTagBinding = *bindingsPtr;
   *bindingsPtr = b;
   if (startNamespaceDeclHandler)
     startNamespaceDeclHandler(handlerArg, prefix->name,
-			      prefix->binding ? uri : 0);
-  return 1;
+                              prefix->binding ? uri : 0);
+  return XML_ERROR_NONE;
 }
 
 /* The idea here is to avoid using stack for each CDATA section when
-the whole file is parsed with one call. */
-
-static
-enum XML_Error cdataSectionProcessor(XML_Parser parser,
-				     const char *start,
-			    	     const char *end,
-				     const char **endPtr)
+   the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+cdataSectionProcessor(XML_Parser parser,
+                      const char *start,
+                      const char *end,
+                      const char **endPtr)
 {
-  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+  enum XML_Error result = doCdataSection(parser, encoding, &start,
+                                         end, endPtr);
   if (start) {
-    processor = contentProcessor;
-    return contentProcessor(parser, start, end, endPtr);
+    if (parentParser) {  /* we are parsing an external entity */
+      processor = externalEntityContentProcessor;
+      return externalEntityContentProcessor(parser, start, end, endPtr);
+    }
+    else {
+      processor = contentProcessor;
+      return contentProcessor(parser, start, end, endPtr);
+    }
   }
   return result;
 }
 
 /* startPtr gets set to non-null is the section is closed, and to null if
-the section is not yet closed. */
-
-static
-enum XML_Error doCdataSection(XML_Parser parser,
-			      const ENCODING *enc,
-			      const char **startPtr,
-			      const char *end,
-			      const char **nextPtr)
+   the section is not yet closed.
+*/
+static enum XML_Error
+doCdataSection(XML_Parser parser,
+               const ENCODING *enc,
+               const char **startPtr,
+               const char *end,
+               const char **nextPtr)
 {
   const char *s = *startPtr;
   const char **eventPP;
@@ -2200,7 +2814,7 @@
     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   }
   *eventPP = s;
-  *startPtr = 0;
+  *startPtr = NULL;
   for (;;) {
     const char *next;
     int tok = XmlCdataSectionTok(enc, s, end, &next);
@@ -2208,59 +2822,60 @@
     switch (tok) {
     case XML_TOK_CDATA_SECT_CLOSE:
       if (endCdataSectionHandler)
-	endCdataSectionHandler(handlerArg);
+        endCdataSectionHandler(handlerArg);
 #if 0
       /* see comment under XML_TOK_CDATA_SECT_OPEN */
       else if (characterDataHandler)
-	characterDataHandler(handlerArg, dataBuf, 0);
+        characterDataHandler(handlerArg, dataBuf, 0);
 #endif
       else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       *startPtr = next;
       return XML_ERROR_NONE;
     case XML_TOK_DATA_NEWLINE:
       if (characterDataHandler) {
-	XML_Char c = 0xA;
-	characterDataHandler(handlerArg, &c, 1);
+        XML_Char c = 0xA;
+        characterDataHandler(handlerArg, &c, 1);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_DATA_CHARS:
       if (characterDataHandler) {
-	if (MUST_CONVERT(enc, s)) {
-	  for (;;) {
-  	    ICHAR *dataPtr = (ICHAR *)dataBuf;
-	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-	    *eventEndPP = next;
-	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-	    if (s == next)
-	      break;
-	    *eventPP = s;
-	  }
-	}
-	else
-	  characterDataHandler(handlerArg,
-		  	       (XML_Char *)s,
-			       (XML_Char *)next - (XML_Char *)s);
+        if (MUST_CONVERT(enc, s)) {
+          for (;;) {
+            ICHAR *dataPtr = (ICHAR *)dataBuf;
+            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+            *eventEndPP = next;
+            characterDataHandler(handlerArg, dataBuf,
+                                 dataPtr - (ICHAR *)dataBuf);
+            if (s == next)
+              break;
+            *eventPP = s;
+          }
+        }
+        else
+          characterDataHandler(handlerArg,
+                               (XML_Char *)s,
+                               (XML_Char *)next - (XML_Char *)s);
       }
       else if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+        reportDefault(parser, enc, s, next);
       break;
     case XML_TOK_INVALID:
       *eventPP = next;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_PARTIAL_CHAR;
     case XML_TOK_PARTIAL:
     case XML_TOK_NONE:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_UNCLOSED_CDATA_SECTION;
     default:
@@ -2275,15 +2890,16 @@
 #ifdef XML_DTD
 
 /* The idea here is to avoid using stack for each IGNORE section when
-the whole file is parsed with one call. */
-
-static
-enum XML_Error ignoreSectionProcessor(XML_Parser parser,
-				      const char *start,
-				      const char *end,
-				      const char **endPtr)
+   the whole file is parsed with one call.
+*/
+static enum XML_Error PTRCALL
+ignoreSectionProcessor(XML_Parser parser,
+                       const char *start,
+                       const char *end,
+                       const char **endPtr)
 {
-  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start,
+                                          end, endPtr);
   if (start) {
     processor = prologProcessor;
     return prologProcessor(parser, start, end, endPtr);
@@ -2291,15 +2907,15 @@
   return result;
 }
 
-/* startPtr gets set to non-null is the section is closed, and to null if
-the section is not yet closed. */
-
-static
-enum XML_Error doIgnoreSection(XML_Parser parser,
-			       const ENCODING *enc,
-			       const char **startPtr,
-			       const char *end,
-			       const char **nextPtr)
+/* startPtr gets set to non-null is the section is closed, and to null
+   if the section is not yet closed.
+*/
+static enum XML_Error
+doIgnoreSection(XML_Parser parser,
+                const ENCODING *enc,
+                const char **startPtr,
+                const char *end,
+                const char **nextPtr)
 {
   const char *next;
   int tok;
@@ -2316,7 +2932,7 @@
     eventEndPP = &(openInternalEntities->internalEventEndPtr);
   }
   *eventPP = s;
-  *startPtr = 0;
+  *startPtr = NULL;
   tok = XmlIgnoreSectionTok(enc, s, end, &next);
   *eventEndPP = next;
   switch (tok) {
@@ -2357,14 +2973,14 @@
 #ifdef XML_UNICODE
   char encodingBuf[128];
   if (!protocolEncodingName)
-    s = 0;
+    s = NULL;
   else {
     int i;
     for (i = 0; protocolEncodingName[i]; i++) {
       if (i == sizeof(encodingBuf) - 1
-	  || (protocolEncodingName[i] & ~0x7f) != 0) {
-	encodingBuf[0] = '\0';
-	break;
+          || (protocolEncodingName[i] & ~0x7f) != 0) {
+        encodingBuf[0] = '\0';
+        break;
       }
       encodingBuf[i] = (char)protocolEncodingName[i];
     }
@@ -2381,81 +2997,79 @@
 
 static enum XML_Error
 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
-	       const char *s, const char *next)
+               const char *s, const char *next)
 {
-  const char *encodingName = 0;
-  const char *storedEncName = 0;
-  const ENCODING *newEncoding = 0;
-  const char *version = 0;
+  const char *encodingName = NULL;
+  const XML_Char *storedEncName = NULL;
+  const ENCODING *newEncoding = NULL;
+  const char *version = NULL;
   const char *versionend;
-  const char *storedversion = 0;
+  const XML_Char *storedversion = NULL;
   int standalone = -1;
   if (!(ns
         ? XmlParseXmlDeclNS
-	: XmlParseXmlDecl)(isGeneralTextEntity,
-		           encoding,
-		           s,
-		           next,
-		           &eventPtr,
-		           &version,
-			   &versionend,
-		           &encodingName,
-		           &newEncoding,
-		           &standalone))
+        : XmlParseXmlDecl)(isGeneralTextEntity,
+                           encoding,
+                           s,
+                           next,
+                           &eventPtr,
+                           &version,
+                           &versionend,
+                           &encodingName,
+                           &newEncoding,
+                           &standalone))
     return XML_ERROR_SYNTAX;
   if (!isGeneralTextEntity && standalone == 1) {
-    dtd.standalone = 1;
+    _dtd->standalone = XML_TRUE;
 #ifdef XML_DTD
     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
 #endif /* XML_DTD */
   }
   if (xmlDeclHandler) {
-    if (encodingName) {
+    if (encodingName != NULL) {
       storedEncName = poolStoreString(&temp2Pool,
-				      encoding,
-				      encodingName,
-				      encodingName
-				      + XmlNameLength(encoding, encodingName));
-      if (! storedEncName)
-	return XML_ERROR_NO_MEMORY;
+                                      encoding,
+                                      encodingName,
+                                      encodingName
+                                      + XmlNameLength(encoding, encodingName));
+      if (!storedEncName)
+              return XML_ERROR_NO_MEMORY;
       poolFinish(&temp2Pool);
     }
     if (version) {
       storedversion = poolStoreString(&temp2Pool,
-				      encoding,
-				      version,
-				      versionend - encoding->minBytesPerChar);
-      if (! storedversion)
-	return XML_ERROR_NO_MEMORY;
+                                      encoding,
+                                      version,
+                                      versionend - encoding->minBytesPerChar);
+      if (!storedversion)
+        return XML_ERROR_NO_MEMORY;
     }
     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
   }
   else if (defaultHandler)
     reportDefault(parser, encoding, s, next);
-  if (!protocolEncodingName) {
+  if (protocolEncodingName == NULL) {
     if (newEncoding) {
       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
-	eventPtr = encodingName;
-	return XML_ERROR_INCORRECT_ENCODING;
+        eventPtr = encodingName;
+        return XML_ERROR_INCORRECT_ENCODING;
       }
       encoding = newEncoding;
     }
     else if (encodingName) {
       enum XML_Error result;
-      if (! storedEncName) {
-	storedEncName = poolStoreString(&temp2Pool,
-					encoding,
-					encodingName,
-					encodingName
-					+ XmlNameLength(encoding, encodingName));
-	if (! storedEncName)
-	  return XML_ERROR_NO_MEMORY;
+      if (!storedEncName) {
+        storedEncName = poolStoreString(
+          &temp2Pool, encoding, encodingName,
+          encodingName + XmlNameLength(encoding, encodingName));
+        if (!storedEncName)
+          return XML_ERROR_NO_MEMORY;
       }
       result = handleUnknownEncoding(parser, storedEncName);
-      poolClear(&tempPool);
+      poolClear(&temp2Pool);
       if (result == XML_ERROR_UNKNOWN_ENCODING)
-	eventPtr = encodingName;
+        eventPtr = encodingName;
       return result;
     }
   }
@@ -2474,41 +3088,42 @@
     int i;
     for (i = 0; i < 256; i++)
       info.map[i] = -1;
-    info.convert = 0;
-    info.data = 0;
-    info.release = 0;
-    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+    info.convert = NULL;
+    info.data = NULL;
+    info.release = NULL;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
+                               &info)) {
       ENCODING *enc;
       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
       if (!unknownEncodingMem) {
-	if (info.release)
-	  info.release(info.data);
-	return XML_ERROR_NO_MEMORY;
+        if (info.release)
+          info.release(info.data);
+        return XML_ERROR_NO_MEMORY;
       }
       enc = (ns
-	     ? XmlInitUnknownEncodingNS
-	     : XmlInitUnknownEncoding)(unknownEncodingMem,
-				       info.map,
-				       info.convert,
-				       info.data);
+             ? XmlInitUnknownEncodingNS
+             : XmlInitUnknownEncoding)(unknownEncodingMem,
+                                       info.map,
+                                       info.convert,
+                                       info.data);
       if (enc) {
-	unknownEncodingData = info.data;
-	unknownEncodingRelease = info.release;
-	encoding = enc;
-	return XML_ERROR_NONE;
+        unknownEncodingData = info.data;
+        unknownEncodingRelease = info.release;
+        encoding = enc;
+        return XML_ERROR_NONE;
       }
     }
-    if (info.release)
+    if (info.release != NULL)
       info.release(info.data);
   }
   return XML_ERROR_UNKNOWN_ENCODING;
 }
 
-static enum XML_Error
+static enum XML_Error PTRCALL
 prologInitProcessor(XML_Parser parser,
-		    const char *s,
-		    const char *end,
-		    const char **nextPtr)
+                    const char *s,
+                    const char *end,
+                    const char **nextPtr)
 {
   enum XML_Error result = initializeEncoding(parser);
   if (result != XML_ERROR_NONE)
@@ -2517,29 +3132,204 @@
   return prologProcessor(parser, s, end, nextPtr);
 }
 
-static enum XML_Error
-prologProcessor(XML_Parser parser,
-		const char *s,
-		const char *end,
-		const char **nextPtr)
+#ifdef XML_DTD
+
+static enum XML_Error PTRCALL
+externalParEntInitProcessor(XML_Parser parser,
+                            const char *s,
+                            const char *end,
+                            const char **nextPtr)
 {
-  const char *next;
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+
+  /* we know now that XML_Parse(Buffer) has been called,
+     so we consider the external parameter entity read */
+  _dtd->paramEntityRead = XML_TRUE;
+
+  if (prologState.inEntityValue) {
+    processor = entityValueInitProcessor;
+    return entityValueInitProcessor(parser, s, end, nextPtr);
+  }
+  else {
+    processor = externalParEntProcessor;
+    return externalParEntProcessor(parser, s, end, nextPtr);
+  }
+}
+
+static enum XML_Error PTRCALL
+entityValueInitProcessor(XML_Parser parser,
+                         const char *s,
+                         const char *end,
+                         const char **nextPtr)
+{
+  const char *start = s;
+  const char *next = s;
+  int tok;
+
+  for (;;) {
+    tok = XmlPrologTok(encoding, start, end, &next);
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+              *nextPtr = s;
+              return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+              return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+              return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+              return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:   /* start == end */
+      default:
+        break;
+      }
+      return storeEntityValue(parser, encoding, s, end);
+    }
+    else if (tok == XML_TOK_XML_DECL) {
+      enum XML_Error result = processXmlDecl(parser, 0, start, next);
+            if (result != XML_ERROR_NONE)
+              return result;
+      if (nextPtr) *nextPtr = next;
+      /* stop scanning for text declaration - we found one */
+      processor = entityValueProcessor;
+      return entityValueProcessor(parser, next, end, nextPtr);
+    }
+    /* If we are at the end of the buffer, this would cause XmlPrologTok to
+       return XML_TOK_NONE on the next call, which would then cause the
+       function to exit with *nextPtr set to s - that is what we want for other
+       tokens, but not for the BOM - we would rather like to skip it;
+       then, when this routine is entered the next time, XmlPrologTok will
+       return XML_TOK_INVALID, since the BOM is still in the buffer
+    */
+    else if (tok == XML_TOK_BOM && next == end && nextPtr) {
+      *nextPtr = next;
+      return XML_ERROR_NONE;
+    }
+    start = next;
+  }
+}
+
+static enum XML_Error PTRCALL
+externalParEntProcessor(XML_Parser parser,
+                        const char *s,
+                        const char *end,
+                        const char **nextPtr)
+{
+  const char *start = s;
+  const char *next = s;
+  int tok;
+
+  tok = XmlPrologTok(encoding, start, end, &next);
+  if (tok <= 0) {
+    if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    switch (tok) {
+    case XML_TOK_INVALID:
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_NONE:   /* start == end */
+    default:
+      break;
+    }
+  }
+  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
+     However, when parsing an external subset, doProlog will not accept a BOM
+     as valid, and report a syntax error, so we have to skip the BOM
+  */
+  else if (tok == XML_TOK_BOM) {
+    s = next;
+    tok = XmlPrologTok(encoding, s, end, &next);
+  }
+
+  processor = prologProcessor;
+  return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+static enum XML_Error PTRCALL
+entityValueProcessor(XML_Parser parser,
+                     const char *s,
+                     const char *end,
+                     const char **nextPtr)
+{
+  const char *start = s;
+  const char *next = s;
+  const ENCODING *enc = encoding;
+  int tok;
+
+  for (;;) {
+    tok = XmlPrologTok(enc, start, end, &next);
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+        *nextPtr = s;
+        return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+              return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+              return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+              return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:   /* start == end */
+      default:
+        break;
+      }
+      return storeEntityValue(parser, enc, s, end);
+    }
+    start = next;
+  }
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error PTRCALL
+prologProcessor(XML_Parser parser,
+                const char *s,
+                const char *end,
+                const char **nextPtr)
+{
+  const char *next = s;
   int tok = XmlPrologTok(encoding, s, end, &next);
   return doProlog(parser, encoding, s, end, tok, next, nextPtr);
 }
 
 static enum XML_Error
 doProlog(XML_Parser parser,
-	 const ENCODING *enc,
-	 const char *s,
-	 const char *end,
-	 int tok,
-	 const char *next,
-	 const char **nextPtr)
+         const ENCODING *enc,
+         const char *s,
+         const char *end,
+         int tok,
+         const char *next,
+         const char **nextPtr)
 {
 #ifdef XML_DTD
   static const XML_Char externalSubsetName[] = { '#' , '\0' };
 #endif /* XML_DTD */
+  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
+  static const XML_Char atypeID[] = { 'I', 'D', '\0' };
+  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
+  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
+  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
+  static const XML_Char atypeENTITIES[] =
+      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
+  static const XML_Char atypeNMTOKEN[] = {
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
+  static const XML_Char atypeNMTOKENS[] = {
+      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
+  static const XML_Char notationPrefix[] = {
+      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
+  static const XML_Char enumValueSep[] = { '|', '\0' };
+  static const XML_Char enumValueStart[] = { '(', '\0' };
+
+  DTD * const dtd = _dtd;  /* save one level of indirection */
 
   const char **eventPP;
   const char **eventEndPP;
@@ -2555,624 +3345,780 @@
   }
   for (;;) {
     int role;
+    XML_Bool handleDefault = XML_TRUE;
     *eventPP = s;
     *eventEndPP = next;
     if (tok <= 0) {
       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       switch (tok) {
       case XML_TOK_INVALID:
-	*eventPP = next;
-	return XML_ERROR_INVALID_TOKEN;
+        *eventPP = next;
+        return XML_ERROR_INVALID_TOKEN;
       case XML_TOK_PARTIAL:
-	return XML_ERROR_UNCLOSED_TOKEN;
+        return XML_ERROR_UNCLOSED_TOKEN;
       case XML_TOK_PARTIAL_CHAR:
-	return XML_ERROR_PARTIAL_CHAR;
+        return XML_ERROR_PARTIAL_CHAR;
+      case -XML_TOK_PROLOG_S:
+        tok = -tok;
+        break;
       case XML_TOK_NONE:
 #ifdef XML_DTD
-	if (enc != encoding)
-	  return XML_ERROR_NONE;
-	if (parentParser) {
-	  if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
-	      == XML_ROLE_ERROR)
-	    return XML_ERROR_SYNTAX;
-	  hadExternalDoctype = 0;
-	  return XML_ERROR_NONE;
-	}
+        if (enc != encoding)
+          return XML_ERROR_NONE;
+        if (isParamEntity) {
+          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+              == XML_ROLE_ERROR)
+            return XML_ERROR_SYNTAX;
+          return XML_ERROR_NONE;
+        }
 #endif /* XML_DTD */
-	return XML_ERROR_NO_ELEMENTS;
+        return XML_ERROR_NO_ELEMENTS;
       default:
-	tok = -tok;
-	next = end;
-	break;
+        tok = -tok;
+        next = end;
+        break;
       }
     }
     role = XmlTokenRole(&prologState, tok, s, next, enc);
     switch (role) {
     case XML_ROLE_XML_DECL:
       {
-	enum XML_Error result = processXmlDecl(parser, 0, s, next);
-	if (result != XML_ERROR_NONE)
-	  return result;
-	enc = encoding;
+        enum XML_Error result = processXmlDecl(parser, 0, s, next);
+        if (result != XML_ERROR_NONE)
+          return result;
+        enc = encoding;
+        handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_DOCTYPE_NAME:
       if (startDoctypeDeclHandler) {
-	doctypeName = poolStoreString(&tempPool, enc, s, next);
-	if (! doctypeName)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&tempPool);
-	doctypeSysid = 0;
-	doctypePubid = 0;
+        doctypeName = poolStoreString(&tempPool, enc, s, next);
+        if (!doctypeName)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        doctypePubid = NULL;
+        handleDefault = XML_FALSE;
       }
+      doctypeSysid = NULL; /* always initialize to NULL */
       break;
     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
       if (startDoctypeDeclHandler) {
-	startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
-				doctypePubid, 1);
-	doctypeName = 0;
-	poolClear(&tempPool);
+        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+                                doctypePubid, 1);
+        doctypeName = NULL;
+        poolClear(&tempPool);
+        handleDefault = XML_FALSE;
       }
       break;
 #ifdef XML_DTD
     case XML_ROLE_TEXT_DECL:
       {
-	enum XML_Error result = processXmlDecl(parser, 1, s, next);
-	if (result != XML_ERROR_NONE)
-	  return result;
-	enc = encoding;
+        enum XML_Error result = processXmlDecl(parser, 1, s, next);
+        if (result != XML_ERROR_NONE)
+          return result;
+        enc = encoding;
+        handleDefault = XML_FALSE;
       }
       break;
 #endif /* XML_DTD */
     case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+      useForeignDTD = XML_FALSE;
+#endif /* XML_DTD */
+      dtd->hasParamEntityRefs = XML_TRUE;
       if (startDoctypeDeclHandler) {
-	doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
-	if (! doctypePubid)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&tempPool);
+        doctypePubid = poolStoreString(&tempPool, enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+        if (!doctypePubid)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
       }
 #ifdef XML_DTD
-      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
-				    externalSubsetName,
-				    sizeof(ENTITY));
+      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                    externalSubsetName,
+                                    sizeof(ENTITY));
       if (!declEntity)
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
 #endif /* XML_DTD */
       /* fall through */
     case XML_ROLE_ENTITY_PUBLIC_ID:
       if (!XmlIsPublicId(enc, s, next, eventPP))
-	return XML_ERROR_SYNTAX;
-      if (declEntity) {
-	XML_Char *tem = poolStoreString(&dtd.pool,
-	                                enc,
-					s + enc->minBytesPerChar,
-	  				next - enc->minBytesPerChar);
-	if (!tem)
-	  return XML_ERROR_NO_MEMORY;
-	normalizePublicId(tem);
-	declEntity->publicId = tem;
-	poolFinish(&dtd.pool);
+        return XML_ERROR_SYNTAX;
+      if (dtd->keepProcessing && declEntity) {
+        XML_Char *tem = poolStoreString(&dtd->pool,
+                                        enc,
+                                        s + enc->minBytesPerChar,
+                                        next - enc->minBytesPerChar);
+        if (!tem)
+          return XML_ERROR_NO_MEMORY;
+        normalizePublicId(tem);
+        declEntity->publicId = tem;
+        poolFinish(&dtd->pool);
+        if (entityDeclHandler)
+          handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_DOCTYPE_CLOSE:
       if (doctypeName) {
-	startDoctypeDeclHandler(handlerArg, doctypeName,
-				doctypeSysid, doctypePubid, 0);
-	poolClear(&tempPool);
+        startDoctypeDeclHandler(handlerArg, doctypeName,
+                                doctypeSysid, doctypePubid, 0);
+        poolClear(&tempPool);
+        handleDefault = XML_FALSE;
       }
-      if (dtd.complete && hadExternalDoctype) {
-	dtd.complete = 0;
+      /* doctypeSysid will be non-NULL in the case of a previous
+         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
+         was not set, indicating an external subset
+      */
 #ifdef XML_DTD
-	if (paramEntityParsing && externalEntityRefHandler) {
-	  ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
-					    externalSubsetName,
-					    0);
-	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-					0,
-					entity->base,
-					entity->systemId,
-					entity->publicId))
-	   return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-	}
-#endif /* XML_DTD */
-	if (!dtd.complete
-	    && !dtd.standalone
-	    && notStandaloneHandler
-	    && !notStandaloneHandler(handlerArg))
-	  return XML_ERROR_NOT_STANDALONE;
+      if (doctypeSysid || useForeignDTD) {
+        dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
+        if (paramEntityParsing && externalEntityRefHandler) {
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+                                            externalSubsetName,
+                                            sizeof(ENTITY));
+          if (!entity)
+            return XML_ERROR_NO_MEMORY;
+          if (useForeignDTD)
+            entity->base = curBase;
+          dtd->paramEntityRead = XML_FALSE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          if (dtd->paramEntityRead &&
+              !dtd->standalone &&
+              notStandaloneHandler &&
+              !notStandaloneHandler(handlerArg))
+            return XML_ERROR_NOT_STANDALONE;
+          /* end of DTD - no need to update dtd->keepProcessing */
+        }
+        useForeignDTD = XML_FALSE;
       }
-      if (endDoctypeDeclHandler)
-	endDoctypeDeclHandler(handlerArg);
+#endif /* XML_DTD */
+      if (endDoctypeDeclHandler) {
+        endDoctypeDeclHandler(handlerArg);
+        handleDefault = XML_FALSE;
+      }
       break;
     case XML_ROLE_INSTANCE_START:
+#ifdef XML_DTD
+      /* if there is no DOCTYPE declaration then now is the
+         last chance to read the foreign DTD
+      */
+      if (useForeignDTD) {
+        dtd->hasParamEntityRefs = XML_TRUE;
+        if (paramEntityParsing && externalEntityRefHandler) {
+          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
+                                            externalSubsetName,
+                                            sizeof(ENTITY));
+          if (!entity)
+            return XML_ERROR_NO_MEMORY;
+          entity->base = curBase;
+          dtd->paramEntityRead = XML_FALSE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId))
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          if (dtd->paramEntityRead &&
+              !dtd->standalone &&
+              notStandaloneHandler &&
+              !notStandaloneHandler(handlerArg))
+            return XML_ERROR_NOT_STANDALONE;
+          /* end of DTD - no need to update dtd->keepProcessing */
+        }
+      }
+#endif /* XML_DTD */
       processor = contentProcessor;
       return contentProcessor(parser, s, end, nextPtr);
     case XML_ROLE_ATTLIST_ELEMENT_NAME:
       declElementType = getElementType(parser, enc, s, next);
       if (!declElementType)
-	return XML_ERROR_NO_MEMORY;
-      break;
+        return XML_ERROR_NO_MEMORY;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_NAME:
       declAttributeId = getAttributeId(parser, enc, s, next);
       if (!declAttributeId)
-	return XML_ERROR_NO_MEMORY;
-      declAttributeIsCdata = 0;
-      declAttributeType = 0;
-      declAttributeIsId = 0;
-      break;
+        return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = XML_FALSE;
+      declAttributeType = NULL;
+      declAttributeIsId = XML_FALSE;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
-      declAttributeIsCdata = 1;
-      declAttributeType = "CDATA";
-      break;
+      declAttributeIsCdata = XML_TRUE;
+      declAttributeType = atypeCDATA;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_ID:
-      declAttributeIsId = 1;
-      declAttributeType = "ID";
-      break;
+      declAttributeIsId = XML_TRUE;
+      declAttributeType = atypeID;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
-      declAttributeType = "IDREF";
-      break;
+      declAttributeType = atypeIDREF;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
-      declAttributeType = "IDREFS";
-      break;
+      declAttributeType = atypeIDREFS;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
-      declAttributeType = "ENTITY";
-      break;
+      declAttributeType = atypeENTITY;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
-      declAttributeType = "ENTITIES";
-      break;
+      declAttributeType = atypeENTITIES;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
-      declAttributeType = "NMTOKEN";
-      break;
+      declAttributeType = atypeNMTOKEN;
+      goto checkAttListDeclHandler;
     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
-      declAttributeType = "NMTOKENS";
+      declAttributeType = atypeNMTOKENS;
+    checkAttListDeclHandler:
+      if (dtd->keepProcessing && attlistDeclHandler)
+        handleDefault = XML_FALSE;
       break;
-
     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
-      if (attlistDeclHandler)
-      {
-	char *prefix;
-	if (declAttributeType) {
-	  prefix = "|";
-	}
-	else {
-	  prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
-		    ? "NOTATION("
-		    : "(");
-	}
-	if (! poolAppendString(&tempPool, prefix))
-	  return XML_ERROR_NO_MEMORY;
-	if (! poolAppend(&tempPool, enc, s, next))
-	  return XML_ERROR_NO_MEMORY;
-	declAttributeType = tempPool.start;
+      if (dtd->keepProcessing && attlistDeclHandler) {
+        const XML_Char *prefix;
+        if (declAttributeType) {
+          prefix = enumValueSep;
+        }
+        else {
+          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+                    ? notationPrefix
+                    : enumValueStart);
+        }
+        if (!poolAppendString(&tempPool, prefix))
+          return XML_ERROR_NO_MEMORY;
+        if (!poolAppend(&tempPool, enc, s, next))
+          return XML_ERROR_NO_MEMORY;
+        declAttributeType = tempPool.start;
+        handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
-      if (dtd.complete
-	  && !defineAttribute(declElementType, declAttributeId,
-			      declAttributeIsCdata, declAttributeIsId, 0,
-			      parser))
-	return XML_ERROR_NO_MEMORY;
-      if (attlistDeclHandler && declAttributeType) {
-	if (*declAttributeType == '('
-	    || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
-	  /* Enumerated or Notation type */
-	  if (! poolAppendChar(&tempPool, ')')
-	      || ! poolAppendChar(&tempPool, '\0'))
-	    return XML_ERROR_NO_MEMORY;
-	  declAttributeType = tempPool.start;
-	  poolFinish(&tempPool);
-	}
-	*eventEndPP = s;
-	attlistDeclHandler(handlerArg, declElementType->name,
-			   declAttributeId->name, declAttributeType,
-			   0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
-	poolClear(&tempPool);
+      if (dtd->keepProcessing) {
+        if (!defineAttribute(declElementType, declAttributeId,
+                             declAttributeIsCdata, declAttributeIsId,
+                             0, parser))
+          return XML_ERROR_NO_MEMORY;
+        if (attlistDeclHandler && declAttributeType) {
+          if (*declAttributeType == XML_T('(')
+              || (*declAttributeType == XML_T('N')
+                  && declAttributeType[1] == XML_T('O'))) {
+            /* Enumerated or Notation type */
+            if (!poolAppendChar(&tempPool, XML_T(')'))
+                || !poolAppendChar(&tempPool, XML_T('\0')))
+              return XML_ERROR_NO_MEMORY;
+            declAttributeType = tempPool.start;
+            poolFinish(&tempPool);
+          }
+          *eventEndPP = s;
+          attlistDeclHandler(handlerArg, declElementType->name,
+                             declAttributeId->name, declAttributeType,
+                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+          poolClear(&tempPool);
+          handleDefault = XML_FALSE;
+        }
       }
       break;
     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
-      {
-	const XML_Char *attVal;
-	enum XML_Error result
-	  = storeAttributeValue(parser, enc, declAttributeIsCdata,
-				s + enc->minBytesPerChar,
-			        next - enc->minBytesPerChar,
-			        &dtd.pool);
-	if (result)
-	  return result;
-	attVal = poolStart(&dtd.pool);
-	poolFinish(&dtd.pool);
-	if (dtd.complete
-	    /* ID attributes aren't allowed to have a default */
-	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
-	  return XML_ERROR_NO_MEMORY;
-	if (attlistDeclHandler && declAttributeType) {
-	  if (*declAttributeType == '('
-	      || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
-	    /* Enumerated or Notation type */
-	    if (! poolAppendChar(&tempPool, ')')
-		|| ! poolAppendChar(&tempPool, '\0'))
-	      return XML_ERROR_NO_MEMORY;
-	    declAttributeType = tempPool.start;
-	    poolFinish(&tempPool);
-	  }
-	  *eventEndPP = s;
-	  attlistDeclHandler(handlerArg, declElementType->name,
-			     declAttributeId->name, declAttributeType,
-			     attVal,
-			     role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
-	  poolClear(&tempPool);
-	}
-	break;
+      if (dtd->keepProcessing) {
+        const XML_Char *attVal;
+        enum XML_Error result =
+          storeAttributeValue(parser, enc, declAttributeIsCdata,
+                              s + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar,
+                              &dtd->pool);
+        if (result)
+          return result;
+        attVal = poolStart(&dtd->pool);
+        poolFinish(&dtd->pool);
+        /* ID attributes aren't allowed to have a default */
+        if (!defineAttribute(declElementType, declAttributeId,
+                             declAttributeIsCdata, XML_FALSE, attVal, parser))
+          return XML_ERROR_NO_MEMORY;
+        if (attlistDeclHandler && declAttributeType) {
+          if (*declAttributeType == XML_T('(')
+              || (*declAttributeType == XML_T('N')
+                  && declAttributeType[1] == XML_T('O'))) {
+            /* Enumerated or Notation type */
+            if (!poolAppendChar(&tempPool, XML_T(')'))
+                || !poolAppendChar(&tempPool, XML_T('\0')))
+              return XML_ERROR_NO_MEMORY;
+            declAttributeType = tempPool.start;
+            poolFinish(&tempPool);
+          }
+          *eventEndPP = s;
+          attlistDeclHandler(handlerArg, declElementType->name,
+                             declAttributeId->name, declAttributeType,
+                             attVal,
+                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+          poolClear(&tempPool);
+          handleDefault = XML_FALSE;
+        }
       }
+      break;
     case XML_ROLE_ENTITY_VALUE:
-      {
-	enum XML_Error result = storeEntityValue(parser, enc,
-						 s + enc->minBytesPerChar,
-						 next - enc->minBytesPerChar);
-	if (declEntity) {
-	  declEntity->textPtr = poolStart(&dtd.pool);
-	  declEntity->textLen = poolLength(&dtd.pool);
-	  poolFinish(&dtd.pool);
-	  if (entityDeclHandler) {
-	    *eventEndPP = s;
-	    entityDeclHandler(handlerArg,
-			      declEntity->name,
-			      declEntity->is_param,
-			      declEntity->textPtr,
-			      declEntity->textLen,
-			      curBase, 0, 0, 0);
-	  }
-	}
-	else
-	  poolDiscard(&dtd.pool);
-	if (result != XML_ERROR_NONE)
-	  return result;
+      if (dtd->keepProcessing) {
+        enum XML_Error result = storeEntityValue(parser, enc,
+                                            s + enc->minBytesPerChar,
+                                            next - enc->minBytesPerChar);
+        if (declEntity) {
+          declEntity->textPtr = poolStart(&dtd->entityValuePool);
+          declEntity->textLen = poolLength(&dtd->entityValuePool);
+          poolFinish(&dtd->entityValuePool);
+          if (entityDeclHandler) {
+            *eventEndPP = s;
+            entityDeclHandler(handlerArg,
+                              declEntity->name,
+                              declEntity->is_param,
+                              declEntity->textPtr,
+                              declEntity->textLen,
+                              curBase, 0, 0, 0);
+            handleDefault = XML_FALSE;
+          }
+        }
+        else
+          poolDiscard(&dtd->entityValuePool);
+        if (result != XML_ERROR_NONE)
+          return result;
       }
       break;
     case XML_ROLE_DOCTYPE_SYSTEM_ID:
-      if (startDoctypeDeclHandler) {
-	doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
-	if (! doctypeSysid)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&tempPool);
-      }
-      if (!dtd.standalone
 #ifdef XML_DTD
-	  && !paramEntityParsing
+      useForeignDTD = XML_FALSE;
 #endif /* XML_DTD */
-	  && notStandaloneHandler
-	  && !notStandaloneHandler(handlerArg))
-	return XML_ERROR_NOT_STANDALONE;
-      hadExternalDoctype = 1;
+      dtd->hasParamEntityRefs = XML_TRUE;
+      if (startDoctypeDeclHandler) {
+        doctypeSysid = poolStoreString(&tempPool, enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+        if (doctypeSysid == NULL)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
+      }
+#ifdef XML_DTD
+      else
+        /* use externalSubsetName to make doctypeSysid non-NULL
+           for the case where no startDoctypeDeclHandler is set */
+        doctypeSysid = externalSubsetName;
+#endif /* XML_DTD */
+      if (!dtd->standalone
+#ifdef XML_DTD
+          && !paramEntityParsing
+#endif /* XML_DTD */
+          && notStandaloneHandler
+          && !notStandaloneHandler(handlerArg))
+        return XML_ERROR_NOT_STANDALONE;
 #ifndef XML_DTD
       break;
 #else /* XML_DTD */
       if (!declEntity) {
-	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
-				      externalSubsetName,
-				      sizeof(ENTITY));
-	declEntity->publicId = 0;
-	if (!declEntity)
-	  return XML_ERROR_NO_MEMORY;
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                      externalSubsetName,
+                                      sizeof(ENTITY));
+        if (!declEntity)
+          return XML_ERROR_NO_MEMORY;
+        declEntity->publicId = NULL;
       }
       /* fall through */
 #endif /* XML_DTD */
     case XML_ROLE_ENTITY_SYSTEM_ID:
-      if (declEntity) {
-	declEntity->systemId = poolStoreString(&dtd.pool, enc,
-	                                       s + enc->minBytesPerChar,
-	  				       next - enc->minBytesPerChar);
-	if (!declEntity->systemId)
-	  return XML_ERROR_NO_MEMORY;
-	declEntity->base = curBase;
-	poolFinish(&dtd.pool);
+      if (dtd->keepProcessing && declEntity) {
+        declEntity->systemId = poolStoreString(&dtd->pool, enc,
+                                               s + enc->minBytesPerChar,
+                                               next - enc->minBytesPerChar);
+        if (!declEntity->systemId)
+          return XML_ERROR_NO_MEMORY;
+        declEntity->base = curBase;
+        poolFinish(&dtd->pool);
+        if (entityDeclHandler)
+          handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_ENTITY_COMPLETE:
-      if (declEntity && entityDeclHandler) {
-	*eventEndPP = s;
-	entityDeclHandler(handlerArg,
-			  declEntity->name,
-			  0,0,0,
-			  declEntity->base,
-			  declEntity->systemId,
-			  declEntity->publicId,
-			  0);
+      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
+        *eventEndPP = s;
+        entityDeclHandler(handlerArg,
+                          declEntity->name,
+                          declEntity->is_param,
+                          0,0,
+                          declEntity->base,
+                          declEntity->systemId,
+                          declEntity->publicId,
+                          0);
+        handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_ENTITY_NOTATION_NAME:
-      if (declEntity) {
-	declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
-	if (!declEntity->notation)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&dtd.pool);
-	if (unparsedEntityDeclHandler) {
-	  *eventEndPP = s;
-	  unparsedEntityDeclHandler(handlerArg,
-				    declEntity->name,
-				    declEntity->base,
-				    declEntity->systemId,
-				    declEntity->publicId,
-				    declEntity->notation);
-	}
-	else if (entityDeclHandler) {
-	  *eventEndPP = s;
-	  entityDeclHandler(handlerArg,
-			    declEntity->name,
-			    0,0,0,
-			    declEntity->base,
-			    declEntity->systemId,
-			    declEntity->publicId,
-			    declEntity->notation);
-	}
+      if (dtd->keepProcessing && declEntity) {
+        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
+        if (!declEntity->notation)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&dtd->pool);
+        if (unparsedEntityDeclHandler) {
+          *eventEndPP = s;
+          unparsedEntityDeclHandler(handlerArg,
+                                    declEntity->name,
+                                    declEntity->base,
+                                    declEntity->systemId,
+                                    declEntity->publicId,
+                                    declEntity->notation);
+          handleDefault = XML_FALSE;
+        }
+        else if (entityDeclHandler) {
+          *eventEndPP = s;
+          entityDeclHandler(handlerArg,
+                            declEntity->name,
+                            0,0,0,
+                            declEntity->base,
+                            declEntity->systemId,
+                            declEntity->publicId,
+                            declEntity->notation);
+          handleDefault = XML_FALSE;
+        }
       }
       break;
     case XML_ROLE_GENERAL_ENTITY_NAME:
       {
-	const XML_Char *name;
-	if (XmlPredefinedEntityName(enc, s, next)) {
-	  declEntity = 0;
-	  break;
-	}
-	name = poolStoreString(&dtd.pool, enc, s, next);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	if (dtd.complete) {
-	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
-	  if (!declEntity)
-	    return XML_ERROR_NO_MEMORY;
-	  if (declEntity->name != name) {
-	    poolDiscard(&dtd.pool);
-	    declEntity = 0;
-	  }
-	  else {
-	    poolFinish(&dtd.pool);
-	    declEntity->publicId = 0;
-	    declEntity->is_param = 0;
-	  }
-	}
-	else {
-	  poolDiscard(&dtd.pool);
-	  declEntity = 0;
-	}
+        if (XmlPredefinedEntityName(enc, s, next)) {
+          declEntity = NULL;
+          break;
+        }
+        if (dtd->keepProcessing) {
+          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+          if (!name)
+            return XML_ERROR_NO_MEMORY;
+          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
+                                        sizeof(ENTITY));
+          if (!declEntity)
+            return XML_ERROR_NO_MEMORY;
+          if (declEntity->name != name) {
+            poolDiscard(&dtd->pool);
+            declEntity = NULL;
+          }
+          else {
+            poolFinish(&dtd->pool);
+            declEntity->publicId = NULL;
+            declEntity->is_param = XML_FALSE;
+            /* if we have a parent parser or are reading an internal parameter
+               entity, then the entity declaration is not considered "internal"
+            */
+            declEntity->is_internal = !(parentParser || openInternalEntities);
+            if (entityDeclHandler)
+              handleDefault = XML_FALSE;
+          }
+        }
+        else {
+          poolDiscard(&dtd->pool);
+          declEntity = NULL;
+        }
       }
       break;
     case XML_ROLE_PARAM_ENTITY_NAME:
 #ifdef XML_DTD
-      if (dtd.complete) {
-	const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
-				      name, sizeof(ENTITY));
-	if (!declEntity)
-	  return XML_ERROR_NO_MEMORY;
-	if (declEntity->name != name) {
-	  poolDiscard(&dtd.pool);
-	  declEntity = 0;
-	}
-	else {
-	  poolFinish(&dtd.pool);
-	  declEntity->publicId = 0;
-	  declEntity->is_param = 1;
-	}
+      if (dtd->keepProcessing) {
+        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
+                                           name, sizeof(ENTITY));
+        if (!declEntity)
+          return XML_ERROR_NO_MEMORY;
+        if (declEntity->name != name) {
+          poolDiscard(&dtd->pool);
+          declEntity = NULL;
+        }
+        else {
+          poolFinish(&dtd->pool);
+          declEntity->publicId = NULL;
+          declEntity->is_param = XML_TRUE;
+          /* if we have a parent parser or are reading an internal parameter
+             entity, then the entity declaration is not considered "internal"
+          */
+          declEntity->is_internal = !(parentParser || openInternalEntities);
+          if (entityDeclHandler)
+            handleDefault = XML_FALSE;
+        }
+      }
+      else {
+        poolDiscard(&dtd->pool);
+        declEntity = NULL;
       }
 #else /* not XML_DTD */
-      declEntity = 0;
-#endif /* not XML_DTD */
+      declEntity = NULL;
+#endif /* XML_DTD */
       break;
     case XML_ROLE_NOTATION_NAME:
-      declNotationPublicId = 0;
-      declNotationName = 0;
+      declNotationPublicId = NULL;
+      declNotationName = NULL;
       if (notationDeclHandler) {
-	declNotationName = poolStoreString(&tempPool, enc, s, next);
-	if (!declNotationName)
-	  return XML_ERROR_NO_MEMORY;
-	poolFinish(&tempPool);
+        declNotationName = poolStoreString(&tempPool, enc, s, next);
+        if (!declNotationName)
+          return XML_ERROR_NO_MEMORY;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_NOTATION_PUBLIC_ID:
       if (!XmlIsPublicId(enc, s, next, eventPP))
-	return XML_ERROR_SYNTAX;
-      if (declNotationName) {
-	XML_Char *tem = poolStoreString(&tempPool,
-	                                enc,
-					s + enc->minBytesPerChar,
-	  				next - enc->minBytesPerChar);
-	if (!tem)
-	  return XML_ERROR_NO_MEMORY;
-	normalizePublicId(tem);
-	declNotationPublicId = tem;
-	poolFinish(&tempPool);
+        return XML_ERROR_SYNTAX;
+      if (declNotationName) {  /* means notationDeclHandler != NULL */
+        XML_Char *tem = poolStoreString(&tempPool,
+                                        enc,
+                                        s + enc->minBytesPerChar,
+                                        next - enc->minBytesPerChar);
+        if (!tem)
+          return XML_ERROR_NO_MEMORY;
+        normalizePublicId(tem);
+        declNotationPublicId = tem;
+        poolFinish(&tempPool);
+        handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_NOTATION_SYSTEM_ID:
       if (declNotationName && notationDeclHandler) {
-	const XML_Char *systemId
-	  = poolStoreString(&tempPool, enc,
-			    s + enc->minBytesPerChar,
-	  		    next - enc->minBytesPerChar);
-	if (!systemId)
-	  return XML_ERROR_NO_MEMORY;
-	*eventEndPP = s;
-	notationDeclHandler(handlerArg,
-			    declNotationName,
-			    curBase,
-			    systemId,
-			    declNotationPublicId);
+        const XML_Char *systemId
+          = poolStoreString(&tempPool, enc,
+                            s + enc->minBytesPerChar,
+                            next - enc->minBytesPerChar);
+        if (!systemId)
+          return XML_ERROR_NO_MEMORY;
+        *eventEndPP = s;
+        notationDeclHandler(handlerArg,
+                            declNotationName,
+                            curBase,
+                            systemId,
+                            declNotationPublicId);
+        handleDefault = XML_FALSE;
       }
       poolClear(&tempPool);
       break;
     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
       if (declNotationPublicId && notationDeclHandler) {
-	*eventEndPP = s;
-	notationDeclHandler(handlerArg,
-			    declNotationName,
-			    curBase,
-			    0,
-			    declNotationPublicId);
+        *eventEndPP = s;
+        notationDeclHandler(handlerArg,
+                            declNotationName,
+                            curBase,
+                            0,
+                            declNotationPublicId);
+        handleDefault = XML_FALSE;
       }
       poolClear(&tempPool);
       break;
     case XML_ROLE_ERROR:
       switch (tok) {
       case XML_TOK_PARAM_ENTITY_REF:
-	return XML_ERROR_PARAM_ENTITY_REF;
+        return XML_ERROR_PARAM_ENTITY_REF;
       case XML_TOK_XML_DECL:
-	return XML_ERROR_MISPLACED_XML_PI;
+        return XML_ERROR_MISPLACED_XML_PI;
       default:
-	return XML_ERROR_SYNTAX;
+        return XML_ERROR_SYNTAX;
       }
 #ifdef XML_DTD
     case XML_ROLE_IGNORE_SECT:
       {
-	enum XML_Error result;
-	if (defaultHandler)
-	  reportDefault(parser, enc, s, next);
-	result = doIgnoreSection(parser, enc, &next, end, nextPtr);
-	if (!next) {
-	  processor = ignoreSectionProcessor;
-	  return result;
-	}
+        enum XML_Error result;
+        if (defaultHandler)
+          reportDefault(parser, enc, s, next);
+        handleDefault = XML_FALSE;
+        result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+        if (!next) {
+          processor = ignoreSectionProcessor;
+          return result;
+        }
       }
       break;
 #endif /* XML_DTD */
     case XML_ROLE_GROUP_OPEN:
       if (prologState.level >= groupSize) {
-	if (groupSize) {
-	  groupConnector = REALLOC(groupConnector, groupSize *= 2);
-	  if (dtd.scaffIndex)
-	    dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
-	}
-	else
-	  groupConnector = MALLOC(groupSize = 32);
-	if (!groupConnector)
-	  return XML_ERROR_NO_MEMORY;
+        if (groupSize) {
+          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
+          if (temp == NULL)
+            return XML_ERROR_NO_MEMORY;
+          groupConnector = temp;
+          if (dtd->scaffIndex) {
+            int *temp = (int *)REALLOC(dtd->scaffIndex,
+                          groupSize * sizeof(int));
+            if (temp == NULL)
+              return XML_ERROR_NO_MEMORY;
+            dtd->scaffIndex = temp;
+          }
+        }
+        else {
+          groupConnector = (char *)MALLOC(groupSize = 32);
+          if (!groupConnector)
+            return XML_ERROR_NO_MEMORY;
+        }
       }
       groupConnector[prologState.level] = 0;
-      if (dtd.in_eldecl) {
-	int myindex = nextScaffoldPart(parser);
-	if (myindex < 0)
-	  return XML_ERROR_NO_MEMORY;
-	dtd.scaffIndex[dtd.scaffLevel] = myindex;
-	dtd.scaffLevel++;
-	dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
+      if (dtd->in_eldecl) {
+        int myindex = nextScaffoldPart(parser);
+        if (myindex < 0)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffIndex[dtd->scaffLevel] = myindex;
+        dtd->scaffLevel++;
+        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
       }
       break;
     case XML_ROLE_GROUP_SEQUENCE:
       if (groupConnector[prologState.level] == '|')
-	return XML_ERROR_SYNTAX;
+        return XML_ERROR_SYNTAX;
       groupConnector[prologState.level] = ',';
+      if (dtd->in_eldecl && elementDeclHandler)
+        handleDefault = XML_FALSE;
       break;
     case XML_ROLE_GROUP_CHOICE:
       if (groupConnector[prologState.level] == ',')
-	return XML_ERROR_SYNTAX;
-      if (dtd.in_eldecl
-	  && ! groupConnector[prologState.level]
-	  && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
-	  ) {
-	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
+        return XML_ERROR_SYNTAX;
+      if (dtd->in_eldecl
+          && !groupConnector[prologState.level]
+          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+              != XML_CTYPE_MIXED)
+          ) {
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+            = XML_CTYPE_CHOICE;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
       }
       groupConnector[prologState.level] = '|';
       break;
     case XML_ROLE_PARAM_ENTITY_REF:
 #ifdef XML_DTD
     case XML_ROLE_INNER_PARAM_ENTITY_REF:
-      if (paramEntityParsing
-	  && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
-	const XML_Char *name;
-	ENTITY *entity;
-	name = poolStoreString(&dtd.pool, enc,
-				s + enc->minBytesPerChar,
-				next - enc->minBytesPerChar);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
-	poolDiscard(&dtd.pool);
-	if (!entity) {
-	  /* FIXME what to do if !dtd.complete? */
-	  return XML_ERROR_UNDEFINED_ENTITY;
-	}
-	if (entity->open)
-	  return XML_ERROR_RECURSIVE_ENTITY_REF;
-	if (entity->textPtr) {
-	  enum XML_Error result;
-	  result = processInternalParamEntity(parser, entity);
-	  if (result != XML_ERROR_NONE)
-	    return result;
-	  break;
-	}
-	if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
-	  return XML_ERROR_PARAM_ENTITY_REF;
-	if (externalEntityRefHandler) {
-	  dtd.complete = 0;
-	  entity->open = 1;
-	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-					0,
-					entity->base,
-					entity->systemId,
-					entity->publicId)) {
-	    entity->open = 0;
-	    return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-	  }
-	  entity->open = 0;
-	  if (dtd.complete)
-	    break;
-	}
+      /* PE references in internal subset are
+         not allowed within declarations      */
+      if (prologState.documentEntity &&
+          role == XML_ROLE_INNER_PARAM_ENTITY_REF)
+        return XML_ERROR_PARAM_ENTITY_REF;
+      dtd->hasParamEntityRefs = XML_TRUE;
+      if (!paramEntityParsing)
+        dtd->keepProcessing = dtd->standalone;
+      else {
+        const XML_Char *name;
+        ENTITY *entity;
+        name = poolStoreString(&dtd->pool, enc,
+                                s + enc->minBytesPerChar,
+                                next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+        poolDiscard(&dtd->pool);
+        /* first, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the skipped entity handler
+        */
+        if (prologState.documentEntity &&
+            (dtd->standalone
+             ? !openInternalEntities
+             : !dtd->hasParamEntityRefs)) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          dtd->keepProcessing = dtd->standalone;
+          /* cannot report skipped entities in declarations */
+          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
+            skippedEntityHandler(handlerArg, name, 1);
+            handleDefault = XML_FALSE;
+          }
+          break;
+        }
+        if (entity->open)
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        if (entity->textPtr) {
+          enum XML_Error result;
+          result = processInternalParamEntity(parser, entity);
+          if (result != XML_ERROR_NONE)
+            return result;
+          handleDefault = XML_FALSE;
+          break;
+        }
+        if (externalEntityRefHandler) {
+          dtd->paramEntityRead = XML_FALSE;
+          entity->open = XML_TRUE;
+          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                        0,
+                                        entity->base,
+                                        entity->systemId,
+                                        entity->publicId)) {
+            entity->open = XML_FALSE;
+            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+          }
+          entity->open = XML_FALSE;
+          handleDefault = XML_FALSE;
+          if (!dtd->paramEntityRead) {
+            dtd->keepProcessing = dtd->standalone;
+            break;
+          }
+        }
+        else {
+          dtd->keepProcessing = dtd->standalone;
+          break;
+        }
       }
 #endif /* XML_DTD */
-      if (!dtd.standalone
-	  && notStandaloneHandler
-	  && !notStandaloneHandler(handlerArg))
-	return XML_ERROR_NOT_STANDALONE;
-      dtd.complete = 0;
-      if (defaultHandler)
-	reportDefault(parser, enc, s, next);
+      if (!dtd->standalone &&
+          notStandaloneHandler &&
+          !notStandaloneHandler(handlerArg))
+        return XML_ERROR_NOT_STANDALONE;
       break;
 
-      /* Element declaration stuff */
+    /* Element declaration stuff */
 
     case XML_ROLE_ELEMENT_NAME:
       if (elementDeclHandler) {
-	declElementType = getElementType(parser, enc, s, next);
-	if (! declElementType)
-	  return XML_ERROR_NO_MEMORY;
-	dtd.scaffLevel = 0;
-	dtd.scaffCount = 0;
-	dtd.in_eldecl = 1;
+        declElementType = getElementType(parser, enc, s, next);
+        if (!declElementType)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffLevel = 0;
+        dtd->scaffCount = 0;
+        dtd->in_eldecl = XML_TRUE;
+        handleDefault = XML_FALSE;
       }
       break;
 
     case XML_ROLE_CONTENT_ANY:
     case XML_ROLE_CONTENT_EMPTY:
-      if (dtd.in_eldecl) {
-	if (elementDeclHandler) {
-	  XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
-	  if (! content)
-	    return XML_ERROR_NO_MEMORY;
-	  content->quant = XML_CQUANT_NONE;
-	  content->name = 0;
-	  content->numchildren = 0;
-	  content->children = 0;
-	  content->type = ((role == XML_ROLE_CONTENT_ANY) ?
-			   XML_CTYPE_ANY :
-			   XML_CTYPE_EMPTY);
-	  *eventEndPP = s;
-	  elementDeclHandler(handlerArg, declElementType->name, content);
-	}
-	dtd.in_eldecl = 0;
+      if (dtd->in_eldecl) {
+        if (elementDeclHandler) {
+          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+          if (!content)
+            return XML_ERROR_NO_MEMORY;
+          content->quant = XML_CQUANT_NONE;
+          content->name = NULL;
+          content->numchildren = 0;
+          content->children = NULL;
+          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+                           XML_CTYPE_ANY :
+                           XML_CTYPE_EMPTY);
+          *eventEndPP = s;
+          elementDeclHandler(handlerArg, declElementType->name, content);
+          handleDefault = XML_FALSE;
+        }
+        dtd->in_eldecl = XML_FALSE;
       }
       break;
-      
+
     case XML_ROLE_CONTENT_PCDATA:
-      if (dtd.in_eldecl) {
-	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
+      if (dtd->in_eldecl) {
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
+            = XML_CTYPE_MIXED;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
       }
       break;
 
@@ -3188,21 +4134,29 @@
     case XML_ROLE_CONTENT_ELEMENT_PLUS:
       quant = XML_CQUANT_PLUS;
     elementContent:
-      if (dtd.in_eldecl)
-	{
-	  ELEMENT_TYPE *el;
-	  const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
-	  int myindex = nextScaffoldPart(parser);
-	  if (myindex < 0)
-	    return XML_ERROR_NO_MEMORY;
-	  dtd.scaffold[myindex].type = XML_CTYPE_NAME;
-	  dtd.scaffold[myindex].quant = quant;
-	  el = getElementType(parser, enc, s, nxt);
-	  if (! el)
-	    return XML_ERROR_NO_MEMORY;
-	  dtd.scaffold[myindex].name = el->name;
-	  dtd.contentStringLen +=  nxt - s + 1;
-	}
+      if (dtd->in_eldecl) {
+        ELEMENT_TYPE *el;
+        const XML_Char *name;
+        int nameLen;
+        const char *nxt = (quant == XML_CQUANT_NONE
+                           ? next
+                           : next - enc->minBytesPerChar);
+        int myindex = nextScaffoldPart(parser);
+        if (myindex < 0)
+          return XML_ERROR_NO_MEMORY;
+        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
+        dtd->scaffold[myindex].quant = quant;
+        el = getElementType(parser, enc, s, nxt);
+        if (!el)
+          return XML_ERROR_NO_MEMORY;
+        name = el->name;
+        dtd->scaffold[myindex].name = name;
+        nameLen = 0;
+        for (; name[nameLen++]; );
+        dtd->contentStringLen +=  nameLen;
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+      }
       break;
 
     case XML_ROLE_GROUP_CLOSE:
@@ -3217,109 +4171,125 @@
     case XML_ROLE_GROUP_CLOSE_PLUS:
       quant = XML_CQUANT_PLUS;
     closeGroup:
-      if (dtd.in_eldecl) {
-	dtd.scaffLevel--;
-	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
-	if (dtd.scaffLevel == 0) {
-	  if (elementDeclHandler) {
-	    XML_Content *model = build_model(parser);
-	    if (! model)
-	      return XML_ERROR_NO_MEMORY;
-	    *eventEndPP = s;
-	    elementDeclHandler(handlerArg, declElementType->name, model);
-	  }
-	  dtd.in_eldecl = 0;
-	  dtd.contentStringLen = 0;
-	}
+      if (dtd->in_eldecl) {
+        if (elementDeclHandler)
+          handleDefault = XML_FALSE;
+        dtd->scaffLevel--;
+        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
+        if (dtd->scaffLevel == 0) {
+          if (!handleDefault) {
+            XML_Content *model = build_model(parser);
+            if (!model)
+              return XML_ERROR_NO_MEMORY;
+            *eventEndPP = s;
+            elementDeclHandler(handlerArg, declElementType->name, model);
+          }
+          dtd->in_eldecl = XML_FALSE;
+          dtd->contentStringLen = 0;
+        }
       }
       break;
       /* End element declaration stuff */
 
+    case XML_ROLE_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+        return XML_ERROR_NO_MEMORY;
+      handleDefault = XML_FALSE;
+      break;
     case XML_ROLE_NONE:
       switch (tok) {
-      case XML_TOK_PI:
-	if (!reportProcessingInstruction(parser, enc, s, next))
-	  return XML_ERROR_NO_MEMORY;
-	break;
-      case XML_TOK_COMMENT:
-	if (!reportComment(parser, enc, s, next))
-	  return XML_ERROR_NO_MEMORY;
-	break;
+      case XML_TOK_BOM:
+        handleDefault = XML_FALSE;
+        break;
       }
       break;
-    }
-    if (defaultHandler) {
-      switch (tok) {
-      case XML_TOK_PI:
-      case XML_TOK_COMMENT:
-      case XML_TOK_BOM:
-      case XML_TOK_XML_DECL:
-#ifdef XML_DTD
-      case XML_TOK_IGNORE_SECT:
-#endif /* XML_DTD */
-      case XML_TOK_PARAM_ENTITY_REF:
-	break;
-      default:
-#ifdef XML_DTD
-	if (role != XML_ROLE_IGNORE_SECT)
-#endif /* XML_DTD */
-	  reportDefault(parser, enc, s, next);
-      }
-    }
+    case XML_ROLE_DOCTYPE_NONE:
+      if (startDoctypeDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ENTITY_NONE:
+      if (dtd->keepProcessing && entityDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_NOTATION_NONE:
+      if (notationDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ATTLIST_NONE:
+      if (dtd->keepProcessing && attlistDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    case XML_ROLE_ELEMENT_NONE:
+      if (elementDeclHandler)
+        handleDefault = XML_FALSE;
+      break;
+    } /* end of big switch */
+
+    if (handleDefault && defaultHandler)
+      reportDefault(parser, enc, s, next);
+
     s = next;
     tok = XmlPrologTok(enc, s, end, &next);
   }
   /* not reached */
 }
 
-static
-enum XML_Error epilogProcessor(XML_Parser parser,
-			       const char *s,
-			       const char *end,
-			       const char **nextPtr)
+static enum XML_Error PTRCALL
+epilogProcessor(XML_Parser parser,
+                const char *s,
+                const char *end,
+                const char **nextPtr)
 {
   processor = epilogProcessor;
   eventPtr = s;
   for (;;) {
-    const char *next;
+    const char *next = NULL;
     int tok = XmlPrologTok(encoding, s, end, &next);
     eventEndPtr = next;
     switch (tok) {
+    /* report partial linebreak - it might be the last token */
     case -XML_TOK_PROLOG_S:
       if (defaultHandler) {
-	eventEndPtr = end;
-	reportDefault(parser, encoding, s, end);
+        eventEndPtr = next;
+        reportDefault(parser, encoding, s, next);
       }
-      /* fall through */
+      if (nextPtr)
+        *nextPtr = next;
+      return XML_ERROR_NONE;
     case XML_TOK_NONE:
       if (nextPtr)
-	*nextPtr = end;
+        *nextPtr = s;
       return XML_ERROR_NONE;
     case XML_TOK_PROLOG_S:
       if (defaultHandler)
-	reportDefault(parser, encoding, s, next);
+        reportDefault(parser, encoding, s, next);
       break;
     case XML_TOK_PI:
       if (!reportProcessingInstruction(parser, encoding, s, next))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_COMMENT:
       if (!reportComment(parser, encoding, s, next))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_INVALID:
       eventPtr = next;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_UNCLOSED_TOKEN;
     case XML_TOK_PARTIAL_CHAR:
       if (nextPtr) {
-	*nextPtr = s;
-	return XML_ERROR_NONE;
+        *nextPtr = s;
+        return XML_ERROR_NONE;
       }
       return XML_ERROR_PARTIAL_CHAR;
     default:
@@ -3338,38 +4308,39 @@
   int tok;
   enum XML_Error result;
   OPEN_INTERNAL_ENTITY openEntity;
-  entity->open = 1;
+  entity->open = XML_TRUE;
   openEntity.next = openInternalEntities;
   openInternalEntities = &openEntity;
   openEntity.entity = entity;
-  openEntity.internalEventPtr = 0;
-  openEntity.internalEventEndPtr = 0;
+  openEntity.internalEventPtr = NULL;
+  openEntity.internalEventEndPtr = NULL;
   s = (char *)entity->textPtr;
   end = (char *)(entity->textPtr + entity->textLen);
   tok = XmlPrologTok(internalEncoding, s, end, &next);
   result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
-  entity->open = 0;
+  entity->open = XML_FALSE;
   openInternalEntities = openEntity.next;
   return result;
 }
 
 #endif /* XML_DTD */
 
-static
-enum XML_Error errorProcessor(XML_Parser parser,
-			      const char *s,
-			      const char *end,
-			      const char **nextPtr)
+static enum XML_Error PTRCALL
+errorProcessor(XML_Parser parser,
+               const char *s,
+               const char *end,
+               const char **nextPtr)
 {
   return errorCode;
 }
 
 static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-		    const char *ptr, const char *end,
-		    STRING_POOL *pool)
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+                    const char *ptr, const char *end,
+                    STRING_POOL *pool)
 {
-  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
+                                               end, pool);
   if (result)
     return result;
   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
@@ -3380,10 +4351,11 @@
 }
 
 static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-		     const char *ptr, const char *end,
-		     STRING_POOL *pool)
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
+                     const char *ptr, const char *end,
+                     STRING_POOL *pool)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   for (;;) {
     const char *next;
     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
@@ -3392,41 +4364,41 @@
       return XML_ERROR_NONE;
     case XML_TOK_INVALID:
       if (enc == encoding)
-	eventPtr = next;
+        eventPtr = next;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_PARTIAL:
       if (enc == encoding)
-	eventPtr = ptr;
+        eventPtr = ptr;
       return XML_ERROR_INVALID_TOKEN;
     case XML_TOK_CHAR_REF:
       {
-	XML_Char buf[XML_ENCODE_MAX];
-	int i;
-	int n = XmlCharRefNumber(enc, ptr);
-	if (n < 0) {
-	  if (enc == encoding)
-	    eventPtr = ptr;
-      	  return XML_ERROR_BAD_CHAR_REF;
-	}
-	if (!isCdata
-	    && n == 0x20 /* space */
-	    && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-	  break;
-	n = XmlEncode(n, (ICHAR *)buf);
-	if (!n) {
-	  if (enc == encoding)
-	    eventPtr = ptr;
-	  return XML_ERROR_BAD_CHAR_REF;
-	}
-	for (i = 0; i < n; i++) {
-	  if (!poolAppendChar(pool, buf[i]))
-	    return XML_ERROR_NO_MEMORY;
-	}
+        XML_Char buf[XML_ENCODE_MAX];
+        int i;
+        int n = XmlCharRefNumber(enc, ptr);
+        if (n < 0) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BAD_CHAR_REF;
+        }
+        if (!isCdata
+            && n == 0x20 /* space */
+            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+          break;
+        n = XmlEncode(n, (ICHAR *)buf);
+        if (!n) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BAD_CHAR_REF;
+        }
+        for (i = 0; i < n; i++) {
+          if (!poolAppendChar(pool, buf[i]))
+            return XML_ERROR_NO_MEMORY;
+        }
       }
       break;
     case XML_TOK_DATA_CHARS:
       if (!poolAppend(pool, enc, ptr, next))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_TRAILING_CR:
       next = ptr + enc->minBytesPerChar;
@@ -3434,65 +4406,91 @@
     case XML_TOK_ATTRIBUTE_VALUE_S:
     case XML_TOK_DATA_NEWLINE:
       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-	break;
+        break;
       if (!poolAppendChar(pool, 0x20))
-	return XML_ERROR_NO_MEMORY;
+        return XML_ERROR_NO_MEMORY;
       break;
     case XML_TOK_ENTITY_REF:
       {
-	const XML_Char *name;
-	ENTITY *entity;
-	XML_Char ch = XmlPredefinedEntityName(enc,
-					      ptr + enc->minBytesPerChar,
-					      next - enc->minBytesPerChar);
-	if (ch) {
-	  if (!poolAppendChar(pool, ch))
-  	    return XML_ERROR_NO_MEMORY;
-	  break;
-	}
-	name = poolStoreString(&temp2Pool, enc,
-			       ptr + enc->minBytesPerChar,
-			       next - enc->minBytesPerChar);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-	poolDiscard(&temp2Pool);
-	if (!entity) {
-	  if (dtd.complete) {
-	    if (enc == encoding)
-	      eventPtr = ptr;
-	    return XML_ERROR_UNDEFINED_ENTITY;
-	  }
-	}
-	else if (entity->open) {
-	  if (enc == encoding)
-	    eventPtr = ptr;
-	  return XML_ERROR_RECURSIVE_ENTITY_REF;
-	}
-	else if (entity->notation) {
-	  if (enc == encoding)
-	    eventPtr = ptr;
-	  return XML_ERROR_BINARY_ENTITY_REF;
-	}
-	else if (!entity->textPtr) {
-	  if (enc == encoding)
-	    eventPtr = ptr;
-  	  return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
-	}
-	else {
-	  enum XML_Error result;
-	  const XML_Char *textEnd = entity->textPtr + entity->textLen;
-	  entity->open = 1;
-	  result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
-	  entity->open = 0;
-	  if (result)
-	    return result;
-	}
+        const XML_Char *name;
+        ENTITY *entity;
+        char checkEntityDecl;
+        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
+                                              ptr + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+        if (ch) {
+          if (!poolAppendChar(pool, ch))
+                return XML_ERROR_NO_MEMORY;
+          break;
+        }
+        name = poolStoreString(&temp2Pool, enc,
+                               ptr + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+        if (!name)
+          return XML_ERROR_NO_MEMORY;
+        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
+        poolDiscard(&temp2Pool);
+        /* first, determine if a check for an existing declaration is needed;
+           if yes, check that the entity exists, and that it is internal,
+           otherwise call the default handler (if called from content)
+        */
+        if (pool == &dtd->pool)  /* are we called from prolog? */
+          checkEntityDecl =
+#ifdef XML_DTD
+              prologState.documentEntity &&
+#endif /* XML_DTD */
+              (dtd->standalone
+               ? !openInternalEntities
+               : !dtd->hasParamEntityRefs);
+        else /* if (pool == &tempPool): we are called from content */
+          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
+        if (checkEntityDecl) {
+          if (!entity)
+            return XML_ERROR_UNDEFINED_ENTITY;
+          else if (!entity->is_internal)
+            return XML_ERROR_ENTITY_DECLARED_IN_PE;
+        }
+        else if (!entity) {
+          /* cannot report skipped entity here - see comments on
+             skippedEntityHandler
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          */
+          if ((pool == &tempPool) && defaultHandler)
+            reportDefault(parser, enc, ptr, next);
+          break;
+        }
+        if (entity->open) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_RECURSIVE_ENTITY_REF;
+        }
+        if (entity->notation) {
+          if (enc == encoding)
+            eventPtr = ptr;
+          return XML_ERROR_BINARY_ENTITY_REF;
+        }
+        if (!entity->textPtr) {
+          if (enc == encoding)
+            eventPtr = ptr;
+              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+        }
+        else {
+          enum XML_Error result;
+          const XML_Char *textEnd = entity->textPtr + entity->textLen;
+          entity->open = XML_TRUE;
+          result = appendAttributeValue(parser, internalEncoding, isCdata,
+                                        (char *)entity->textPtr,
+                                        (char *)textEnd, pool);
+          entity->open = XML_FALSE;
+          if (result)
+            return result;
+        }
       }
       break;
     default:
       if (enc == encoding)
-	eventPtr = ptr;
+        eventPtr = ptr;
       return XML_ERROR_UNEXPECTED_STATE;
     }
     ptr = next;
@@ -3500,115 +4498,173 @@
   /* not reached */
 }
 
-static
-enum XML_Error storeEntityValue(XML_Parser parser,
-				const ENCODING *enc,
-				const char *entityTextPtr,
-				const char *entityTextEnd)
+static enum XML_Error
+storeEntityValue(XML_Parser parser,
+                 const ENCODING *enc,
+                 const char *entityTextPtr,
+                 const char *entityTextEnd)
 {
-  STRING_POOL *pool = &(dtd.pool);
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  STRING_POOL *pool = &(dtd->entityValuePool);
+  enum XML_Error result = XML_ERROR_NONE;
+#ifdef XML_DTD
+  int oldInEntityValue = prologState.inEntityValue;
+  prologState.inEntityValue = 1;
+#endif /* XML_DTD */
+  /* never return Null for the value argument in EntityDeclHandler,
+     since this would indicate an external entity; therefore we
+     have to make sure that entityValuePool.start is not null */
+  if (!pool->blocks) {
+    if (!poolGrow(pool))
+      return XML_ERROR_NO_MEMORY;
+  }
+
   for (;;) {
     const char *next;
     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
     switch (tok) {
     case XML_TOK_PARAM_ENTITY_REF:
 #ifdef XML_DTD
-      if (parentParser || enc != encoding) {
-	enum XML_Error result;
-	const XML_Char *name;
-	ENTITY *entity;
-	name = poolStoreString(&tempPool, enc,
-			       entityTextPtr + enc->minBytesPerChar,
-			       next - enc->minBytesPerChar);
-	if (!name)
-	  return XML_ERROR_NO_MEMORY;
-	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
-	poolDiscard(&tempPool);
-	if (!entity) {
-	  if (enc == encoding)
-	    eventPtr = entityTextPtr;
-	  return XML_ERROR_UNDEFINED_ENTITY;
-	}
-	if (entity->open) {
-	  if (enc == encoding)
-	    eventPtr = entityTextPtr;
-	  return XML_ERROR_RECURSIVE_ENTITY_REF;
-	}
-	if (entity->systemId) {
-	  if (enc == encoding)
-	    eventPtr = entityTextPtr;
-	  return XML_ERROR_PARAM_ENTITY_REF;
-	}
-	entity->open = 1;
-	result = storeEntityValue(parser,
-				  internalEncoding,
-				  (char *)entity->textPtr,
-				  (char *)(entity->textPtr + entity->textLen));
-	entity->open = 0;
-	if (result)
-	  return result;
-	break;
+      if (isParamEntity || enc != encoding) {
+        const XML_Char *name;
+        ENTITY *entity;
+        name = poolStoreString(&tempPool, enc,
+                               entityTextPtr + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+        if (!name) {
+          result = XML_ERROR_NO_MEMORY;
+          goto endEntityValue;
+        }
+        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
+        poolDiscard(&tempPool);
+        if (!entity) {
+          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
+          /* cannot report skipped entity here - see comments on
+             skippedEntityHandler
+          if (skippedEntityHandler)
+            skippedEntityHandler(handlerArg, name, 0);
+          */
+          dtd->keepProcessing = dtd->standalone;
+          goto endEntityValue;
+        }
+        if (entity->open) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_RECURSIVE_ENTITY_REF;
+          goto endEntityValue;
+        }
+        if (entity->systemId) {
+          if (externalEntityRefHandler) {
+            dtd->paramEntityRead = XML_FALSE;
+            entity->open = XML_TRUE;
+            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                          0,
+                                          entity->base,
+                                          entity->systemId,
+                                          entity->publicId)) {
+              entity->open = XML_FALSE;
+              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+              goto endEntityValue;
+            }
+            entity->open = XML_FALSE;
+            if (!dtd->paramEntityRead)
+              dtd->keepProcessing = dtd->standalone;
+          }
+          else
+            dtd->keepProcessing = dtd->standalone;
+        }
+        else {
+          entity->open = XML_TRUE;
+          result = storeEntityValue(parser,
+                                    internalEncoding,
+                                    (char *)entity->textPtr,
+                                    (char *)(entity->textPtr
+                                             + entity->textLen));
+          entity->open = XML_FALSE;
+          if (result)
+            goto endEntityValue;
+        }
+        break;
       }
 #endif /* XML_DTD */
+      /* in the internal subset, PE references are not legal
+         within markup declarations, e.g entity values in this case */
       eventPtr = entityTextPtr;
-      return XML_ERROR_SYNTAX;
+      result = XML_ERROR_PARAM_ENTITY_REF;
+      goto endEntityValue;
     case XML_TOK_NONE:
-      return XML_ERROR_NONE;
+      result = XML_ERROR_NONE;
+      goto endEntityValue;
     case XML_TOK_ENTITY_REF:
     case XML_TOK_DATA_CHARS:
-      if (!poolAppend(pool, enc, entityTextPtr, next))
-	return XML_ERROR_NO_MEMORY;
+      if (!poolAppend(pool, enc, entityTextPtr, next)) {
+        result = XML_ERROR_NO_MEMORY;
+        goto endEntityValue;
+      }
       break;
     case XML_TOK_TRAILING_CR:
       next = entityTextPtr + enc->minBytesPerChar;
       /* fall through */
     case XML_TOK_DATA_NEWLINE:
-      if (pool->end == pool->ptr && !poolGrow(pool))
-	return XML_ERROR_NO_MEMORY;
+      if (pool->end == pool->ptr && !poolGrow(pool)) {
+              result = XML_ERROR_NO_MEMORY;
+        goto endEntityValue;
+      }
       *(pool->ptr)++ = 0xA;
       break;
     case XML_TOK_CHAR_REF:
       {
-	XML_Char buf[XML_ENCODE_MAX];
-	int i;
-	int n = XmlCharRefNumber(enc, entityTextPtr);
-	if (n < 0) {
-	  if (enc == encoding)
-	    eventPtr = entityTextPtr;
-	  return XML_ERROR_BAD_CHAR_REF;
-	}
-	n = XmlEncode(n, (ICHAR *)buf);
-	if (!n) {
-	  if (enc == encoding)
-	    eventPtr = entityTextPtr;
-	  return XML_ERROR_BAD_CHAR_REF;
-	}
-	for (i = 0; i < n; i++) {
-	  if (pool->end == pool->ptr && !poolGrow(pool))
-	    return XML_ERROR_NO_MEMORY;
-	  *(pool->ptr)++ = buf[i];
-	}
+        XML_Char buf[XML_ENCODE_MAX];
+        int i;
+        int n = XmlCharRefNumber(enc, entityTextPtr);
+        if (n < 0) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_BAD_CHAR_REF;
+          goto endEntityValue;
+        }
+        n = XmlEncode(n, (ICHAR *)buf);
+        if (!n) {
+          if (enc == encoding)
+            eventPtr = entityTextPtr;
+          result = XML_ERROR_BAD_CHAR_REF;
+          goto endEntityValue;
+        }
+        for (i = 0; i < n; i++) {
+          if (pool->end == pool->ptr && !poolGrow(pool)) {
+            result = XML_ERROR_NO_MEMORY;
+            goto endEntityValue;
+          }
+          *(pool->ptr)++ = buf[i];
+        }
       }
       break;
     case XML_TOK_PARTIAL:
       if (enc == encoding)
-	eventPtr = entityTextPtr;
-      return XML_ERROR_INVALID_TOKEN;
+        eventPtr = entityTextPtr;
+      result = XML_ERROR_INVALID_TOKEN;
+      goto endEntityValue;
     case XML_TOK_INVALID:
       if (enc == encoding)
-	eventPtr = next;
-      return XML_ERROR_INVALID_TOKEN;
+        eventPtr = next;
+      result = XML_ERROR_INVALID_TOKEN;
+      goto endEntityValue;
     default:
       if (enc == encoding)
-	eventPtr = entityTextPtr;
-      return XML_ERROR_UNEXPECTED_STATE;
+        eventPtr = entityTextPtr;
+      result = XML_ERROR_UNEXPECTED_STATE;
+      goto endEntityValue;
     }
     entityTextPtr = next;
   }
-  /* not reached */
+endEntityValue:
+#ifdef XML_DTD
+  prologState.inEntityValue = oldInEntityValue;
+#endif /* XML_DTD */
+  return result;
 }
 
-static void
+static void FASTCALL
 normalizeLines(XML_Char *s)
 {
   XML_Char *p;
@@ -3632,7 +4688,8 @@
 }
 
 static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
+                            const char *start, const char *end)
 {
   const XML_Char *target;
   XML_Char *data;
@@ -3649,8 +4706,8 @@
     return 0;
   poolFinish(&tempPool);
   data = poolStoreString(&tempPool, enc,
-			XmlSkipS(enc, tem),
-			end - enc->minBytesPerChar*2);
+                        XmlSkipS(enc, tem),
+                        end - enc->minBytesPerChar*2);
   if (!data)
     return 0;
   normalizeLines(data);
@@ -3660,7 +4717,8 @@
 }
 
 static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+reportComment(XML_Parser parser, const ENCODING *enc,
+              const char *start, const char *end)
 {
   XML_Char *data;
   if (!commentHandler) {
@@ -3670,8 +4728,8 @@
   }
   data = poolStoreString(&tempPool,
                          enc,
-                         start + enc->minBytesPerChar * 4, 
-			 end - enc->minBytesPerChar * 3);
+                         start + enc->minBytesPerChar * 4,
+                         end - enc->minBytesPerChar * 3);
   if (!data)
     return 0;
   normalizeLines(data);
@@ -3681,7 +4739,8 @@
 }
 
 static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
+reportDefault(XML_Parser parser, const ENCODING *enc,
+              const char *s, const char *end)
 {
   if (MUST_CONVERT(enc, s)) {
     const char **eventPP;
@@ -3708,8 +4767,8 @@
 
 
 static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
-		int isId, const XML_Char *value, XML_Parser parser)
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
+                XML_Bool isId, const XML_Char *value, XML_Parser parser)
 {
   DEFAULT_ATTRIBUTE *att;
   if (value || isId) {
@@ -3718,53 +4777,62 @@
     int i;
     for (i = 0; i < type->nDefaultAtts; i++)
       if (attId == type->defaultAtts[i].id)
-	return 1;
+        return 1;
     if (isId && !type->idAtt && !attId->xmlns)
       type->idAtt = attId;
   }
   if (type->nDefaultAtts == type->allocDefaultAtts) {
     if (type->allocDefaultAtts == 0) {
       type->allocDefaultAtts = 8;
-      type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
+                            * sizeof(DEFAULT_ATTRIBUTE));
+      if (!type->defaultAtts)
+        return 0;
     }
     else {
-      type->allocDefaultAtts *= 2;
-      type->defaultAtts = REALLOC(type->defaultAtts,
-				  type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+      DEFAULT_ATTRIBUTE *temp;
+      int count = type->allocDefaultAtts * 2;
+      temp = (DEFAULT_ATTRIBUTE *)
+        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
+      if (temp == NULL)
+        return 0;
+      type->allocDefaultAtts = count;
+      type->defaultAtts = temp;
     }
-    if (!type->defaultAtts)
-      return 0;
   }
   att = type->defaultAtts + type->nDefaultAtts;
   att->id = attId;
   att->value = value;
   att->isCdata = isCdata;
   if (!isCdata)
-    attId->maybeTokenized = 1;
+    attId->maybeTokenized = XML_TRUE;
   type->nDefaultAtts += 1;
   return 1;
 }
 
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+static int
+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   const XML_Char *name;
   for (name = elementType->name; *name; name++) {
     if (*name == XML_T(':')) {
       PREFIX *prefix;
       const XML_Char *s;
       for (s = elementType->name; s != name; s++) {
-	if (!poolAppendChar(&dtd.pool, *s))
-	  return 0;
+        if (!poolAppendChar(&dtd->pool, *s))
+          return 0;
       }
-      if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-	return 0;
-      prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+        return 0;
+      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+                                sizeof(PREFIX));
       if (!prefix)
-	return 0;
-      if (prefix->name == poolStart(&dtd.pool))
-	poolFinish(&dtd.pool);
+        return 0;
+      if (prefix->name == poolStart(&dtd->pool))
+        poolFinish(&dtd->pool);
       else
-	poolDiscard(&dtd.pool);
+        poolDiscard(&dtd->pool);
       elementType->prefix = prefix;
 
     }
@@ -3773,55 +4841,60 @@
 }
 
 static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+getAttributeId(XML_Parser parser, const ENCODING *enc,
+               const char *start, const char *end)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   ATTRIBUTE_ID *id;
   const XML_Char *name;
-  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-    return 0;
-  name = poolStoreString(&dtd.pool, enc, start, end);
+  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+    return NULL;
+  name = poolStoreString(&dtd->pool, enc, start, end);
   if (!name)
-    return 0;
+    return NULL;
+  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
   ++name;
-  id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
+  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
   if (!id)
-    return 0;
+    return NULL;
   if (id->name != name)
-    poolDiscard(&dtd.pool);
+    poolDiscard(&dtd->pool);
   else {
-    poolFinish(&dtd.pool);
+    poolFinish(&dtd->pool);
     if (!ns)
       ;
-    else if (name[0] == 'x'
-	&& name[1] == 'm'
-	&& name[2] == 'l'
-	&& name[3] == 'n'
-	&& name[4] == 's'
-	&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
-      if (name[5] == '\0')
-	id->prefix = &dtd.defaultPrefix;
+    else if (name[0] == XML_T('x')
+        && name[1] == XML_T('m')
+        && name[2] == XML_T('l')
+        && name[3] == XML_T('n')
+        && name[4] == XML_T('s')
+        && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+      if (name[5] == XML_T('\0'))
+        id->prefix = &dtd->defaultPrefix;
       else
-	id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
-      id->xmlns = 1;
+        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
+      id->xmlns = XML_TRUE;
     }
     else {
       int i;
       for (i = 0; name[i]; i++) {
-	if (name[i] == XML_T(':')) {
-	  int j;
-	  for (j = 0; j < i; j++) {
-	    if (!poolAppendChar(&dtd.pool, name[j]))
-	      return 0;
-	  }
-	  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-	    return 0;
-	  id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
-	  if (id->prefix->name == poolStart(&dtd.pool))
-	    poolFinish(&dtd.pool);
-	  else
-	    poolDiscard(&dtd.pool);
-	  break;
-	}
+        /* attributes without prefix are *not* in the default namespace */
+        if (name[i] == XML_T(':')) {
+          int j;
+          for (j = 0; j < i; j++) {
+            if (!poolAppendChar(&dtd->pool, name[j]))
+              return NULL;
+          }
+          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
+            return NULL;
+          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
+                                        sizeof(PREFIX));
+          if (id->prefix->name == poolStart(&dtd->pool))
+            poolFinish(&dtd->pool);
+          else
+            poolDiscard(&dtd->pool);
+          break;
+        }
       }
     }
   }
@@ -3830,27 +4903,28 @@
 
 #define CONTEXT_SEP XML_T('\f')
 
-static
-const XML_Char *getContext(XML_Parser parser)
+static const XML_Char *
+getContext(XML_Parser parser)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   HASH_TABLE_ITER iter;
-  int needSep = 0;
+  XML_Bool needSep = XML_FALSE;
 
-  if (dtd.defaultPrefix.binding) {
+  if (dtd->defaultPrefix.binding) {
     int i;
     int len;
     if (!poolAppendChar(&tempPool, XML_T('=')))
-      return 0;
-    len = dtd.defaultPrefix.binding->uriLen;
+      return NULL;
+    len = dtd->defaultPrefix.binding->uriLen;
     if (namespaceSeparator != XML_T('\0'))
       len--;
     for (i = 0; i < len; i++)
-      if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
-  	return 0;
-    needSep = 1;
+      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
+        return NULL;
+    needSep = XML_TRUE;
   }
 
-  hashTableIterInit(&iter, &(dtd.prefixes));
+  hashTableIterInit(&iter, &(dtd->prefixes));
   for (;;) {
     int i;
     int len;
@@ -3861,23 +4935,23 @@
     if (!prefix->binding)
       continue;
     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-      return 0;
+      return NULL;
     for (s = prefix->name; *s; s++)
       if (!poolAppendChar(&tempPool, *s))
-        return 0;
+        return NULL;
     if (!poolAppendChar(&tempPool, XML_T('=')))
-      return 0;
+      return NULL;
     len = prefix->binding->uriLen;
     if (namespaceSeparator != XML_T('\0'))
       len--;
     for (i = 0; i < len; i++)
       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
-        return 0;
-    needSep = 1;
+        return NULL;
+    needSep = XML_TRUE;
   }
 
 
-  hashTableIterInit(&iter, &(dtd.generalEntities));
+  hashTableIterInit(&iter, &(dtd->generalEntities));
   for (;;) {
     const XML_Char *s;
     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
@@ -3886,77 +4960,81 @@
     if (!e->open)
       continue;
     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-      return 0;
+      return NULL;
     for (s = e->name; *s; s++)
       if (!poolAppendChar(&tempPool, *s))
         return 0;
-    needSep = 1;
+    needSep = XML_TRUE;
   }
 
   if (!poolAppendChar(&tempPool, XML_T('\0')))
-    return 0;
+    return NULL;
   return tempPool.start;
 }
 
-static
-int setContext(XML_Parser parser, const XML_Char *context)
+static XML_Bool
+setContext(XML_Parser parser, const XML_Char *context)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   const XML_Char *s = context;
 
   while (*context != XML_T('\0')) {
     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
       ENTITY *e;
       if (!poolAppendChar(&tempPool, XML_T('\0')))
-	return 0;
-      e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
+        return XML_FALSE;
+      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
       if (e)
-	e->open = 1;
+        e->open = XML_TRUE;
       if (*s != XML_T('\0'))
-	s++;
+        s++;
       context = s;
       poolDiscard(&tempPool);
     }
-    else if (*s == '=') {
+    else if (*s == XML_T('=')) {
       PREFIX *prefix;
       if (poolLength(&tempPool) == 0)
-	prefix = &dtd.defaultPrefix;
+        prefix = &dtd->defaultPrefix;
       else {
-	if (!poolAppendChar(&tempPool, XML_T('\0')))
-	  return 0;
-	prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
-	if (!prefix)
-	  return 0;
+        if (!poolAppendChar(&tempPool, XML_T('\0')))
+          return XML_FALSE;
+        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
+                                  sizeof(PREFIX));
+        if (!prefix)
+          return XML_FALSE;
         if (prefix->name == poolStart(&tempPool)) {
-	  prefix->name = poolCopyString(&dtd.pool, prefix->name);
-	  if (!prefix->name)
-	    return 0;
-	}
-	poolDiscard(&tempPool);
+          prefix->name = poolCopyString(&dtd->pool, prefix->name);
+          if (!prefix->name)
+            return XML_FALSE;
+        }
+        poolDiscard(&tempPool);
       }
-      for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
+      for (context = s + 1;
+           *context != CONTEXT_SEP && *context != XML_T('\0');
+           context++)
         if (!poolAppendChar(&tempPool, *context))
-          return 0;
+          return XML_FALSE;
       if (!poolAppendChar(&tempPool, XML_T('\0')))
-	return 0;
-      if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
-	return 0;
+        return XML_FALSE;
+      if (addBinding(parser, prefix, 0, poolStart(&tempPool),
+                     &inheritedBindings) != XML_ERROR_NONE)
+        return XML_FALSE;
       poolDiscard(&tempPool);
       if (*context != XML_T('\0'))
-	++context;
+        ++context;
       s = context;
     }
     else {
       if (!poolAppendChar(&tempPool, *s))
-	return 0;
+        return XML_FALSE;
       s++;
     }
   }
-  return 1;
+  return XML_TRUE;
 }
 
-
-static
-void normalizePublicId(XML_Char *publicId)
+static void FASTCALL
+normalizePublicId(XML_Char *publicId)
 {
   XML_Char *p = publicId;
   XML_Char *s;
@@ -3966,7 +5044,7 @@
     case 0xD:
     case 0xA:
       if (p != publicId && p[-1] != 0x20)
-	*p++ = 0x20;
+        *p++ = 0x20;
       break;
     default:
       *p++ = *s;
@@ -3977,46 +5055,43 @@
   *p = XML_T('\0');
 }
 
-static int dtdInit(DTD *p, XML_Parser parser)
+static DTD *
+dtdCreate(const XML_Memory_Handling_Suite *ms)
 {
-  XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem; 
+  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
+  if (p == NULL)
+    return p;
   poolInit(&(p->pool), ms);
+#ifdef XML_DTD
+  poolInit(&(p->entityValuePool), ms);
+#endif /* XML_DTD */
   hashTableInit(&(p->generalEntities), ms);
   hashTableInit(&(p->elementTypes), ms);
   hashTableInit(&(p->attributeIds), ms);
   hashTableInit(&(p->prefixes), ms);
-  p->complete = 1;
-  p->standalone = 0;
 #ifdef XML_DTD
+  p->paramEntityRead = XML_FALSE;
   hashTableInit(&(p->paramEntities), ms);
 #endif /* XML_DTD */
-  p->defaultPrefix.name = 0;
-  p->defaultPrefix.binding = 0;
+  p->defaultPrefix.name = NULL;
+  p->defaultPrefix.binding = NULL;
 
-  p->in_eldecl = 0;
-  p->scaffIndex = 0;
+  p->in_eldecl = XML_FALSE;
+  p->scaffIndex = NULL;
+  p->scaffold = NULL;
   p->scaffLevel = 0;
-  p->scaffold = 0;
-  p->contentStringLen = 0;
   p->scaffSize = 0;
   p->scaffCount = 0;
+  p->contentStringLen = 0;
 
-  return 1;
+  p->keepProcessing = XML_TRUE;
+  p->hasParamEntityRefs = XML_FALSE;
+  p->standalone = XML_FALSE;
+  return p;
 }
 
-#ifdef XML_DTD
-
-static void dtdSwap(DTD *p1, DTD *p2)
-{
-  DTD tem;
-  memcpy(&tem, p1, sizeof(DTD));
-  memcpy(p1, p2, sizeof(DTD));
-  memcpy(p2, &tem, sizeof(DTD));
-}
-
-#endif /* XML_DTD */
-
-static void dtdDestroy(DTD *p, XML_Parser parser)
+static void
+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
 {
   HASH_TABLE_ITER iter;
   hashTableIterInit(&iter, &(p->elementTypes));
@@ -4025,7 +5100,51 @@
     if (!e)
       break;
     if (e->allocDefaultAtts != 0)
-      FREE(e->defaultAtts);
+      ms->free_fcn(e->defaultAtts);
+  }
+  hashTableClear(&(p->generalEntities));
+#ifdef XML_DTD
+  p->paramEntityRead = XML_FALSE;
+  hashTableClear(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableClear(&(p->elementTypes));
+  hashTableClear(&(p->attributeIds));
+  hashTableClear(&(p->prefixes));
+  poolClear(&(p->pool));
+#ifdef XML_DTD
+  poolClear(&(p->entityValuePool));
+#endif /* XML_DTD */
+  p->defaultPrefix.name = NULL;
+  p->defaultPrefix.binding = NULL;
+
+  p->in_eldecl = XML_FALSE;
+
+  ms->free_fcn(p->scaffIndex);
+  p->scaffIndex = NULL;
+  ms->free_fcn(p->scaffold);
+  p->scaffold = NULL;
+
+  p->scaffLevel = 0;
+  p->scaffSize = 0;
+  p->scaffCount = 0;
+  p->contentStringLen = 0;
+
+  p->keepProcessing = XML_TRUE;
+  p->hasParamEntityRefs = XML_FALSE;
+  p->standalone = XML_FALSE;
+}
+
+static void
+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      ms->free_fcn(e->defaultAtts);
   }
   hashTableDestroy(&(p->generalEntities));
 #ifdef XML_DTD
@@ -4035,16 +5154,21 @@
   hashTableDestroy(&(p->attributeIds));
   hashTableDestroy(&(p->prefixes));
   poolDestroy(&(p->pool));
-  if (p->scaffIndex)
-    FREE(p->scaffIndex);
-  if (p->scaffold)
-    FREE(p->scaffold);
+#ifdef XML_DTD
+  poolDestroy(&(p->entityValuePool));
+#endif /* XML_DTD */
+  if (isDocEntity) {
+    ms->free_fcn(p->scaffIndex);
+    ms->free_fcn(p->scaffold);
+  }
+  ms->free_fcn(p);
 }
 
-/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
-The new DTD has already been initialized. */
-
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
+/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
+   The new DTD has already been initialized.
+*/
+static int
+dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
 {
   HASH_TABLE_ITER iter;
 
@@ -4081,16 +5205,18 @@
     if (!name)
       return 0;
     ++name;
-    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
+                                  sizeof(ATTRIBUTE_ID));
     if (!newA)
       return 0;
     newA->maybeTokenized = oldA->maybeTokenized;
     if (oldA->prefix) {
       newA->xmlns = oldA->xmlns;
       if (oldA->prefix == &oldDtd->defaultPrefix)
-	newA->prefix = &newDtd->defaultPrefix;
+        newA->prefix = &newDtd->defaultPrefix;
       else
-	newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
+        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+                                        oldA->prefix->name, 0);
     }
   }
 
@@ -4108,46 +5234,56 @@
     name = poolCopyString(&(newDtd->pool), oldE->name);
     if (!name)
       return 0;
-    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
+                                  sizeof(ELEMENT_TYPE));
     if (!newE)
       return 0;
     if (oldE->nDefaultAtts) {
-      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
-      if (!newE->defaultAtts)
-	return 0;
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
+          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (!newE->defaultAtts) {
+        ms->free_fcn(newE);
+        return 0;
+      }
     }
     if (oldE->idAtt)
-      newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+      newE->idAtt = (ATTRIBUTE_ID *)
+          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
     if (oldE->prefix)
-      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
+                                      oldE->prefix->name, 0);
     for (i = 0; i < newE->nDefaultAtts; i++) {
-      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
+          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
       if (oldE->defaultAtts[i].value) {
-	newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
-	if (!newE->defaultAtts[i].value)
-  	  return 0;
+        newE->defaultAtts[i].value
+            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+        if (!newE->defaultAtts[i].value)
+          return 0;
       }
       else
-	newE->defaultAtts[i].value = 0;
+        newE->defaultAtts[i].value = NULL;
     }
   }
 
   /* Copy the entity tables. */
   if (!copyEntityTable(&(newDtd->generalEntities),
-		       &(newDtd->pool),
-		       &(oldDtd->generalEntities), parser))
+                       &(newDtd->pool),
+                       &(oldDtd->generalEntities)))
       return 0;
 
 #ifdef XML_DTD
   if (!copyEntityTable(&(newDtd->paramEntities),
-		       &(newDtd->pool),
-		       &(oldDtd->paramEntities), parser))
+                       &(newDtd->pool),
+                       &(oldDtd->paramEntities)))
       return 0;
+  newDtd->paramEntityRead = oldDtd->paramEntityRead;
 #endif /* XML_DTD */
 
-  newDtd->complete = oldDtd->complete;
+  newDtd->keepProcessing = oldDtd->keepProcessing;
+  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
   newDtd->standalone = oldDtd->standalone;
 
   /* Don't want deep copying for scaffolding */
@@ -4161,14 +5297,14 @@
   return 1;
 }  /* End dtdCopy */
 
-static int copyEntityTable(HASH_TABLE *newTable,
-			   STRING_POOL *newPool,
-			   const HASH_TABLE *oldTable,
-			   XML_Parser parser)
+static int
+copyEntityTable(HASH_TABLE *newTable,
+                STRING_POOL *newPool,
+                const HASH_TABLE *oldTable)
 {
   HASH_TABLE_ITER iter;
-  const XML_Char *cachedOldBase = 0;
-  const XML_Char *cachedNewBase = 0;
+  const XML_Char *cachedOldBase = NULL;
+  const XML_Char *cachedNewBase = NULL;
 
   hashTableIterInit(&iter, oldTable);
 
@@ -4187,176 +5323,204 @@
     if (oldE->systemId) {
       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
       if (!tem)
-	return 0;
+        return 0;
       newE->systemId = tem;
       if (oldE->base) {
-	if (oldE->base == cachedOldBase)
-	  newE->base = cachedNewBase;
-	else {
-	  cachedOldBase = oldE->base;
-	  tem = poolCopyString(newPool, cachedOldBase);
-	  if (!tem)
-	    return 0;
-	  cachedNewBase = newE->base = tem;
-	}
+        if (oldE->base == cachedOldBase)
+          newE->base = cachedNewBase;
+        else {
+          cachedOldBase = oldE->base;
+          tem = poolCopyString(newPool, cachedOldBase);
+          if (!tem)
+            return 0;
+          cachedNewBase = newE->base = tem;
+        }
+      }
+      if (oldE->publicId) {
+        tem = poolCopyString(newPool, oldE->publicId);
+        if (!tem)
+          return 0;
+        newE->publicId = tem;
       }
     }
     else {
-      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
+                                            oldE->textLen);
       if (!tem)
-	return 0;
+        return 0;
       newE->textPtr = tem;
       newE->textLen = oldE->textLen;
     }
     if (oldE->notation) {
       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
       if (!tem)
-	return 0;
+        return 0;
       newE->notation = tem;
     }
+    newE->is_param = oldE->is_param;
+    newE->is_internal = oldE->is_internal;
   }
   return 1;
 }
 
-#define INIT_SIZE 64
+#define INIT_POWER 6
 
-static
-int keyeq(KEY s1, KEY s2)
+static XML_Bool FASTCALL
+keyeq(KEY s1, KEY s2)
 {
   for (; *s1 == *s2; s1++, s2++)
     if (*s1 == 0)
-      return 1;
-  return 0;
+      return XML_TRUE;
+  return XML_FALSE;
 }
 
-static
-unsigned long hash(KEY s)
+static unsigned long FASTCALL
+hash(KEY s)
 {
   unsigned long h = 0;
   while (*s)
-    h = (h << 5) + h + (unsigned char)*s++;
+    h = CHAR_HASH(h, *s++);
   return h;
 }
 
-static
-NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
+static NAMED *
+lookup(HASH_TABLE *table, KEY name, size_t createSize)
 {
   size_t i;
   if (table->size == 0) {
     size_t tsize;
-
     if (!createSize)
-      return 0;
-    tsize = INIT_SIZE * sizeof(NAMED *);
-    table->v = table->mem->malloc_fcn(tsize);
+      return NULL;
+    table->power = INIT_POWER;
+    /* table->size is a power of 2 */
+    table->size = (size_t)1 << INIT_POWER;
+    tsize = table->size * sizeof(NAMED *);
+    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
     if (!table->v)
-      return 0;
+      return NULL;
     memset(table->v, 0, tsize);
-    table->size = INIT_SIZE;
-    table->usedLim = INIT_SIZE / 2;
-    i = hash(name) & (table->size - 1);
+    i = hash(name) & ((unsigned long)table->size - 1);
   }
   else {
     unsigned long h = hash(name);
-    for (i = h & (table->size - 1);
-         table->v[i];
-         i == 0 ? i = table->size - 1 : --i) {
+    unsigned long mask = (unsigned long)table->size - 1;
+    unsigned char step = 0;
+    i = h & mask;
+    while (table->v[i]) {
       if (keyeq(name, table->v[i]->name))
-	return table->v[i];
+        return table->v[i];
+      if (!step)
+        step = PROBE_STEP(h, mask, table->power);
+      i < step ? (i += table->size - step) : (i -= step);
     }
     if (!createSize)
-      return 0;
-    if (table->used == table->usedLim) {
-      /* check for overflow */
-      size_t newSize = table->size * 2;
+      return NULL;
+
+    /* check for overflow (table is half full) */
+    if (table->used >> (table->power - 1)) {
+      unsigned char newPower = table->power + 1;
+      size_t newSize = (size_t)1 << newPower;
+      unsigned long newMask = (unsigned long)newSize - 1;
       size_t tsize = newSize * sizeof(NAMED *);
-      NAMED **newV = table->mem->malloc_fcn(tsize);
+      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
       if (!newV)
-	return 0;
+        return NULL;
       memset(newV, 0, tsize);
       for (i = 0; i < table->size; i++)
-	if (table->v[i]) {
-	  size_t j;
-	  for (j = hash(table->v[i]->name) & (newSize - 1);
-	       newV[j];
-	       j == 0 ? j = newSize - 1 : --j)
-	    ;
-	  newV[j] = table->v[i];
-	}
+        if (table->v[i]) {
+          unsigned long newHash = hash(table->v[i]->name);
+          size_t j = newHash & newMask;
+          step = 0;
+          while (newV[j]) {
+            if (!step)
+              step = PROBE_STEP(newHash, newMask, newPower);
+            j < step ? (j += newSize - step) : (j -= step);
+          }
+          newV[j] = table->v[i];
+        }
       table->mem->free_fcn(table->v);
       table->v = newV;
+      table->power = newPower;
       table->size = newSize;
-      table->usedLim = newSize/2;
-      for (i = h & (table->size - 1);
-	   table->v[i];
-	   i == 0 ? i = table->size - 1 : --i)
-	;
+      i = h & newMask;
+      step = 0;
+      while (table->v[i]) {
+        if (!step)
+          step = PROBE_STEP(h, newMask, newPower);
+        i < step ? (i += newSize - step) : (i -= step);
+      }
     }
   }
-  table->v[i] = table->mem->malloc_fcn(createSize);
+  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
   if (!table->v[i])
-    return 0;
+    return NULL;
   memset(table->v[i], 0, createSize);
   table->v[i]->name = name;
   (table->used)++;
   return table->v[i];
 }
 
-static
-void hashTableDestroy(HASH_TABLE *table)
+static void FASTCALL
+hashTableClear(HASH_TABLE *table)
 {
   size_t i;
   for (i = 0; i < table->size; i++) {
-    NAMED *p = table->v[i];
-    if (p)
-      table->mem->free_fcn(p);
+    table->mem->free_fcn(table->v[i]);
+    table->v[i] = NULL;
   }
-  if (table->v)
-    table->mem->free_fcn(table->v);
+  table->used = 0;
 }
 
-static
-void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
+static void FASTCALL
+hashTableDestroy(HASH_TABLE *table)
 {
+  size_t i;
+  for (i = 0; i < table->size; i++)
+    table->mem->free_fcn(table->v[i]);
+  table->mem->free_fcn(table->v);
+}
+
+static void FASTCALL
+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
+{
+  p->power = 0;
   p->size = 0;
-  p->usedLim = 0;
   p->used = 0;
-  p->v = 0;
+  p->v = NULL;
   p->mem = ms;
 }
 
-static
-void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+static void FASTCALL
+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
 {
   iter->p = table->v;
   iter->end = iter->p + table->size;
 }
 
-static
-NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
+static NAMED * FASTCALL
+hashTableIterNext(HASH_TABLE_ITER *iter)
 {
   while (iter->p != iter->end) {
     NAMED *tem = *(iter->p)++;
     if (tem)
       return tem;
   }
-  return 0;
+  return NULL;
 }
 
-
-static
-void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
+static void FASTCALL
+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
 {
-  pool->blocks = 0;
-  pool->freeBlocks = 0;
-  pool->start = 0;
-  pool->ptr = 0;
-  pool->end = 0;
+  pool->blocks = NULL;
+  pool->freeBlocks = NULL;
+  pool->start = NULL;
+  pool->ptr = NULL;
+  pool->end = NULL;
   pool->mem = ms;
 }
 
-static
-void poolClear(STRING_POOL *pool)
+static void FASTCALL
+poolClear(STRING_POOL *pool)
 {
   if (!pool->freeBlocks)
     pool->freeBlocks = pool->blocks;
@@ -4369,14 +5533,14 @@
       p = tem;
     }
   }
-  pool->blocks = 0;
-  pool->start = 0;
-  pool->ptr = 0;
-  pool->end = 0;
+  pool->blocks = NULL;
+  pool->start = NULL;
+  pool->ptr = NULL;
+  pool->end = NULL;
 }
 
-static
-void poolDestroy(STRING_POOL *pool)
+static void FASTCALL
+poolDestroy(STRING_POOL *pool)
 {
   BLOCK *p = pool->blocks;
   while (p) {
@@ -4384,113 +5548,113 @@
     pool->mem->free_fcn(p);
     p = tem;
   }
-  pool->blocks = 0;
   p = pool->freeBlocks;
   while (p) {
     BLOCK *tem = p->next;
     pool->mem->free_fcn(p);
     p = tem;
   }
-  pool->freeBlocks = 0;
-  pool->ptr = 0;
-  pool->start = 0;
-  pool->end = 0;
 }
 
-static
-XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-		     const char *ptr, const char *end)
+static XML_Char *
+poolAppend(STRING_POOL *pool, const ENCODING *enc,
+           const char *ptr, const char *end)
 {
   if (!pool->ptr && !poolGrow(pool))
-    return 0;
+    return NULL;
   for (;;) {
     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
     if (ptr == end)
       break;
     if (!poolGrow(pool))
-      return 0;
+      return NULL;
   }
   return pool->start;
 }
 
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
+static const XML_Char * FASTCALL
+poolCopyString(STRING_POOL *pool, const XML_Char *s)
 {
   do {
     if (!poolAppendChar(pool, *s))
-      return 0;
+      return NULL;
   } while (*s++);
   s = pool->start;
   poolFinish(pool);
   return s;
 }
 
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+static const XML_Char *
+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
 {
   if (!pool->ptr && !poolGrow(pool))
-    return 0;
+    return NULL;
   for (; n > 0; --n, s++) {
     if (!poolAppendChar(pool, *s))
-      return 0;
-
+      return NULL;
   }
   s = pool->start;
   poolFinish(pool);
   return s;
 }
 
-static
-const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
+static const XML_Char * FASTCALL
+poolAppendString(STRING_POOL *pool, const XML_Char *s)
 {
   while (*s) {
     if (!poolAppendChar(pool, *s))
-      return 0;
+      return NULL;
     s++;
-  } 
+  }
   return pool->start;
-}  /* End poolAppendString */
+}
 
-static
-XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-			  const char *ptr, const char *end)
+static XML_Char *
+poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                const char *ptr, const char *end)
 {
   if (!poolAppend(pool, enc, ptr, end))
-    return 0;
+    return NULL;
   if (pool->ptr == pool->end && !poolGrow(pool))
-    return 0;
+    return NULL;
   *(pool->ptr)++ = 0;
   return pool->start;
 }
 
-static
-int poolGrow(STRING_POOL *pool)
+static XML_Bool FASTCALL
+poolGrow(STRING_POOL *pool)
 {
   if (pool->freeBlocks) {
     if (pool->start == 0) {
       pool->blocks = pool->freeBlocks;
       pool->freeBlocks = pool->freeBlocks->next;
-      pool->blocks->next = 0;
+      pool->blocks->next = NULL;
       pool->start = pool->blocks->s;
       pool->end = pool->start + pool->blocks->size;
       pool->ptr = pool->start;
-      return 1;
+      return XML_TRUE;
     }
     if (pool->end - pool->start < pool->freeBlocks->size) {
       BLOCK *tem = pool->freeBlocks->next;
       pool->freeBlocks->next = pool->blocks;
       pool->blocks = pool->freeBlocks;
       pool->freeBlocks = tem;
-      memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
+      memcpy(pool->blocks->s, pool->start,
+             (pool->end - pool->start) * sizeof(XML_Char));
       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
       pool->start = pool->blocks->s;
       pool->end = pool->start + pool->blocks->size;
-      return 1;
+      return XML_TRUE;
     }
   }
   if (pool->blocks && pool->start == pool->blocks->s) {
     int blockSize = (pool->end - pool->start)*2;
-    pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
-    if (!pool->blocks)
-      return 0;
+    pool->blocks = (BLOCK *)
+      pool->mem->realloc_fcn(pool->blocks,
+                             (offsetof(BLOCK, s)
+                              + blockSize * sizeof(XML_Char)));
+    if (pool->blocks == NULL)
+      return XML_FALSE;
     pool->blocks->size = blockSize;
     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
     pool->start = pool->blocks->s;
@@ -4503,139 +5667,151 @@
       blockSize = INIT_BLOCK_SIZE;
     else
       blockSize *= 2;
-    tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
+                                        + blockSize * sizeof(XML_Char));
     if (!tem)
-      return 0;
+      return XML_FALSE;
     tem->size = blockSize;
     tem->next = pool->blocks;
     pool->blocks = tem;
     if (pool->ptr != pool->start)
-      memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
+      memcpy(tem->s, pool->start,
+             (pool->ptr - pool->start) * sizeof(XML_Char));
     pool->ptr = tem->s + (pool->ptr - pool->start);
     pool->start = tem->s;
     pool->end = tem->s + blockSize;
   }
-  return 1;
+  return XML_TRUE;
 }
 
-static int
+static int FASTCALL
 nextScaffoldPart(XML_Parser parser)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   CONTENT_SCAFFOLD * me;
   int next;
 
-  if (! dtd.scaffIndex) {
-    dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
-    if (! dtd.scaffIndex)
+  if (!dtd->scaffIndex) {
+    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
+    if (!dtd->scaffIndex)
       return -1;
-    dtd.scaffIndex[0] = 0;
+    dtd->scaffIndex[0] = 0;
   }
 
-  if (dtd.scaffCount >= dtd.scaffSize) {
-    if (dtd.scaffold) {
-      dtd.scaffSize *= 2;
-      dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
-					      dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+  if (dtd->scaffCount >= dtd->scaffSize) {
+    CONTENT_SCAFFOLD *temp;
+    if (dtd->scaffold) {
+      temp = (CONTENT_SCAFFOLD *)
+        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
+      if (temp == NULL)
+        return -1;
+      dtd->scaffSize *= 2;
     }
     else {
-      dtd.scaffSize = 32;
-      dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
+                                        * sizeof(CONTENT_SCAFFOLD));
+      if (temp == NULL)
+        return -1;
+      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
     }
-    if (! dtd.scaffold)
-      return -1;
+    dtd->scaffold = temp;
   }
-  next = dtd.scaffCount++;
-  me = &dtd.scaffold[next];
-  if (dtd.scaffLevel) { 
-    CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
+  next = dtd->scaffCount++;
+  me = &dtd->scaffold[next];
+  if (dtd->scaffLevel) {
+    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
     if (parent->lastchild) {
-      dtd.scaffold[parent->lastchild].nextsib = next;
+      dtd->scaffold[parent->lastchild].nextsib = next;
     }
-    if (! parent->childcnt)
+    if (!parent->childcnt)
       parent->firstchild = next;
     parent->lastchild = next;
     parent->childcnt++;
   }
   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
   return next;
-}  /* End nextScaffoldPart */
+}
 
 static void
-build_node (XML_Parser parser,
-	    int src_node,
-	    XML_Content *dest,
-	    XML_Content **contpos,
-	    char **strpos)
+build_node(XML_Parser parser,
+           int src_node,
+           XML_Content *dest,
+           XML_Content **contpos,
+           XML_Char **strpos)
 {
-  dest->type = dtd.scaffold[src_node].type;
-  dest->quant = dtd.scaffold[src_node].quant;
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  dest->type = dtd->scaffold[src_node].type;
+  dest->quant = dtd->scaffold[src_node].quant;
   if (dest->type == XML_CTYPE_NAME) {
-    const char *src;
+    const XML_Char *src;
     dest->name = *strpos;
-    src = dtd.scaffold[src_node].name;
+    src = dtd->scaffold[src_node].name;
     for (;;) {
       *(*strpos)++ = *src;
-      if (! *src)
-	break;
+      if (!*src)
+        break;
       src++;
     }
     dest->numchildren = 0;
-    dest->children = 0;
+    dest->children = NULL;
   }
   else {
     unsigned int i;
     int cn;
-    dest->numchildren = dtd.scaffold[src_node].childcnt;
+    dest->numchildren = dtd->scaffold[src_node].childcnt;
     dest->children = *contpos;
     *contpos += dest->numchildren;
-    for (i = 0, cn = dtd.scaffold[src_node].firstchild;
-	 i < dest->numchildren;
-	 i++, cn = dtd.scaffold[cn].nextsib) {
+    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
+         i < dest->numchildren;
+         i++, cn = dtd->scaffold[cn].nextsib) {
       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
     }
-    dest->name = 0;
+    dest->name = NULL;
   }
-}  /* End build_node */
+}
 
 static XML_Content *
 build_model (XML_Parser parser)
 {
+  DTD * const dtd = _dtd;  /* save one level of indirection */
   XML_Content *ret;
   XML_Content *cpos;
-  char * str;
-  int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
-  
-  ret = MALLOC(allocsize);
-  if (! ret)
-    return 0;
+  XML_Char * str;
+  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
+                   + (dtd->contentStringLen * sizeof(XML_Char)));
 
-  str =  (char *) (&ret[dtd.scaffCount]);
+  ret = (XML_Content *)MALLOC(allocsize);
+  if (!ret)
+    return NULL;
+
+  str =  (XML_Char *) (&ret[dtd->scaffCount]);
   cpos = &ret[1];
 
   build_node(parser, 0, ret, &cpos, &str);
   return ret;
-}  /* End build_model */
+}
 
 static ELEMENT_TYPE *
 getElementType(XML_Parser parser,
-	       const ENCODING *enc,
-	       const char *ptr,
-	       const char *end)
+               const ENCODING *enc,
+               const char *ptr,
+               const char *end)
 {
-  const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
+  DTD * const dtd = _dtd;  /* save one level of indirection */
+  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
   ELEMENT_TYPE *ret;
 
-  if (! name)
-    return 0;
-  ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
-  if (! ret)
-    return 0;
+  if (!name)
+    return NULL;
+  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
+  if (!ret)
+    return NULL;
   if (ret->name != name)
-    poolDiscard(&dtd.pool);
+    poolDiscard(&dtd->pool);
   else {
-    poolFinish(&dtd.pool);
+    poolFinish(&dtd->pool);
     if (!setElementTypePrefix(parser, ret))
-      return 0;
+      return NULL;
   }
   return ret;
-}  /* End getElementType */
+}
diff --git a/xml/expat/lib/xmlrole.c b/xml/expat/lib/xmlrole.c
index ac13039..83c0d71 100644
--- a/xml/expat/lib/xmlrole.c
+++ b/xml/expat/lib/xmlrole.c
@@ -1,17 +1,18 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
-static char RCSId[]
-  = "$Header: /home/cvs/apr-util/xml/expat/lib/xmlrole.c,v 1.1 2001/02/28 14:41:26 gstein Exp $";
-
 #ifdef COMPILED_FROM_DSP
-#  include "winconfig.h"
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
 #else
-#  include <config.h>
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
 #endif /* ndef COMPILED_FROM_DSP */
 
+#include "internal.h"
 #include "xmlrole.h"
 #include "ascii.h"
 
@@ -22,29 +23,56 @@
 
 */
 
-static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' };
-static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
-static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
-static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
-static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
-static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
-static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
-static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' };
-static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
-static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
-static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
-static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
-static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
-static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' };
-static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
-static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' };
-static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+static const char KW_ANY[] = {
+    ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = {
+    ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = {
+    ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = {
+    ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = {
+    ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = {
+    ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = {
+    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
+    '\0' };
+static const char KW_ENTITY[] = {
+    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = {
+    ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = {
+    ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = {
+    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = {
+    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = {
+    ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = {
+    ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = {
+    ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = {
+    ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = {
+    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = {
+    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
+    '\0' };
+static const char KW_NOTATION[] =
+    { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
+      '\0' };
+static const char KW_PCDATA[] = {
+    ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = {
+    ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = {
+    ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
+    '\0' };
+static const char KW_SYSTEM[] = {
+    ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
 
 #ifndef MIN_BYTES_PER_CHAR
 #define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
@@ -59,18 +87,18 @@
 #define setTopLevel(state) ((state)->handler = internalSubset)
 #endif /* not XML_DTD */
 
-typedef int PROLOG_HANDLER(PROLOG_STATE *state,
-			   int tok,
-			   const char *ptr,
-			   const char *end,
-			   const ENCODING *enc);
+typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state,
+                                   int tok,
+                                   const char *ptr,
+                                   const char *end,
+                                   const ENCODING *enc);
 
 static PROLOG_HANDLER
   prolog0, prolog1, prolog2,
   doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
   internalSubset,
   entity0, entity1, entity2, entity3, entity4, entity5, entity6,
-  entity7, entity8, entity9,
+  entity7, entity8, entity9, entity10,
   notation0, notation1, notation2, notation3, notation4,
   attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
   attlist7, attlist8, attlist9,
@@ -83,15 +111,14 @@
   declClose,
   error;
 
-static
-int common(PROLOG_STATE *state, int tok);
+static int FASTCALL common(PROLOG_STATE *state, int tok);
 
-static
-int prolog0(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+prolog0(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -102,19 +129,20 @@
     return XML_ROLE_XML_DECL;
   case XML_TOK_PI:
     state->handler = prolog1;
-    return XML_ROLE_NONE;
+    return XML_ROLE_PI;
   case XML_TOK_COMMENT:
     state->handler = prolog1;
+    return XML_ROLE_COMMENT;
   case XML_TOK_BOM:
     return XML_ROLE_NONE;
   case XML_TOK_DECL_OPEN:
     if (!XmlNameMatchesAscii(enc,
-			     ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			     end,
-			     KW_DOCTYPE))
+                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                             end,
+                             KW_DOCTYPE))
       break;
     state->handler = doctype0;
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_INSTANCE_START:
     state->handler = error;
     return XML_ROLE_INSTANCE_START;
@@ -122,28 +150,30 @@
   return common(state, tok);
 }
 
-static
-int prolog1(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+prolog1(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
   case XML_TOK_PI:
+    return XML_ROLE_PI;
   case XML_TOK_COMMENT:
+    return XML_ROLE_COMMENT;
   case XML_TOK_BOM:
     return XML_ROLE_NONE;
   case XML_TOK_DECL_OPEN:
     if (!XmlNameMatchesAscii(enc,
-			     ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			     end,
-			     KW_DOCTYPE))
+                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                             end,
+                             KW_DOCTYPE))
       break;
     state->handler = doctype0;
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_INSTANCE_START:
     state->handler = error;
     return XML_ROLE_INSTANCE_START;
@@ -151,19 +181,20 @@
   return common(state, tok);
 }
 
-static
-int prolog2(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+prolog2(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
   case XML_TOK_PI:
+    return XML_ROLE_PI;
   case XML_TOK_COMMENT:
-    return XML_ROLE_NONE;
+    return XML_ROLE_COMMENT;
   case XML_TOK_INSTANCE_START:
     state->handler = error;
     return XML_ROLE_INSTANCE_START;
@@ -171,16 +202,16 @@
   return common(state, tok);
 }
 
-static
-int doctype0(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
     state->handler = doctype1;
@@ -189,16 +220,16 @@
   return common(state, tok);
 }
 
-static
-int doctype1(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_OPEN_BRACKET:
     state->handler = internalSubset;
     return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
@@ -208,27 +239,27 @@
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
       state->handler = doctype3;
-      return XML_ROLE_NONE;
+      return XML_ROLE_DOCTYPE_NONE;
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
       state->handler = doctype2;
-      return XML_ROLE_NONE;
+      return XML_ROLE_DOCTYPE_NONE;
     }
     break;
   }
   return common(state, tok);
 }
 
-static
-int doctype2(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_LITERAL:
     state->handler = doctype3;
     return XML_ROLE_DOCTYPE_PUBLIC_ID;
@@ -236,16 +267,16 @@
   return common(state, tok);
 }
 
-static
-int doctype3(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_LITERAL:
     state->handler = doctype4;
     return XML_ROLE_DOCTYPE_SYSTEM_ID;
@@ -253,16 +284,16 @@
   return common(state, tok);
 }
 
-static
-int doctype4(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_OPEN_BRACKET:
     state->handler = internalSubset;
     return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
@@ -273,16 +304,16 @@
   return common(state, tok);
 }
 
-static
-int doctype5(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+doctype5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   case XML_TOK_DECL_CLOSE:
     state->handler = prolog2;
     return XML_ROLE_DOCTYPE_CLOSE;
@@ -290,66 +321,67 @@
   return common(state, tok);
 }
 
-static
-int internalSubset(PROLOG_STATE *state,
-		   int tok,
-		   const char *ptr,
-		   const char *end,
-		   const ENCODING *enc)
+static int PTRCALL
+internalSubset(PROLOG_STATE *state,
+               int tok,
+               const char *ptr,
+               const char *end,
+               const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
     return XML_ROLE_NONE;
   case XML_TOK_DECL_OPEN:
     if (XmlNameMatchesAscii(enc,
-			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_ENTITY)) {
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ENTITY)) {
       state->handler = entity0;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     if (XmlNameMatchesAscii(enc,
-			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_ATTLIST)) {
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ATTLIST)) {
       state->handler = attlist0;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ATTLIST_NONE;
     }
     if (XmlNameMatchesAscii(enc,
-			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_ELEMENT)) {
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_ELEMENT)) {
       state->handler = element0;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ELEMENT_NONE;
     }
     if (XmlNameMatchesAscii(enc,
-			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_NOTATION)) {
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_NOTATION)) {
       state->handler = notation0;
-      return XML_ROLE_NONE;
+      return XML_ROLE_NOTATION_NONE;
     }
     break;
   case XML_TOK_PI:
+    return XML_ROLE_PI;
   case XML_TOK_COMMENT:
-    return XML_ROLE_NONE;
+    return XML_ROLE_COMMENT;
   case XML_TOK_PARAM_ENTITY_REF:
     return XML_ROLE_PARAM_ENTITY_REF;
   case XML_TOK_CLOSE_BRACKET:
     state->handler = doctype5;
-    return XML_ROLE_NONE;
+    return XML_ROLE_DOCTYPE_NONE;
   }
   return common(state, tok);
 }
 
 #ifdef XML_DTD
 
-static
-int externalSubset0(PROLOG_STATE *state,
-		    int tok,
-		    const char *ptr,
-		    const char *end,
-		    const ENCODING *enc)
+static int PTRCALL
+externalSubset0(PROLOG_STATE *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc)
 {
   state->handler = externalSubset1;
   if (tok == XML_TOK_XML_DECL)
@@ -357,12 +389,12 @@
   return externalSubset1(state, tok, ptr, end, enc);
 }
 
-static
-int externalSubset1(PROLOG_STATE *state,
-		    int tok,
-		    const char *ptr,
-		    const char *end,
-		    const ENCODING *enc)
+static int PTRCALL
+externalSubset1(PROLOG_STATE *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_COND_SECT_OPEN:
@@ -389,19 +421,19 @@
 
 #endif /* XML_DTD */
 
-static
-int entity0(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity0(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_PERCENT:
     state->handler = entity1;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_NAME:
     state->handler = entity2;
     return XML_ROLE_GENERAL_ENTITY_NAME;
@@ -409,16 +441,16 @@
   return common(state, tok);
 }
 
-static
-int entity1(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity1(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_NAME:
     state->handler = entity7;
     return XML_ROLE_PARAM_ENTITY_NAME;
@@ -426,43 +458,44 @@
   return common(state, tok);
 }
 
-static
-int entity2(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity2(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
       state->handler = entity4;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
       state->handler = entity3;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     break;
   case XML_TOK_LITERAL:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
     return XML_ROLE_ENTITY_VALUE;
   }
   return common(state, tok);
 }
 
-static
-int entity3(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity3(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_LITERAL:
     state->handler = entity4;
     return XML_ROLE_ENTITY_PUBLIC_ID;
@@ -470,17 +503,16 @@
   return common(state, tok);
 }
 
-
-static
-int entity4(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity4(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_LITERAL:
     state->handler = entity5;
     return XML_ROLE_ENTITY_SYSTEM_ID;
@@ -488,83 +520,85 @@
   return common(state, tok);
 }
 
-static
-int entity5(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity5(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_DECL_CLOSE:
     setTopLevel(state);
     return XML_ROLE_ENTITY_COMPLETE;
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
       state->handler = entity6;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     break;
   }
   return common(state, tok);
 }
 
-static
-int entity6(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity6(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_NAME:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
     return XML_ROLE_ENTITY_NOTATION_NAME;
   }
   return common(state, tok);
 }
 
-static
-int entity7(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity7(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
       state->handler = entity9;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
       state->handler = entity8;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ENTITY_NONE;
     }
     break;
   case XML_TOK_LITERAL:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ENTITY_NONE;
     return XML_ROLE_ENTITY_VALUE;
   }
   return common(state, tok);
 }
 
-static
-int entity8(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity8(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_LITERAL:
     state->handler = entity9;
     return XML_ROLE_ENTITY_PUBLIC_ID;
@@ -572,33 +606,50 @@
   return common(state, tok);
 }
 
-static
-int entity9(PROLOG_STATE *state,
-	    int tok,
-	    const char *ptr,
-	    const char *end,
-	    const ENCODING *enc)
+static int PTRCALL
+entity9(PROLOG_STATE *state,
+        int tok,
+        const char *ptr,
+        const char *end,
+        const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
   case XML_TOK_LITERAL:
-    state->handler = declClose;
+    state->handler = entity10;
     return XML_ROLE_ENTITY_SYSTEM_ID;
   }
   return common(state, tok);
 }
 
-static
-int notation0(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+entity10(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ENTITY_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_ENTITY_COMPLETE;
+  }
+  return common(state, tok);
+}
+
+static int PTRCALL
+notation0(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NOTATION_NONE;
   case XML_TOK_NAME:
     state->handler = notation1;
     return XML_ROLE_NOTATION_NAME;
@@ -606,40 +657,40 @@
   return common(state, tok);
 }
 
-static
-int notation1(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+notation1(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_NOTATION_NONE;
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
       state->handler = notation3;
-      return XML_ROLE_NONE;
+      return XML_ROLE_NOTATION_NONE;
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
       state->handler = notation2;
-      return XML_ROLE_NONE;
+      return XML_ROLE_NOTATION_NONE;
     }
     break;
   }
   return common(state, tok);
 }
 
-static
-int notation2(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+notation2(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_NOTATION_NONE;
   case XML_TOK_LITERAL:
     state->handler = notation4;
     return XML_ROLE_NOTATION_PUBLIC_ID;
@@ -647,35 +698,37 @@
   return common(state, tok);
 }
 
-static
-int notation3(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+notation3(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_NOTATION_NONE;
   case XML_TOK_LITERAL:
     state->handler = declClose;
+    state->role_none = XML_ROLE_NOTATION_NONE;
     return XML_ROLE_NOTATION_SYSTEM_ID;
   }
   return common(state, tok);
 }
 
-static
-int notation4(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+notation4(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_NOTATION_NONE;
   case XML_TOK_LITERAL:
     state->handler = declClose;
+    state->role_none = XML_ROLE_NOTATION_NONE;
     return XML_ROLE_NOTATION_SYSTEM_ID;
   case XML_TOK_DECL_CLOSE:
     setTopLevel(state);
@@ -684,16 +737,16 @@
   return common(state, tok);
 }
 
-static
-int attlist0(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
     state->handler = attlist1;
@@ -702,19 +755,19 @@
   return common(state, tok);
 }
 
-static
-int attlist1(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_DECL_CLOSE:
     setTopLevel(state);
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
     state->handler = attlist2;
@@ -723,20 +776,20 @@
   return common(state, tok);
 }
 
-static
-int attlist2(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_NAME:
     {
       static const char *types[] = {
-	KW_CDATA,
+        KW_CDATA,
         KW_ID,
         KW_IDREF,
         KW_IDREFS,
@@ -747,33 +800,33 @@
       };
       int i;
       for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
-	if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
-	  state->handler = attlist8;
-	  return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
-	}
+        if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+          state->handler = attlist8;
+          return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+        }
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
       state->handler = attlist5;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ATTLIST_NONE;
     }
     break;
   case XML_TOK_OPEN_PAREN:
     state->handler = attlist3;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   }
   return common(state, tok);
 }
 
-static
-int attlist3(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_NMTOKEN:
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
@@ -783,54 +836,53 @@
   return common(state, tok);
 }
 
-static
-int attlist4(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_CLOSE_PAREN:
     state->handler = attlist8;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_OR:
     state->handler = attlist3;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   }
   return common(state, tok);
 }
 
-static
-int attlist5(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_OPEN_PAREN:
     state->handler = attlist6;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   }
   return common(state, tok);
 }
 
-
-static
-int attlist6(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist6(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_NAME:
     state->handler = attlist7;
     return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
@@ -838,58 +890,58 @@
   return common(state, tok);
 }
 
-static
-int attlist7(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist7(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_CLOSE_PAREN:
     state->handler = attlist8;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_OR:
     state->handler = attlist6;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   }
   return common(state, tok);
 }
 
 /* default value */
-static
-int attlist8(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist8(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_POUND_NAME:
     if (XmlNameMatchesAscii(enc,
-			    ptr + MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_IMPLIED)) {
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_IMPLIED)) {
       state->handler = attlist1;
       return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
     }
     if (XmlNameMatchesAscii(enc,
-			    ptr + MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_REQUIRED)) {
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_REQUIRED)) {
       state->handler = attlist1;
       return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
     }
     if (XmlNameMatchesAscii(enc,
-			    ptr + MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_FIXED)) {
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_FIXED)) {
       state->handler = attlist9;
-      return XML_ROLE_NONE;
+      return XML_ROLE_ATTLIST_NONE;
     }
     break;
   case XML_TOK_LITERAL:
@@ -899,16 +951,16 @@
   return common(state, tok);
 }
 
-static
-int attlist9(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+attlist9(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ATTLIST_NONE;
   case XML_TOK_LITERAL:
     state->handler = attlist1;
     return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
@@ -916,16 +968,16 @@
   return common(state, tok);
 }
 
-static
-int element0(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element0(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
     state->handler = element1;
@@ -934,23 +986,25 @@
   return common(state, tok);
 }
 
-static
-int element1(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element1(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_NAME:
     if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
       return XML_ROLE_CONTENT_EMPTY;
     }
     if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
       return XML_ROLE_CONTENT_ANY;
     }
     break;
@@ -962,21 +1016,21 @@
   return common(state, tok);
 }
 
-static
-int element2(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element2(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_POUND_NAME:
     if (XmlNameMatchesAscii(enc,
-			    ptr + MIN_BYTES_PER_CHAR(enc),
-			    end,
-			    KW_PCDATA)) {
+                            ptr + MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_PCDATA)) {
       state->handler = element3;
       return XML_ROLE_CONTENT_PCDATA;
     }
@@ -1002,39 +1056,41 @@
   return common(state, tok);
 }
 
-static
-int element3(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element3(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_CLOSE_PAREN:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
     return XML_ROLE_GROUP_CLOSE;
   case XML_TOK_CLOSE_PAREN_ASTERISK:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
     return XML_ROLE_GROUP_CLOSE_REP;
   case XML_TOK_OR:
     state->handler = element4;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   }
   return common(state, tok);
 }
 
-static
-int element4(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element4(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_NAME:
   case XML_TOK_PREFIXED_NAME:
     state->handler = element5;
@@ -1043,36 +1099,37 @@
   return common(state, tok);
 }
 
-static
-int element5(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element5(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_CLOSE_PAREN_ASTERISK:
     state->handler = declClose;
+    state->role_none = XML_ROLE_ELEMENT_NONE;
     return XML_ROLE_GROUP_CLOSE_REP;
   case XML_TOK_OR:
     state->handler = element4;
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   }
   return common(state, tok);
 }
 
-static
-int element6(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element6(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_OPEN_PAREN:
     state->level += 1;
     return XML_ROLE_GROUP_OPEN;
@@ -1093,35 +1150,43 @@
   return common(state, tok);
 }
 
-static
-int element7(PROLOG_STATE *state,
-	     int tok,
-	     const char *ptr,
-	     const char *end,
-	     const ENCODING *enc)
+static int PTRCALL
+element7(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return XML_ROLE_ELEMENT_NONE;
   case XML_TOK_CLOSE_PAREN:
     state->level -= 1;
-    if (state->level == 0)
+    if (state->level == 0) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
     return XML_ROLE_GROUP_CLOSE;
   case XML_TOK_CLOSE_PAREN_ASTERISK:
     state->level -= 1;
-    if (state->level == 0)
+    if (state->level == 0) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
     return XML_ROLE_GROUP_CLOSE_REP;
   case XML_TOK_CLOSE_PAREN_QUESTION:
     state->level -= 1;
-    if (state->level == 0)
+    if (state->level == 0) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
     return XML_ROLE_GROUP_CLOSE_OPT;
   case XML_TOK_CLOSE_PAREN_PLUS:
     state->level -= 1;
-    if (state->level == 0)
+    if (state->level == 0) {
       state->handler = declClose;
+      state->role_none = XML_ROLE_ELEMENT_NONE;
+    }
     return XML_ROLE_GROUP_CLOSE_PLUS;
   case XML_TOK_COMMA:
     state->handler = element6;
@@ -1135,12 +1200,12 @@
 
 #ifdef XML_DTD
 
-static
-int condSect0(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+condSect0(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1159,12 +1224,12 @@
   return common(state, tok);
 }
 
-static
-int condSect1(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+condSect1(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1177,12 +1242,12 @@
   return common(state, tok);
 }
 
-static
-int condSect2(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+condSect2(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
@@ -1196,55 +1261,35 @@
 
 #endif /* XML_DTD */
 
-static
-int declClose(PROLOG_STATE *state,
-	      int tok,
-	      const char *ptr,
-	      const char *end,
-	      const ENCODING *enc)
+static int PTRCALL
+declClose(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
 {
   switch (tok) {
   case XML_TOK_PROLOG_S:
-    return XML_ROLE_NONE;
+    return state->role_none;
   case XML_TOK_DECL_CLOSE:
     setTopLevel(state);
-    return XML_ROLE_NONE;
+    return state->role_none;
   }
   return common(state, tok);
 }
 
-#if 0
-
-static
-int ignore(PROLOG_STATE *state,
-	   int tok,
-	   const char *ptr,
-	   const char *end,
-	   const ENCODING *enc)
-{
-  switch (tok) {
-  case XML_TOK_DECL_CLOSE:
-    state->handler = internalSubset;
-    return 0;
-  default:
-    return XML_ROLE_NONE;
-  }
-  return common(state, tok);
-}
-#endif
-
-static
-int error(PROLOG_STATE *state,
-	  int tok,
-	  const char *ptr,
-	  const char *end,
-	  const ENCODING *enc)
+static int PTRCALL
+error(PROLOG_STATE *state,
+      int tok,
+      const char *ptr,
+      const char *end,
+      const ENCODING *enc)
 {
   return XML_ROLE_NONE;
 }
 
-static
-int common(PROLOG_STATE *state, int tok)
+static int FASTCALL
+common(PROLOG_STATE *state, int tok)
 {
 #ifdef XML_DTD
   if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
@@ -1254,18 +1299,21 @@
   return XML_ROLE_ERROR;
 }
 
-void XmlPrologStateInit(PROLOG_STATE *state)
+void
+XmlPrologStateInit(PROLOG_STATE *state)
 {
   state->handler = prolog0;
 #ifdef XML_DTD
   state->documentEntity = 1;
   state->includeLevel = 0;
+  state->inEntityValue = 0;
 #endif /* XML_DTD */
 }
 
 #ifdef XML_DTD
 
-void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+void
+XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
 {
   state->handler = externalSubset0;
   state->documentEntity = 0;
diff --git a/xml/expat/lib/xmlrole.h b/xml/expat/lib/xmlrole.h
index db3ebc8..4dd9f06 100644
--- a/xml/expat/lib/xmlrole.h
+++ b/xml/expat/lib/xmlrole.h
@@ -1,11 +1,16 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 #ifndef XmlRole_INCLUDED
 #define XmlRole_INCLUDED 1
 
+#ifdef __VMS
+/*      0        1         2         3      0        1         2         3
+        1234567890123456789012345678901     1234567890123456789012345678901 */
+#define XmlPrologStateInitExternalEntity    XmlPrologStateInitExternalEnt
+#endif
+
 #include "xmltok.h"
 
 #ifdef __cplusplus
@@ -17,6 +22,7 @@
   XML_ROLE_NONE = 0,
   XML_ROLE_XML_DECL,
   XML_ROLE_INSTANCE_START,
+  XML_ROLE_DOCTYPE_NONE,
   XML_ROLE_DOCTYPE_NAME,
   XML_ROLE_DOCTYPE_SYSTEM_ID,
   XML_ROLE_DOCTYPE_PUBLIC_ID,
@@ -24,11 +30,13 @@
   XML_ROLE_DOCTYPE_CLOSE,
   XML_ROLE_GENERAL_ENTITY_NAME,
   XML_ROLE_PARAM_ENTITY_NAME,
+  XML_ROLE_ENTITY_NONE,
   XML_ROLE_ENTITY_VALUE,
   XML_ROLE_ENTITY_SYSTEM_ID,
   XML_ROLE_ENTITY_PUBLIC_ID,
   XML_ROLE_ENTITY_COMPLETE,
   XML_ROLE_ENTITY_NOTATION_NAME,
+  XML_ROLE_NOTATION_NONE,
   XML_ROLE_NOTATION_NAME,
   XML_ROLE_NOTATION_SYSTEM_ID,
   XML_ROLE_NOTATION_NO_SYSTEM_ID,
@@ -44,11 +52,13 @@
   XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
   XML_ROLE_ATTRIBUTE_ENUM_VALUE,
   XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+  XML_ROLE_ATTLIST_NONE,
   XML_ROLE_ATTLIST_ELEMENT_NAME,
   XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
   XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
   XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
   XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+  XML_ROLE_ELEMENT_NONE,
   XML_ROLE_ELEMENT_NAME,
   XML_ROLE_CONTENT_ANY,
   XML_ROLE_CONTENT_EMPTY,
@@ -64,6 +74,8 @@
   XML_ROLE_CONTENT_ELEMENT_REP,
   XML_ROLE_CONTENT_ELEMENT_OPT,
   XML_ROLE_CONTENT_ELEMENT_PLUS,
+  XML_ROLE_PI,
+  XML_ROLE_COMMENT,
 #ifdef XML_DTD
   XML_ROLE_TEXT_DECL,
   XML_ROLE_IGNORE_SECT,
@@ -73,15 +85,17 @@
 };
 
 typedef struct prolog_state {
-  int (*handler)(struct prolog_state *state,
-	         int tok,
-		 const char *ptr,
-		 const char *end,
-		 const ENCODING *enc);
+  int (PTRCALL *handler) (struct prolog_state *state,
+                          int tok,
+                          const char *ptr,
+                          const char *end,
+                          const ENCODING *enc);
   unsigned level;
+  int role_none;
 #ifdef XML_DTD
   unsigned includeLevel;
   int documentEntity;
+  int inEntityValue;
 #endif /* XML_DTD */
 } PROLOG_STATE;
 
diff --git a/xml/expat/lib/xmltok.c b/xml/expat/lib/xmltok.c
index e3fe3f7..962df0e 100644
--- a/xml/expat/lib/xmltok.c
+++ b/xml/expat/lib/xmltok.c
@@ -1,17 +1,18 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
-static char RCSId[]
-  = "$Header: /home/cvs/apr-util/xml/expat/lib/xmltok.c,v 1.1 2001/02/28 14:41:26 gstein Exp $";
-
 #ifdef COMPILED_FROM_DSP
-#  include "winconfig.h"
+#include "winconfig.h"
+#elif defined(MACOS_CLASSIC)
+#include "macconfig.h"
 #else
-#  include <config.h>
+#ifdef HAVE_EXPAT_CONFIG_H
+#include <expat_config.h>
+#endif
 #endif /* ndef COMPILED_FROM_DSP */
 
+#include "internal.h"
 #include "xmltok.h"
 #include "nametab.h"
 
@@ -40,24 +41,25 @@
 #define UCS2_GET_NAMING(pages, hi, lo) \
    (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
 
-/* A 2 byte UTF-8 representation splits the characters 11 bits
-between the bottom 5 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
+/* A 2 byte UTF-8 representation splits the characters 11 bits between
+   the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
+   pages, 3 bits to add to that index and 5 bits to generate the mask.
+*/
 #define UTF8_GET_NAMING2(pages, byte) \
     (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
                       + ((((byte)[0]) & 3) << 1) \
                       + ((((byte)[1]) >> 5) & 1)] \
          & (1 << (((byte)[1]) & 0x1F)))
 
-/* A 3 byte UTF-8 representation splits the characters 16 bits
-between the bottom 4, 6 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
+/* A 3 byte UTF-8 representation splits the characters 16 bits between
+   the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
+   into pages, 3 bits to add to that index and 5 bits to generate the
+   mask.
+*/
 #define UTF8_GET_NAMING3(pages, byte) \
   (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
                              + ((((byte)[1]) >> 2) & 0xF)] \
-		       << 3) \
+                       << 3) \
                       + ((((byte)[1]) & 3) << 1) \
                       + ((((byte)[2]) >> 5) & 1)] \
          & (1 << (((byte)[2]) & 0x1F)))
@@ -69,59 +71,97 @@
      ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
      : 0))
 
+/* Detection of invalid UTF-8 sequences is based on Table 3.1B
+   of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
+   with the additional restriction of not allowing the Unicode
+   code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
+   Implementation details:
+     (A & 0x80) == 0     means A < 0x80
+   and
+     (A & 0xC0) == 0xC0  means A > 0xBF
+*/
+
+#define UTF8_INVALID2(p) \
+  ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
 #define UTF8_INVALID3(p) \
-  ((*p) == 0xED \
-  ? (((p)[1] & 0x20) != 0) \
-  : ((*p) == 0xEF \
-     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
-     : 0))
+  (((p)[2] & 0x80) == 0 \
+  || \
+  ((*p) == 0xEF && (p)[1] == 0xBF \
+    ? \
+    (p)[2] > 0xBD \
+    : \
+    ((p)[2] & 0xC0) == 0xC0) \
+  || \
+  ((*p) == 0xE0 \
+    ? \
+    (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+    : \
+    ((p)[1] & 0x80) == 0 \
+    || \
+    ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
 
-#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
+#define UTF8_INVALID4(p) \
+  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
+  || \
+  ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
+  || \
+  ((*p) == 0xF0 \
+    ? \
+    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
+    : \
+    ((p)[1] & 0x80) == 0 \
+    || \
+    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
 
-static
-int isNever(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+isNever(const ENCODING *enc, const char *p)
 {
   return 0;
 }
 
-static
-int utf8_isName2(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isName2(const ENCODING *enc, const char *p)
 {
   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
 }
 
-static
-int utf8_isName3(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isName3(const ENCODING *enc, const char *p)
 {
   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
 }
 
 #define utf8_isName4 isNever
 
-static
-int utf8_isNmstrt2(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isNmstrt2(const ENCODING *enc, const char *p)
 {
   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
 }
 
-static
-int utf8_isNmstrt3(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isNmstrt3(const ENCODING *enc, const char *p)
 {
   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
 }
 
 #define utf8_isNmstrt4 isNever
 
-#define utf8_isInvalid2 isNever
+static int PTRFASTCALL
+utf8_isInvalid2(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID2((const unsigned char *)p);
+}
 
-static
-int utf8_isInvalid3(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isInvalid3(const ENCODING *enc, const char *p)
 {
   return UTF8_INVALID3((const unsigned char *)p);
 }
 
-static
-int utf8_isInvalid4(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+utf8_isInvalid4(const ENCODING *enc, const char *p)
 {
   return UTF8_INVALID4((const unsigned char *)p);
 }
@@ -130,23 +170,25 @@
   ENCODING enc;
   unsigned char type[256];
 #ifdef XML_MIN_SIZE
-  int (*byteType)(const ENCODING *, const char *);
-  int (*isNameMin)(const ENCODING *, const char *);
-  int (*isNmstrtMin)(const ENCODING *, const char *);
-  int (*byteToAscii)(const ENCODING *, const char *);
-  int (*charMatches)(const ENCODING *, const char *, int);
+  int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
+  int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
+  int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
 #endif /* XML_MIN_SIZE */
-  int (*isName2)(const ENCODING *, const char *);
-  int (*isName3)(const ENCODING *, const char *);
-  int (*isName4)(const ENCODING *, const char *);
-  int (*isNmstrt2)(const ENCODING *, const char *);
-  int (*isNmstrt3)(const ENCODING *, const char *);
-  int (*isNmstrt4)(const ENCODING *, const char *);
-  int (*isInvalid2)(const ENCODING *, const char *);
-  int (*isInvalid3)(const ENCODING *, const char *);
-  int (*isInvalid4)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
+  int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
 };
 
+#define AS_NORMAL_ENCODING(enc)   ((const struct normal_encoding *) (enc))
+
 #ifdef XML_MIN_SIZE
 
 #define STANDARD_VTABLE(E) \
@@ -173,7 +215,7 @@
  E ## isInvalid3, \
  E ## isInvalid4
 
-static int checkCharRefNumber(int);
+static int FASTCALL checkCharRefNumber(int);
 
 #include "xmltok_impl.h"
 #include "ascii.h"
@@ -194,22 +236,22 @@
   (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
 
 #ifdef XML_MIN_SIZE
-static
-int sb_byteType(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+sb_byteType(const ENCODING *enc, const char *p)
 {
   return SB_BYTE_TYPE(enc, p);
 }
 #define BYTE_TYPE(enc, p) \
- (((const struct normal_encoding *)(enc))->byteType(enc, p))
+ (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
 #else
 #define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
 #endif
 
 #ifdef XML_MIN_SIZE
 #define BYTE_TO_ASCII(enc, p) \
- (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
-static
-int sb_byteToAscii(const ENCODING *enc, const char *p)
+ (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
+static int PTRFASTCALL
+sb_byteToAscii(const ENCODING *enc, const char *p)
 {
   return *p;
 }
@@ -218,17 +260,17 @@
 #endif
 
 #define IS_NAME_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
+ (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
 #define IS_NMSTRT_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
+ (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
 #define IS_INVALID_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
+ (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
 
 #ifdef XML_MIN_SIZE
 #define IS_NAME_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
+ (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
 #define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
+ (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
 #else
 #define IS_NAME_CHAR_MINBPC(enc, p) (0)
 #define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
@@ -236,9 +278,9 @@
 
 #ifdef XML_MIN_SIZE
 #define CHAR_MATCHES(enc, p, c) \
- (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
-static
-int sb_charMatches(const ENCODING *enc, const char *p, int c)
+ (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
+static int PTRCALL
+sb_charMatches(const ENCODING *enc, const char *p, int c)
 {
   return *p == c;
 }
@@ -267,10 +309,10 @@
   UTF8_cval4 = 0xf0
 };
 
-static
-void utf8_toUtf8(const ENCODING *enc,
-		 const char **fromP, const char *fromLim,
-		 char **toP, const char *toLim)
+static void PTRCALL
+utf8_toUtf8(const ENCODING *enc,
+            const char **fromP, const char *fromLim,
+            char **toP, const char *toLim)
 {
   char *to;
   const char *from;
@@ -278,7 +320,7 @@
     /* Avoid copying partial characters. */
     for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
       if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
-	break;
+        break;
   }
   for (to = *toP, from = *fromP; from != fromLim; from++, to++)
     *to = *from;
@@ -286,34 +328,36 @@
   *toP = to;
 }
 
-static
-void utf8_toUtf16(const ENCODING *enc,
-		  const char **fromP, const char *fromLim,
-		  unsigned short **toP, const unsigned short *toLim)
+static void PTRCALL
+utf8_toUtf16(const ENCODING *enc,
+             const char **fromP, const char *fromLim,
+             unsigned short **toP, const unsigned short *toLim)
 {
   unsigned short *to = *toP;
   const char *from = *fromP;
   while (from != fromLim && to != toLim) {
     switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
     case BT_LEAD2:
-      *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
+      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
       from += 2;
       break;
     case BT_LEAD3:
-      *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
+      *to++ = (unsigned short)(((from[0] & 0xf) << 12)
+                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
       from += 3;
       break;
     case BT_LEAD4:
       {
-	unsigned long n;
-	if (to + 1 == toLim)
-	  break;
-	n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
-	n -= 0x10000;
-	to[0] = (unsigned short)((n >> 10) | 0xD800);
-	to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
-	to += 2;
-	from += 4;
+        unsigned long n;
+        if (to + 1 == toLim)
+          goto after;
+        n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
+            | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+        n -= 0x10000;
+        to[0] = (unsigned short)((n >> 10) | 0xD800);
+        to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+        to += 2;
+        from += 4;
       }
       break;
     default:
@@ -321,6 +365,7 @@
       break;
     }
   }
+after:
   *fromP = from;
   *toP = to;
 }
@@ -371,10 +416,10 @@
   STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
 };
 
-static
-void latin1_toUtf8(const ENCODING *enc,
-		   const char **fromP, const char *fromLim,
-		   char **toP, const char *toLim)
+static void PTRCALL
+latin1_toUtf8(const ENCODING *enc,
+              const char **fromP, const char *fromLim,
+              char **toP, const char *toLim)
 {
   for (;;) {
     unsigned char c;
@@ -383,23 +428,23 @@
     c = (unsigned char)**fromP;
     if (c & 0x80) {
       if (toLim - *toP < 2)
-	break;
-      *(*toP)++ = ((c >> 6) | UTF8_cval2);
-      *(*toP)++ = ((c & 0x3f) | 0x80);
+        break;
+      *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
+      *(*toP)++ = (char)((c & 0x3f) | 0x80);
       (*fromP)++;
     }
     else {
       if (*toP == toLim)
-	break;
+        break;
       *(*toP)++ = *(*fromP)++;
     }
   }
 }
 
-static
-void latin1_toUtf16(const ENCODING *enc,
-		    const char **fromP, const char *fromLim,
-		    unsigned short **toP, const unsigned short *toLim)
+static void PTRCALL
+latin1_toUtf16(const ENCODING *enc,
+               const char **fromP, const char *fromLim,
+               unsigned short **toP, const unsigned short *toLim)
 {
   while (*fromP != fromLim && *toP != toLim)
     *(*toP)++ = (unsigned char)*(*fromP)++;
@@ -429,10 +474,10 @@
   STANDARD_VTABLE(sb_)
 };
 
-static
-void ascii_toUtf8(const ENCODING *enc,
-		  const char **fromP, const char *fromLim,
-		  char **toP, const char *toLim)
+static void PTRCALL
+ascii_toUtf8(const ENCODING *enc,
+             const char **fromP, const char *fromLim,
+             char **toP, const char *toLim)
 {
   while (*fromP != fromLim && *toP != toLim)
     *(*toP)++ = *(*fromP)++;
@@ -462,7 +507,8 @@
   STANDARD_VTABLE(sb_)
 };
 
-static int unicode_byte_type(char hi, char lo)
+static int PTRFASTCALL
+unicode_byte_type(char hi, char lo)
 {
   switch ((unsigned char)hi) {
   case 0xD8: case 0xD9: case 0xDA: case 0xDB:
@@ -481,10 +527,10 @@
 }
 
 #define DEFINE_UTF16_TO_UTF8(E) \
-static \
-void E ## toUtf8(const ENCODING *enc, \
-		 const char **fromP, const char *fromLim, \
-		 char **toP, const char *toLim) \
+static void  PTRCALL \
+E ## toUtf8(const ENCODING *enc, \
+            const char **fromP, const char *fromLim, \
+            char **toP, const char *toLim) \
 { \
   const char *from; \
   for (from = *fromP; from != fromLim; from += 2) { \
@@ -497,7 +543,7 @@
       if (lo < 0x80) { \
         if (*toP == toLim) { \
           *fromP = from; \
-	  return; \
+          return; \
         } \
         *(*toP)++ = lo; \
         break; \
@@ -507,7 +553,7 @@
     case 0x4: case 0x5: case 0x6: case 0x7: \
       if (toLim -  *toP < 2) { \
         *fromP = from; \
-	return; \
+        return; \
       } \
       *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
       *(*toP)++ = ((lo & 0x3f) | 0x80); \
@@ -515,7 +561,7 @@
     default: \
       if (toLim -  *toP < 3)  { \
         *fromP = from; \
-	return; \
+        return; \
       } \
       /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
       *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
@@ -524,8 +570,8 @@
       break; \
     case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
       if (toLim -  *toP < 4) { \
-	*fromP = from; \
-	return; \
+        *fromP = from; \
+        return; \
       } \
       plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
       *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
@@ -533,9 +579,9 @@
       from += 2; \
       lo2 = GET_LO(from); \
       *(*toP)++ = (((lo & 0x3) << 4) \
-	           | ((GET_HI(from) & 0x3) << 2) \
-		   | (lo2 >> 6) \
-		   | 0x80); \
+                   | ((GET_HI(from) & 0x3) << 2) \
+                   | (lo2 >> 6) \
+                   | 0x80); \
       *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
       break; \
     } \
@@ -544,10 +590,10 @@
 }
 
 #define DEFINE_UTF16_TO_UTF16(E) \
-static \
-void E ## toUtf16(const ENCODING *enc, \
-		  const char **fromP, const char *fromLim, \
-		  unsigned short **toP, const unsigned short *toLim) \
+static void  PTRCALL \
+E ## toUtf16(const ENCODING *enc, \
+             const char **fromP, const char *fromLim, \
+             unsigned short **toP, const unsigned short *toLim) \
 { \
   /* Avoid copying first half only of surrogate */ \
   if (fromLim - *fromP > ((toLim - *toP) << 1) \
@@ -594,32 +640,32 @@
 
 #ifdef XML_MIN_SIZE
 
-static
-int little2_byteType(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+little2_byteType(const ENCODING *enc, const char *p)
 {
   return LITTLE2_BYTE_TYPE(enc, p);
 }
 
-static
-int little2_byteToAscii(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+little2_byteToAscii(const ENCODING *enc, const char *p)
 {
   return LITTLE2_BYTE_TO_ASCII(enc, p);
 }
 
-static
-int little2_charMatches(const ENCODING *enc, const char *p, int c)
+static int PTRCALL
+little2_charMatches(const ENCODING *enc, const char *p, int c)
 {
   return LITTLE2_CHAR_MATCHES(enc, p, c);
 }
 
-static
-int little2_isNameMin(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+little2_isNameMin(const ENCODING *enc, const char *p)
 {
   return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
 }
 
-static
-int little2_isNmstrtMin(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+little2_isNmstrtMin(const ENCODING *enc, const char *p)
 {
   return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
 }
@@ -634,7 +680,7 @@
 #define MINBPC(enc) 2
 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
 #define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
 #define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
 #define IS_NAME_CHAR(enc, p, n) 0
 #define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
@@ -657,9 +703,9 @@
 
 #ifdef XML_NS
 
-static const struct normal_encoding little2_encoding_ns = { 
+static const struct normal_encoding little2_encoding_ns = {
   { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
+#if BYTEORDER == 1234
     1
 #else
     0
@@ -674,9 +720,9 @@
 
 #endif
 
-static const struct normal_encoding little2_encoding = { 
+static const struct normal_encoding little2_encoding = {
   { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
+#if BYTEORDER == 1234
     1
 #else
     0
@@ -691,11 +737,11 @@
   STANDARD_VTABLE(little2_)
 };
 
-#if XML_BYTE_ORDER != 21
+#if BYTEORDER != 4321
 
 #ifdef XML_NS
 
-static const struct normal_encoding internal_little2_encoding_ns = { 
+static const struct normal_encoding internal_little2_encoding_ns = {
   { VTABLE, 2, 0, 1 },
   {
 #include "iasciitab.h"
@@ -706,7 +752,7 @@
 
 #endif
 
-static const struct normal_encoding internal_little2_encoding = { 
+static const struct normal_encoding internal_little2_encoding = {
   { VTABLE, 2, 0, 1 },
   {
 #define BT_COLON BT_NMSTRT
@@ -733,32 +779,32 @@
 
 #ifdef XML_MIN_SIZE
 
-static
-int big2_byteType(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+big2_byteType(const ENCODING *enc, const char *p)
 {
   return BIG2_BYTE_TYPE(enc, p);
 }
 
-static
-int big2_byteToAscii(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+big2_byteToAscii(const ENCODING *enc, const char *p)
 {
   return BIG2_BYTE_TO_ASCII(enc, p);
 }
 
-static
-int big2_charMatches(const ENCODING *enc, const char *p, int c)
+static int PTRCALL
+big2_charMatches(const ENCODING *enc, const char *p, int c)
 {
   return BIG2_CHAR_MATCHES(enc, p, c);
 }
 
-static
-int big2_isNameMin(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+big2_isNameMin(const ENCODING *enc, const char *p)
 {
   return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
 }
 
-static
-int big2_isNmstrtMin(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+big2_isNmstrtMin(const ENCODING *enc, const char *p)
 {
   return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
 }
@@ -773,7 +819,7 @@
 #define MINBPC(enc) 2
 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
 #define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
 #define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
 #define IS_NAME_CHAR(enc, p, n) 0
 #define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
@@ -798,7 +844,7 @@
 
 static const struct normal_encoding big2_encoding_ns = {
   { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
+#if BYTEORDER == 4321
   1
 #else
   0
@@ -815,7 +861,7 @@
 
 static const struct normal_encoding big2_encoding = {
   { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
+#if BYTEORDER == 4321
   1
 #else
   0
@@ -830,7 +876,7 @@
   STANDARD_VTABLE(big2_)
 };
 
-#if XML_BYTE_ORDER != 12
+#if BYTEORDER != 1234
 
 #ifdef XML_NS
 
@@ -860,8 +906,8 @@
 
 #undef PREFIX
 
-static
-int streqci(const char *s1, const char *s2)
+static int FASTCALL
+streqci(const char *s1, const char *s2)
 {
   for (;;) {
     char c1 = *s1++;
@@ -878,15 +924,15 @@
   return 1;
 }
 
-static
-void initUpdatePosition(const ENCODING *enc, const char *ptr,
-			const char *end, POSITION *pos)
+static void PTRCALL
+initUpdatePosition(const ENCODING *enc, const char *ptr,
+                   const char *end, POSITION *pos)
 {
   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
 }
 
-static
-int toAscii(const ENCODING *enc, const char *ptr, const char *end)
+static int
+toAscii(const ENCODING *enc, const char *ptr, const char *end)
 {
   char buf[1];
   char *p = buf;
@@ -897,34 +943,35 @@
     return buf[0];
 }
 
-static
-int isSpace(int c)
+static int FASTCALL
+isSpace(int c)
 {
   switch (c) {
   case 0x20:
   case 0xD:
   case 0xA:
-  case 0x9:	
+  case 0x9:
     return 1;
   }
   return 0;
 }
 
-/* Return 1 if there's just optional white space
-or there's an S followed by name=val. */
-static
-int parsePseudoAttribute(const ENCODING *enc,
-			 const char *ptr,
-			 const char *end,
-			 const char **namePtr,
-			 const char **nameEndPtr,
-			 const char **valPtr,
-			 const char **nextTokPtr)
+/* Return 1 if there's just optional white space or there's an S
+   followed by name=val.
+*/
+static int
+parsePseudoAttribute(const ENCODING *enc,
+                     const char *ptr,
+                     const char *end,
+                     const char **namePtr,
+                     const char **nameEndPtr,
+                     const char **valPtr,
+                     const char **nextTokPtr)
 {
   int c;
   char open;
   if (ptr == end) {
-    *namePtr = 0;
+    *namePtr = NULL;
     return 1;
   }
   if (!isSpace(toAscii(enc, ptr, end))) {
@@ -935,7 +982,7 @@
     ptr += enc->minBytesPerChar;
   } while (isSpace(toAscii(enc, ptr, end)));
   if (ptr == end) {
-    *namePtr = 0;
+    *namePtr = NULL;
     return 1;
   }
   *namePtr = ptr;
@@ -952,11 +999,11 @@
     if (isSpace(c)) {
       *nameEndPtr = ptr;
       do {
-	ptr += enc->minBytesPerChar;
+        ptr += enc->minBytesPerChar;
       } while (isSpace(c = toAscii(enc, ptr, end)));
       if (c != ASCII_EQUALS) {
-	*nextTokPtr = ptr;
-	return 0;
+        *nextTokPtr = ptr;
+        return 0;
       }
       break;
     }
@@ -976,7 +1023,7 @@
     *nextTokPtr = ptr;
     return 0;
   }
-  open = c;
+  open = (char)c;
   ptr += enc->minBytesPerChar;
   *valPtr = ptr;
   for (;; ptr += enc->minBytesPerChar) {
@@ -984,11 +1031,11 @@
     if (c == open)
       break;
     if (!(ASCII_a <= c && c <= ASCII_z)
-	&& !(ASCII_A <= c && c <= ASCII_Z)
-	&& !(ASCII_0 <= c && c <= ASCII_9)
-	&& c != ASCII_PERIOD
-	&& c != ASCII_MINUS
-	&& c != ASCII_UNDERSCORE) {
+        && !(ASCII_A <= c && c <= ASCII_Z)
+        && !(ASCII_0 <= c && c <= ASCII_9)
+        && c != ASCII_PERIOD
+        && c != ASCII_MINUS
+        && c != ASCII_UNDERSCORE) {
       *nextTokPtr = ptr;
       return 0;
     }
@@ -1006,7 +1053,8 @@
 };
 
 static const char KW_standalone[] = {
-  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'
+  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
+  ASCII_n, ASCII_e, '\0'
 };
 
 static const char KW_yes[] = {
@@ -1017,27 +1065,28 @@
   ASCII_n, ASCII_o,  '\0'
 };
 
-static
-int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
-		                                     const char *,
-						     const char *),
-		   int isGeneralTextEntity,
-		   const ENCODING *enc,
-		   const char *ptr,
-		   const char *end,
-		   const char **badPtr,
-		   const char **versionPtr,
-		   const char **versionEndPtr,
-		   const char **encodingName,
-		   const ENCODING **encoding,
-		   int *standalone)
+static int
+doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+                                                 const char *,
+                                                 const char *),
+               int isGeneralTextEntity,
+               const ENCODING *enc,
+               const char *ptr,
+               const char *end,
+               const char **badPtr,
+               const char **versionPtr,
+               const char **versionEndPtr,
+               const char **encodingName,
+               const ENCODING **encoding,
+               int *standalone)
 {
-  const char *val = 0;
-  const char *name = 0;
-  const char *nameEnd = 0;
+  const char *val = NULL;
+  const char *name = NULL;
+  const char *nameEnd = NULL;
   ptr += 5 * enc->minBytesPerChar;
   end -= 2 * enc->minBytesPerChar;
-  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
+  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
+      || !name) {
     *badPtr = ptr;
     return 0;
   }
@@ -1058,9 +1107,9 @@
     }
     if (!name) {
       if (isGeneralTextEntity) {
-	/* a TextDecl must have an EncodingDecl */
-	*badPtr = ptr;
-	return 0;
+        /* a TextDecl must have an EncodingDecl */
+        *badPtr = ptr;
+        return 0;
       }
       return 1;
     }
@@ -1082,7 +1131,8 @@
     if (!name)
       return 1;
   }
-  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
+      || isGeneralTextEntity) {
     *badPtr = name;
     return 0;
   }
@@ -1107,8 +1157,8 @@
   return 1;
 }
 
-static
-int checkCharRefNumber(int result)
+static int FASTCALL
+checkCharRefNumber(int result)
 {
   switch (result >> 8) {
   case 0xD8: case 0xD9: case 0xDA: case 0xDB:
@@ -1126,7 +1176,8 @@
   return result;
 }
 
-int XmlUtf8Encode(int c, char *buf)
+int FASTCALL
+XmlUtf8Encode(int c, char *buf)
 {
   enum {
     /* minN is minimum legal resulting value for N byte sequence */
@@ -1138,42 +1189,43 @@
   if (c < 0)
     return 0;
   if (c < min2) {
-    buf[0] = (c | UTF8_cval1);
+    buf[0] = (char)(c | UTF8_cval1);
     return 1;
   }
   if (c < min3) {
-    buf[0] = ((c >> 6) | UTF8_cval2);
-    buf[1] = ((c & 0x3f) | 0x80);
+    buf[0] = (char)((c >> 6) | UTF8_cval2);
+    buf[1] = (char)((c & 0x3f) | 0x80);
     return 2;
   }
   if (c < min4) {
-    buf[0] = ((c >> 12) | UTF8_cval3);
-    buf[1] = (((c >> 6) & 0x3f) | 0x80);
-    buf[2] = ((c & 0x3f) | 0x80);
+    buf[0] = (char)((c >> 12) | UTF8_cval3);
+    buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
+    buf[2] = (char)((c & 0x3f) | 0x80);
     return 3;
   }
   if (c < 0x110000) {
-    buf[0] = ((c >> 18) | UTF8_cval4);
-    buf[1] = (((c >> 12) & 0x3f) | 0x80);
-    buf[2] = (((c >> 6) & 0x3f) | 0x80);
-    buf[3] = ((c & 0x3f) | 0x80);
+    buf[0] = (char)((c >> 18) | UTF8_cval4);
+    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
+    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
+    buf[3] = (char)((c & 0x3f) | 0x80);
     return 4;
   }
   return 0;
 }
 
-int XmlUtf16Encode(int charNum, unsigned short *buf)
+int FASTCALL
+XmlUtf16Encode(int charNum, unsigned short *buf)
 {
   if (charNum < 0)
     return 0;
   if (charNum < 0x10000) {
-    buf[0] = charNum;
+    buf[0] = (unsigned short)charNum;
     return 1;
   }
   if (charNum < 0x110000) {
     charNum -= 0x10000;
-    buf[0] = (charNum >> 10) + 0xD800;
-    buf[1] = (charNum & 0x3FF) + 0xDC00;
+    buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
+    buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
     return 2;
   }
   return 0;
@@ -1187,65 +1239,68 @@
   char utf8[256][4];
 };
 
-int XmlSizeOfUnknownEncoding(void)
+#define AS_UNKNOWN_ENCODING(enc)  ((const struct unknown_encoding *) (enc))
+
+int
+XmlSizeOfUnknownEncoding(void)
 {
   return sizeof(struct unknown_encoding);
 }
 
-static
-int unknown_isName(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+unknown_isName(const ENCODING *enc, const char *p)
 {
-  int c = ((const struct unknown_encoding *)enc)
-	  ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
   if (c & ~0xFFFF)
     return 0;
   return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
 }
 
-static
-int unknown_isNmstrt(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+unknown_isNmstrt(const ENCODING *enc, const char *p)
 {
-  int c = ((const struct unknown_encoding *)enc)
-	  ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
   if (c & ~0xFFFF)
     return 0;
   return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
 }
 
-static
-int unknown_isInvalid(const ENCODING *enc, const char *p)
+static int PTRFASTCALL
+unknown_isInvalid(const ENCODING *enc, const char *p)
 {
-  int c = ((const struct unknown_encoding *)enc)
-	   ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
+  int c = uenc->convert(uenc->userData, p);
   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
 }
 
-static
-void unknown_toUtf8(const ENCODING *enc,
-		    const char **fromP, const char *fromLim,
-		    char **toP, const char *toLim)
+static void PTRCALL
+unknown_toUtf8(const ENCODING *enc,
+               const char **fromP, const char *fromLim,
+               char **toP, const char *toLim)
 {
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   char buf[XML_UTF8_ENCODE_MAX];
   for (;;) {
     const char *utf8;
     int n;
     if (*fromP == fromLim)
       break;
-    utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
+    utf8 = uenc->utf8[(unsigned char)**fromP];
     n = *utf8++;
     if (n == 0) {
-      int c = ((const struct unknown_encoding *)enc)
-	      ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      int c = uenc->convert(uenc->userData, *fromP);
       n = XmlUtf8Encode(c, buf);
       if (n > toLim - *toP)
-	break;
+        break;
       utf8 = buf;
-      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-	         - (BT_LEAD2 - 2);
+      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+                 - (BT_LEAD2 - 2));
     }
     else {
       if (n > toLim - *toP)
-	break;
+        break;
       (*fromP)++;
     }
     do {
@@ -1254,19 +1309,19 @@
   }
 }
 
-static
-void unknown_toUtf16(const ENCODING *enc,
-		     const char **fromP, const char *fromLim,
-		     unsigned short **toP, const unsigned short *toLim)
+static void PTRCALL
+unknown_toUtf16(const ENCODING *enc,
+                const char **fromP, const char *fromLim,
+                unsigned short **toP, const unsigned short *toLim)
 {
+  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
   while (*fromP != fromLim && *toP != toLim) {
-    unsigned short c
-      = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
+    unsigned short c = uenc->utf16[(unsigned char)**fromP];
     if (c == 0) {
-      c = (unsigned short)((const struct unknown_encoding *)enc)
-	   ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
-      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-	         - (BT_LEAD2 - 2);
+      c = (unsigned short)
+          uenc->convert(uenc->userData, *fromP);
+      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
+                 - (BT_LEAD2 - 2));
     }
     else
       (*fromP)++;
@@ -1276,18 +1331,18 @@
 
 ENCODING *
 XmlInitUnknownEncoding(void *mem,
-		       int *table,
-		       int (*convert)(void *userData, const char *p),
-		       void *userData)
+                       int *table,
+                       CONVERTER convert, 
+                       void *userData)
 {
   int i;
-  struct unknown_encoding *e = mem;
+  struct unknown_encoding *e = (struct unknown_encoding *)mem;
   for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
     ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
   for (i = 0; i < 128; i++)
     if (latin1_encoding.type[i] != BT_OTHER
         && latin1_encoding.type[i] != BT_NONXML
-	&& table[i] != i)
+        && table[i] != i)
       return 0;
   for (i = 0; i < 256; i++) {
     int c = table[i];
@@ -1300,20 +1355,20 @@
     }
     else if (c < 0) {
       if (c < -4)
-	return 0;
-      e->normal.type[i] = BT_LEAD2 - (c + 2);
+        return 0;
+      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
       e->utf8[i][0] = 0;
       e->utf16[i] = 0;
     }
     else if (c < 0x80) {
       if (latin1_encoding.type[c] != BT_OTHER
-	  && latin1_encoding.type[c] != BT_NONXML
-	  && c != i)
-	return 0;
+          && latin1_encoding.type[c] != BT_NONXML
+          && c != i)
+        return 0;
       e->normal.type[i] = latin1_encoding.type[c];
       e->utf8[i][0] = 1;
       e->utf8[i][1] = (char)c;
-      e->utf16[i] = c == 0 ? 0xFFFF : c;
+      e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
     }
     else if (checkCharRefNumber(c) < 0) {
       e->normal.type[i] = BT_NONXML;
@@ -1324,15 +1379,15 @@
     }
     else {
       if (c > 0xFFFF)
-	return 0;
+        return 0;
       if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
-	e->normal.type[i] = BT_NMSTRT;
+        e->normal.type[i] = BT_NMSTRT;
       else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
-	e->normal.type[i] = BT_NAME;
+        e->normal.type[i] = BT_NAME;
       else
-	e->normal.type[i] = BT_OTHER;
+        e->normal.type[i] = BT_OTHER;
       e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
-      e->utf16[i] = c;
+      e->utf16[i] = (unsigned short)c;
     }
   }
   e->userData = userData;
@@ -1368,26 +1423,30 @@
 };
 
 static const char KW_ISO_8859_1[] = {
-  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'
+  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
+  ASCII_MINUS, ASCII_1, '\0'
 };
 static const char KW_US_ASCII[] = {
-  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'
+  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
+  '\0'
 };
-static const char KW_UTF_8[] =	{
+static const char KW_UTF_8[] =  {
   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
 };
-static const char KW_UTF_16[] =	{
+static const char KW_UTF_16[] = {
   ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
 };
 static const char KW_UTF_16BE[] = {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
+  '\0'
 };
 static const char KW_UTF_16LE[] = {
-  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
+  '\0'
 };
 
-static
-int getEncodingIndex(const char *name)
+static int FASTCALL
+getEncodingIndex(const char *name)
 {
   static const char *encodingNames[] = {
     KW_ISO_8859_1,
@@ -1398,7 +1457,7 @@
     KW_UTF_16LE,
   };
   int i;
-  if (name == 0)
+  if (name == NULL)
     return NO_ENC;
   for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
     if (streqci(name, encodingNames[i]))
@@ -1406,27 +1465,28 @@
   return UNKNOWN_ENC;
 }
 
-/* For binary compatibility, we store the index of the encoding specified
-at initialization in the isUtf16 member. */
+/* For binary compatibility, we store the index of the encoding
+   specified at initialization in the isUtf16 member.
+*/
 
 #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
 #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
 
-/* This is what detects the encoding.
-encodingTable maps from encoding indices to encodings;
-INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
-state is XML_CONTENT_STATE if we're parsing an external text entity,
-and XML_PROLOG_STATE otherwise.
+/* This is what detects the encoding.  encodingTable maps from
+   encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
+   the external (protocol) specified encoding; state is
+   XML_CONTENT_STATE if we're parsing an external text entity, and
+   XML_PROLOG_STATE otherwise.
 */
 
 
-static
-int initScan(const ENCODING **encodingTable,
-	     const INIT_ENCODING *enc,
-	     int state,
-	     const char *ptr,
-	     const char *end,
-	     const char **nextTokPtr)
+static int
+initScan(const ENCODING **encodingTable,
+         const INIT_ENCODING *enc,
+         int state,
+         const char *ptr,
+         const char *end,
+         const char **nextTokPtr)
 {
   const ENCODING **encPtr;
 
@@ -1453,8 +1513,8 @@
     case 0xFF:
     case 0xEF: /* possibly first byte of UTF-8 BOM */
       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-	  && state == XML_CONTENT_STATE)
-	break;
+          && state == XML_CONTENT_STATE)
+        break;
       /* fall through */
     case 0x00:
     case 0x3C:
@@ -1465,23 +1525,23 @@
     switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
     case 0xFEFF:
       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-	  && state == XML_CONTENT_STATE)
-	break;
+          && state == XML_CONTENT_STATE)
+        break;
       *nextTokPtr = ptr + 2;
       *encPtr = encodingTable[UTF_16BE_ENC];
       return XML_TOK_BOM;
     /* 00 3C is handled in the default case */
     case 0x3C00:
       if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
-	   || INIT_ENC_INDEX(enc) == UTF_16_ENC)
-	  && state == XML_CONTENT_STATE)
-	break;
+           || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+          && state == XML_CONTENT_STATE)
+        break;
       *encPtr = encodingTable[UTF_16LE_ENC];
       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
     case 0xFFFE:
       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-	  && state == XML_CONTENT_STATE)
-	break;
+          && state == XML_CONTENT_STATE)
+        break;
       *nextTokPtr = ptr + 2;
       *encPtr = encodingTable[UTF_16LE_ENC];
       return XML_TOK_BOM;
@@ -1490,45 +1550,50 @@
       /* If there's an explicitly specified (external) encoding
          of ISO-8859-1 or some flavour of UTF-16
          and this is an external text entity,
-	 don't look for the BOM,
-         because it might be a legal data. */
+         don't look for the BOM,
+         because it might be a legal data.
+      */
       if (state == XML_CONTENT_STATE) {
-	int e = INIT_ENC_INDEX(enc);
-	if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
-	  break;
+        int e = INIT_ENC_INDEX(enc);
+        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
+            || e == UTF_16LE_ENC || e == UTF_16_ENC)
+          break;
       }
       if (ptr + 2 == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if ((unsigned char)ptr[2] == 0xBF) {
-	*nextTokPtr = ptr + 3;
-	*encPtr = encodingTable[UTF_8_ENC];
-	return XML_TOK_BOM;
+        *nextTokPtr = ptr + 3;
+        *encPtr = encodingTable[UTF_8_ENC];
+        return XML_TOK_BOM;
       }
       break;
     default:
       if (ptr[0] == '\0') {
-	/* 0 isn't a legal data character. Furthermore a document entity can only
-	   start with ASCII characters.  So the only way this can fail to be big-endian
-	   UTF-16 if it it's an external parsed general entity that's labelled as
-	   UTF-16LE. */
-	if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
-	  break;
-	*encPtr = encodingTable[UTF_16BE_ENC];
-	return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+        /* 0 isn't a legal data character. Furthermore a document
+           entity can only start with ASCII characters.  So the only
+           way this can fail to be big-endian UTF-16 if it it's an
+           external parsed general entity that's labelled as
+           UTF-16LE.
+        */
+        if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+          break;
+        *encPtr = encodingTable[UTF_16BE_ENC];
+        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
       }
       else if (ptr[1] == '\0') {
-	/* We could recover here in the case:
-	    - parsing an external entity
-	    - second byte is 0
-	    - no externally specified encoding
-	    - no encoding declaration
-	   by assuming UTF-16LE.  But we don't, because this would mean when
-	   presented just with a single byte, we couldn't reliably determine
-	   whether we needed further bytes. */
-	if (state == XML_CONTENT_STATE)
-	  break;
-	*encPtr = encodingTable[UTF_16LE_ENC];
-	return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+        /* We could recover here in the case:
+            - parsing an external entity
+            - second byte is 0
+            - no externally specified encoding
+            - no encoding declaration
+           by assuming UTF-16LE.  But we don't, because this would mean when
+           presented just with a single byte, we couldn't reliably determine
+           whether we needed further bytes.
+        */
+        if (state == XML_CONTENT_STATE)
+          break;
+        *encPtr = encodingTable[UTF_16LE_ENC];
+        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
       }
       break;
     }
@@ -1556,9 +1621,9 @@
 
 ENCODING *
 XmlInitUnknownEncodingNS(void *mem,
-		         int *table,
-		         int (*convert)(void *userData, const char *p),
-		         void *userData)
+                         int *table,
+                         CONVERTER convert, 
+                         void *userData)
 {
   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
   if (enc)
diff --git a/xml/expat/lib/xmltok.h b/xml/expat/lib/xmltok.h
index 8b02324..3d776be 100644
--- a/xml/expat/lib/xmltok.h
+++ b/xml/expat/lib/xmltok.h
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 #ifndef XmlTok_INCLUDED
@@ -11,19 +10,21 @@
 #endif
 
 /* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
-                                    illegal ]]> sequence */
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_NONE -4    /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
-                                  might be part of CRLF sequence */ 
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
+                                    start of illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and
+   XmlContentTok.
+*/
+#define XML_TOK_NONE -4          /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3   /* A CR at the end of the scan;
+                                    might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2  /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1       /* only part of a token */
 #define XML_TOK_INVALID 0
 
 /* The following tokens are returned by XmlContentTok; some are also
-  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
-
+   returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
+*/
 #define XML_TOK_START_TAG_WITH_ATTS 1
 #define XML_TOK_START_TAG_NO_ATTS 2
 #define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
@@ -33,22 +34,24 @@
 #define XML_TOK_DATA_NEWLINE 7
 #define XML_TOK_CDATA_SECT_OPEN 8
 #define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10     /* numeric character reference */
+#define XML_TOK_CHAR_REF 10               /* numeric character reference */
 
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_PI 11      /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+/* The following tokens may be returned by both XmlPrologTok and
+   XmlContentTok.
+*/
+#define XML_TOK_PI 11                     /* processing instruction */
+#define XML_TOK_XML_DECL 12               /* XML decl or text decl */
 #define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14     /* Byte order mark */
+#define XML_TOK_BOM 14                    /* Byte order mark */
 
 /* The following tokens are returned only by XmlPrologTok */
 #define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_DECL_OPEN 16              /* <!foo */
+#define XML_TOK_DECL_CLOSE 17             /* > */
 #define XML_TOK_NAME 18
 #define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
+#define XML_TOK_POUND_NAME 20             /* #name */
+#define XML_TOK_OR 21                     /* | */
 #define XML_TOK_PERCENT 22
 #define XML_TOK_OPEN_PAREN 23
 #define XML_TOK_CLOSE_PAREN 24
@@ -59,14 +62,14 @@
 #define XML_TOK_INSTANCE_START 29
 
 /* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_NAME_QUESTION 30          /* name? */
+#define XML_TOK_NAME_ASTERISK 31          /* name* */
+#define XML_TOK_NAME_PLUS 32              /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33         /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34        /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35   /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36   /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37       /* )+ */
 #define XML_TOK_COMMA 38
 
 /* The following token is returned only by XmlAttributeValueTok */
@@ -75,8 +78,9 @@
 /* The following token is returned only by XmlCdataSectionTok */
 #define XML_TOK_CDATA_SECT_CLOSE 40
 
-/* With namespace processing this is returned by XmlPrologTok
-   for a name with a colon. */
+/* With namespace processing this is returned by XmlPrologTok for a
+   name with a colon.
+*/
 #define XML_TOK_PREFIXED_NAME 41
 
 #ifdef XML_DTD
@@ -121,64 +125,73 @@
 struct encoding;
 typedef struct encoding ENCODING;
 
+typedef int (PTRCALL *SCANNER)(const ENCODING *,
+                               const char *,
+                               const char *,
+                               const char **);
+
 struct encoding {
-  int (*scanners[XML_N_STATES])(const ENCODING *,
-			        const char *,
-			        const char *,
-			        const char **);
-  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
-					      const char *,
-					      const char *,
-					      const char **);
-  int (*sameName)(const ENCODING *,
-	          const char *, const char *);
-  int (*nameMatchesAscii)(const ENCODING *,
-			  const char *, const char *, const char *);
-  int (*nameLength)(const ENCODING *, const char *);
-  const char *(*skipS)(const ENCODING *, const char *);
-  int (*getAtts)(const ENCODING *enc, const char *ptr,
-	         int attsMax, ATTRIBUTE *atts);
-  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
-  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
-  void (*updatePosition)(const ENCODING *,
-			 const char *ptr,
-			 const char *end,
-			 POSITION *);
-  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-		    const char **badPtr);
-  void (*utf8Convert)(const ENCODING *enc,
-		      const char **fromP,
-		      const char *fromLim,
-		      char **toP,
-		      const char *toLim);
-  void (*utf16Convert)(const ENCODING *enc,
-		       const char **fromP,
-		       const char *fromLim,
-		       unsigned short **toP,
-		       const unsigned short *toLim);
+  SCANNER scanners[XML_N_STATES];
+  SCANNER literalScanners[XML_N_LITERAL_TYPES];
+  int (PTRCALL *sameName)(const ENCODING *,
+                          const char *,
+                          const char *);
+  int (PTRCALL *nameMatchesAscii)(const ENCODING *,
+                                  const char *,
+                                  const char *,
+                                  const char *);
+  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
+  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
+  int (PTRCALL *getAtts)(const ENCODING *enc,
+                         const char *ptr,
+                         int attsMax,
+                         ATTRIBUTE *atts);
+  int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (PTRCALL *predefinedEntityName)(const ENCODING *,
+                                      const char *,
+                                      const char *);
+  void (PTRCALL *updatePosition)(const ENCODING *,
+                                 const char *ptr,
+                                 const char *end,
+                                 POSITION *);
+  int (PTRCALL *isPublicId)(const ENCODING *enc,
+                            const char *ptr,
+                            const char *end,
+                            const char **badPtr);
+  void (PTRCALL *utf8Convert)(const ENCODING *enc,
+                              const char **fromP,
+                              const char *fromLim,
+                              char **toP,
+                              const char *toLim);
+  void (PTRCALL *utf16Convert)(const ENCODING *enc,
+                               const char **fromP,
+                               const char *fromLim,
+                               unsigned short **toP,
+                               const unsigned short *toLim);
   int minBytesPerChar;
   char isUtf8;
   char isUtf16;
 };
 
-/*
-Scan the string starting at ptr until the end of the next complete token,
-but do not scan past eptr.  Return an integer giving the type of token.
+/* Scan the string starting at ptr until the end of the next complete
+   token, but do not scan past eptr.  Return an integer giving the
+   type of token.
 
-Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+   Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
 
-Return XML_TOK_PARTIAL when the string does not contain a complete token;
-nextTokPtr will not be set.
+   Return XML_TOK_PARTIAL when the string does not contain a complete
+   token; nextTokPtr will not be set.
 
-Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
-will be set to point to the character which made the token invalid.
+   Return XML_TOK_INVALID when the string does not start a valid
+   token; nextTokPtr will be set to point to the character which made
+   the token invalid.
 
-Otherwise the string starts with a valid token; nextTokPtr will be set to point
-to the character following the end of that token.
+   Otherwise the string starts with a valid token; nextTokPtr will be
+   set to point to the character following the end of that token.
 
-Each data character counts as a single token, but adjacent data characters
-may be returned together.  Similarly for characters in the prolog outside
-literals, comments and processing instructions.
+   Each data character counts as a single token, but adjacent data
+   characters may be returned together.  Similarly for characters in
+   the prolog outside literals, comments and processing instructions.
 */
 
 
@@ -201,9 +214,9 @@
 
 #endif /* XML_DTD */
 
-/* This is used for performing a 2nd-level tokenization on
-the content of a literal that has already been returned by XmlTok. */ 
-
+/* This is used for performing a 2nd-level tokenization on the content
+   of a literal that has already been returned by XmlTok.
+*/
 #define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
   (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
 
@@ -250,48 +263,51 @@
   const ENCODING **encPtr;
 } INIT_ENCODING;
 
-int  XmlParseXmlDecl(int isGeneralTextEntity,
-			      const ENCODING *enc,
-			      const char *ptr,
-	  		      const char *end,
-			      const char **badPtr,
-			      const char **versionPtr,
-			      const char **versionEndPtr,
-			      const char **encodingNamePtr,
-			      const ENCODING **namedEncodingPtr,
-			      int *standalonePtr);
+int XmlParseXmlDecl(int isGeneralTextEntity,
+                    const ENCODING *enc,
+                    const char *ptr,
+                    const char *end,
+                    const char **badPtr,
+                    const char **versionPtr,
+                    const char **versionEndPtr,
+                    const char **encodingNamePtr,
+                    const ENCODING **namedEncodingPtr,
+                    int *standalonePtr);
 
-int  XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING  *XmlGetUtf8InternalEncoding(void);
-const ENCODING  *XmlGetUtf16InternalEncoding(void);
-int  XmlUtf8Encode(int charNumber, char *buf);
-int  XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncoding(void);
+const ENCODING *XmlGetUtf16InternalEncoding(void);
+int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
+int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
+int XmlSizeOfUnknownEncoding(void);
 
-int  XmlSizeOfUnknownEncoding(void);
-ENCODING  *
+typedef int (*CONVERTER)(void *userData, const char *p);
+
+ENCODING *
 XmlInitUnknownEncoding(void *mem,
-		       int *table,
-		       int (*conv)(void *userData, const char *p),
-		       void *userData);
+                       int *table,
+                       CONVERTER convert,
+                       void *userData);
 
-int  XmlParseXmlDeclNS(int isGeneralTextEntity,
-			        const ENCODING *enc,
-			        const char *ptr,
-	  		        const char *end,
-			        const char **badPtr,
-			        const char **versionPtr,
-				const char **versionEndPtr,
-			        const char **encodingNamePtr,
-			        const ENCODING **namedEncodingPtr,
-			        int *standalonePtr);
-int  XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING  *XmlGetUtf8InternalEncodingNS(void);
-const ENCODING  *XmlGetUtf16InternalEncodingNS(void);
-ENCODING  *
+int XmlParseXmlDeclNS(int isGeneralTextEntity,
+                      const ENCODING *enc,
+                      const char *ptr,
+                      const char *end,
+                      const char **badPtr,
+                      const char **versionPtr,
+                      const char **versionEndPtr,
+                      const char **encodingNamePtr,
+                      const ENCODING **namedEncodingPtr,
+                      int *standalonePtr);
+
+int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING *XmlGetUtf16InternalEncodingNS(void);
+ENCODING *
 XmlInitUnknownEncodingNS(void *mem,
-		         int *table,
-		         int (*conv)(void *userData, const char *p),
-		         void *userData);
+                         int *table,
+                         CONVERTER convert,
+                         void *userData);
 #ifdef __cplusplus
 }
 #endif
diff --git a/xml/expat/lib/xmltok_impl.c b/xml/expat/lib/xmltok_impl.c
index 36d2065..f3e0e52 100644
--- a/xml/expat/lib/xmltok_impl.c
+++ b/xml/expat/lib/xmltok_impl.c
@@ -1,6 +1,5 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
+/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+   See the file COPYING for copying permission.
 */
 
 #ifndef IS_INVALID_CHAR
@@ -10,7 +9,7 @@
 #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
     case BT_LEAD ## n: \
       if (end - ptr < n) \
-	return XML_TOK_PARTIAL_CHAR; \
+        return XML_TOK_PARTIAL_CHAR; \
       if (IS_INVALID_CHAR(enc, ptr, n)) { \
         *(nextTokPtr) = (ptr); \
         return XML_TOK_INVALID; \
@@ -87,9 +86,9 @@
 
 /* ptr points to character following "<!-" */
 
-static
-int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
-			const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
+                    const char *end, const char **nextTokPtr)
 {
   if (ptr != end) {
     if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
@@ -101,22 +100,22 @@
       switch (BYTE_TYPE(enc, ptr)) {
       INVALID_CASES(ptr, nextTokPtr)
       case BT_MINUS:
-	if ((ptr += MINBPC(enc)) == end)
-	  return XML_TOK_PARTIAL;
-	if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
-	  if ((ptr += MINBPC(enc)) == end)
-	    return XML_TOK_PARTIAL;
-	  if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	    *nextTokPtr = ptr;
-	    return XML_TOK_INVALID;
-	  }
-	  *nextTokPtr = ptr + MINBPC(enc);
-	  return XML_TOK_COMMENT;
-	}
-	break;
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+          if ((ptr += MINBPC(enc)) == end)
+            return XML_TOK_PARTIAL;
+          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_COMMENT;
+        }
+        break;
       default:
-	ptr += MINBPC(enc);
-	break;
+        ptr += MINBPC(enc);
+        break;
       }
     }
   }
@@ -125,9 +124,9 @@
 
 /* ptr points to character following "<!" */
 
-static
-int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
-		     const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
+                 const char *end, const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_PARTIAL;
@@ -149,12 +148,12 @@
     switch (BYTE_TYPE(enc, ptr)) {
     case BT_PERCNT:
       if (ptr + MINBPC(enc) == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       /* don't allow <!ENTITY% foo "whatever"> */
       switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
       case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       /* fall through */
     case BT_S: case BT_CR: case BT_LF:
@@ -172,8 +171,9 @@
   return XML_TOK_PARTIAL;
 }
 
-static
-int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
+static int PTRCALL
+PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+                      const char *end, int *tokPtr)
 {
   int upper = 0;
   *tokPtr = XML_TOK_PI;
@@ -216,9 +216,9 @@
 
 /* ptr points to character following "<?" */
 
-static
-int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
-		   const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
+               const char *end, const char **nextTokPtr)
 {
   int tok;
   const char *target = ptr;
@@ -235,39 +235,39 @@
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_S: case BT_CR: case BT_LF:
       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       ptr += MINBPC(enc);
       while (ptr != end) {
         switch (BYTE_TYPE(enc, ptr)) {
         INVALID_CASES(ptr, nextTokPtr)
-	case BT_QUEST:
-	  ptr += MINBPC(enc);
-	  if (ptr == end)
-	    return XML_TOK_PARTIAL;
-	  if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	    *nextTokPtr = ptr + MINBPC(enc);
-	    return tok;
-	  }
-	  break;
-	default:
-	  ptr += MINBPC(enc);
-	  break;
-	}
+        case BT_QUEST:
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+            *nextTokPtr = ptr + MINBPC(enc);
+            return tok;
+          }
+          break;
+        default:
+          ptr += MINBPC(enc);
+          break;
+        }
       }
       return XML_TOK_PARTIAL;
     case BT_QUEST:
       if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       ptr += MINBPC(enc);
       if (ptr == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	*nextTokPtr = ptr + MINBPC(enc);
-	return tok;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return tok;
       }
       /* fall through */
     default:
@@ -278,12 +278,12 @@
   return XML_TOK_PARTIAL;
 }
 
-
-static
-int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
-			     const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+                         const char *end, const char **nextTokPtr)
 {
-  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB };
+  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
+                                     ASCII_T, ASCII_A, ASCII_LSQB };
   int i;
   /* CDATA[ */
   if (end - ptr < 6 * MINBPC(enc))
@@ -298,9 +298,9 @@
   return XML_TOK_CDATA_SECT_OPEN;
 }
 
-static
-int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
-			    const char **nextTokPtr)
+static int PTRCALL
+PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
+                        const char *end, const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_NONE;
@@ -309,7 +309,7 @@
     if (n & (MINBPC(enc) - 1)) {
       n &= ~(MINBPC(enc) - 1);
       if (n == 0)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       end = ptr + n;
     }
   }
@@ -350,8 +350,8 @@
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
       if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-	*nextTokPtr = ptr; \
-	return XML_TOK_DATA_CHARS; \
+        *nextTokPtr = ptr; \
+        return XML_TOK_DATA_CHARS; \
       } \
       ptr += n; \
       break;
@@ -376,9 +376,9 @@
 
 /* ptr points to character following "</" */
 
-static
-int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
-		       const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
+                   const char *end, const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_PARTIAL;
@@ -393,21 +393,22 @@
     CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
     case BT_S: case BT_CR: case BT_LF:
       for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-	switch (BYTE_TYPE(enc, ptr)) {
-	case BT_S: case BT_CR: case BT_LF:
-	  break;
-	case BT_GT:
-	  *nextTokPtr = ptr + MINBPC(enc);
+        switch (BYTE_TYPE(enc, ptr)) {
+        case BT_S: case BT_CR: case BT_LF:
+          break;
+        case BT_GT:
+          *nextTokPtr = ptr + MINBPC(enc);
           return XML_TOK_END_TAG;
-	default:
-	  *nextTokPtr = ptr;
-	  return XML_TOK_INVALID;
-	}
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
       }
       return XML_TOK_PARTIAL;
 #ifdef XML_NS
     case BT_COLON:
-      /* no need to check qname syntax here, since end-tag must match exactly */
+      /* no need to check qname syntax here,
+         since end-tag must match exactly */
       ptr += MINBPC(enc);
       break;
 #endif
@@ -424,9 +425,9 @@
 
 /* ptr points to character following "&#X" */
 
-static
-int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-			   const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
+                       const char *end, const char **nextTokPtr)
 {
   if (ptr != end) {
     switch (BYTE_TYPE(enc, ptr)) {
@@ -441,13 +442,13 @@
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_DIGIT:
       case BT_HEX:
-	break;
+        break;
       case BT_SEMI:
-	*nextTokPtr = ptr + MINBPC(enc);
-	return XML_TOK_CHAR_REF;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_CHAR_REF;
       default:
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
     }
   }
@@ -456,9 +457,9 @@
 
 /* ptr points to character following "&#" */
 
-static
-int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-			const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
+                    const char *end, const char **nextTokPtr)
 {
   if (ptr != end) {
     if (CHAR_MATCHES(enc, ptr, ASCII_x))
@@ -473,13 +474,13 @@
     for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_DIGIT:
-	break;
+        break;
       case BT_SEMI:
-	*nextTokPtr = ptr + MINBPC(enc);
-	return XML_TOK_CHAR_REF;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_CHAR_REF;
       default:
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
     }
   }
@@ -488,9 +489,9 @@
 
 /* ptr points to character following "&" */
 
-static
-int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
-		    const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+                const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_PARTIAL;
@@ -518,9 +519,9 @@
 
 /* ptr points to character following first character of attribute name */
 
-static
-int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
-		     const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+                 const char **nextTokPtr)
 {
 #ifdef XML_NS
   int hadColon = 0;
@@ -531,142 +532,141 @@
 #ifdef XML_NS
     case BT_COLON:
       if (hadColon) {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       hadColon = 1;
       ptr += MINBPC(enc);
       if (ptr == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       switch (BYTE_TYPE(enc, ptr)) {
       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       break;
 #endif
     case BT_S: case BT_CR: case BT_LF:
       for (;;) {
-	int t;
+        int t;
 
-	ptr += MINBPC(enc);
-	if (ptr == end)
-	  return XML_TOK_PARTIAL;
-	t = BYTE_TYPE(enc, ptr);
-	if (t == BT_EQUALS)
-	  break;
-	switch (t) {
-	case BT_S:
-	case BT_LF:
-	case BT_CR:
-	  break;
-	default:
-	  *nextTokPtr = ptr;
-	  return XML_TOK_INVALID;
-	}
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        t = BYTE_TYPE(enc, ptr);
+        if (t == BT_EQUALS)
+          break;
+        switch (t) {
+        case BT_S:
+        case BT_LF:
+        case BT_CR:
+          break;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
       }
     /* fall through */
     case BT_EQUALS:
       {
-	int open;
+        int open;
 #ifdef XML_NS
-	hadColon = 0;
+        hadColon = 0;
 #endif
-	for (;;) {
-	  
-	  ptr += MINBPC(enc);
-	  if (ptr == end)
-	    return XML_TOK_PARTIAL;
-	  open = BYTE_TYPE(enc, ptr);
-	  if (open == BT_QUOT || open == BT_APOS)
-	    break;
-	  switch (open) {
-	  case BT_S:
-	  case BT_LF:
-	  case BT_CR:
-	    break;
-	  default:
-	    *nextTokPtr = ptr;
-	    return XML_TOK_INVALID;
-	  }
-	}
-	ptr += MINBPC(enc);
-	/* in attribute value */
-	for (;;) {
-	  int t;
-	  if (ptr == end)
-	    return XML_TOK_PARTIAL;
-	  t = BYTE_TYPE(enc, ptr);
-	  if (t == open)
-	    break;
-	  switch (t) {
-	  INVALID_CASES(ptr, nextTokPtr)
-	  case BT_AMP:
-	    {
-	      int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
-	      if (tok <= 0) {
-		if (tok == XML_TOK_INVALID)
-		  *nextTokPtr = ptr;
-		return tok;
-	      }
-	      break;
-	    }
-	  case BT_LT:
-	    *nextTokPtr = ptr;
-	    return XML_TOK_INVALID;
-	  default:
-	    ptr += MINBPC(enc);
-	    break;
-	  }
-	}
-	ptr += MINBPC(enc);
-	if (ptr == end)
-	  return XML_TOK_PARTIAL;
-	switch (BYTE_TYPE(enc, ptr)) {
-	case BT_S:
-	case BT_CR:
-	case BT_LF:
-	  break;
-	case BT_SOL:
-	  goto sol;
-	case BT_GT:
-	  goto gt;
-	default:
-	  *nextTokPtr = ptr;
-	  return XML_TOK_INVALID;
-	}
-	/* ptr points to closing quote */
-	for (;;) {
-	  ptr += MINBPC(enc);
-	  if (ptr == end)
-	    return XML_TOK_PARTIAL;
-	  switch (BYTE_TYPE(enc, ptr)) {
-	  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-	  case BT_S: case BT_CR: case BT_LF:
-	    continue;
-	  case BT_GT:
+        for (;;) {
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          open = BYTE_TYPE(enc, ptr);
+          if (open == BT_QUOT || open == BT_APOS)
+            break;
+          switch (open) {
+          case BT_S:
+          case BT_LF:
+          case BT_CR:
+            break;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+        }
+        ptr += MINBPC(enc);
+        /* in attribute value */
+        for (;;) {
+          int t;
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          t = BYTE_TYPE(enc, ptr);
+          if (t == open)
+            break;
+          switch (t) {
+          INVALID_CASES(ptr, nextTokPtr)
+          case BT_AMP:
+            {
+              int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+              if (tok <= 0) {
+                if (tok == XML_TOK_INVALID)
+                  *nextTokPtr = ptr;
+                return tok;
+              }
+              break;
+            }
+          case BT_LT:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          default:
+            ptr += MINBPC(enc);
+            break;
+          }
+        }
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        switch (BYTE_TYPE(enc, ptr)) {
+        case BT_S:
+        case BT_CR:
+        case BT_LF:
+          break;
+        case BT_SOL:
+          goto sol;
+        case BT_GT:
+          goto gt;
+        default:
+          *nextTokPtr = ptr;
+          return XML_TOK_INVALID;
+        }
+        /* ptr points to closing quote */
+        for (;;) {
+          ptr += MINBPC(enc);
+          if (ptr == end)
+            return XML_TOK_PARTIAL;
+          switch (BYTE_TYPE(enc, ptr)) {
+          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+          case BT_S: case BT_CR: case BT_LF:
+            continue;
+          case BT_GT:
           gt:
-	    *nextTokPtr = ptr + MINBPC(enc);
-	    return XML_TOK_START_TAG_WITH_ATTS;
-	  case BT_SOL:
+            *nextTokPtr = ptr + MINBPC(enc);
+            return XML_TOK_START_TAG_WITH_ATTS;
+          case BT_SOL:
           sol:
-	    ptr += MINBPC(enc);
-	    if (ptr == end)
-	      return XML_TOK_PARTIAL;
-	    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	      *nextTokPtr = ptr;
-	      return XML_TOK_INVALID;
-	    }
-	    *nextTokPtr = ptr + MINBPC(enc);
-	    return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
-	  default:
-	    *nextTokPtr = ptr;
-	    return XML_TOK_INVALID;
-	  }
-	  break;
-	}
-	break;
+            ptr += MINBPC(enc);
+            if (ptr == end)
+              return XML_TOK_PARTIAL;
+            if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+              *nextTokPtr = ptr;
+              return XML_TOK_INVALID;
+            }
+            *nextTokPtr = ptr + MINBPC(enc);
+            return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          break;
+        }
+        break;
       }
     default:
       *nextTokPtr = ptr;
@@ -678,9 +678,9 @@
 
 /* ptr points to character following "<" */
 
-static
-int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
-		   const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+               const char **nextTokPtr)
 {
 #ifdef XML_NS
   int hadColon;
@@ -696,7 +696,8 @@
     case BT_MINUS:
       return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
     case BT_LSQB:
-      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
+                                      end, nextTokPtr);
     }
     *nextTokPtr = ptr;
     return XML_TOK_INVALID;
@@ -718,13 +719,13 @@
 #ifdef XML_NS
     case BT_COLON:
       if (hadColon) {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       hadColon = 1;
       ptr += MINBPC(enc);
       if (ptr == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       switch (BYTE_TYPE(enc, ptr)) {
       CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
       default:
@@ -736,23 +737,23 @@
     case BT_S: case BT_CR: case BT_LF:
       {
         ptr += MINBPC(enc);
-	while (ptr != end) {
-	  switch (BYTE_TYPE(enc, ptr)) {
-	  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-	  case BT_GT:
-	    goto gt;
-	  case BT_SOL:
-	    goto sol;
-	  case BT_S: case BT_CR: case BT_LF:
-	    ptr += MINBPC(enc);
-	    continue;
-	  default:
-	    *nextTokPtr = ptr;
-	    return XML_TOK_INVALID;
-	  }
-	  return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
-	}
-	return XML_TOK_PARTIAL;
+        while (ptr != end) {
+          switch (BYTE_TYPE(enc, ptr)) {
+          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+          case BT_GT:
+            goto gt;
+          case BT_SOL:
+            goto sol;
+          case BT_S: case BT_CR: case BT_LF:
+            ptr += MINBPC(enc);
+            continue;
+          default:
+            *nextTokPtr = ptr;
+            return XML_TOK_INVALID;
+          }
+          return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+        }
+        return XML_TOK_PARTIAL;
       }
     case BT_GT:
     gt:
@@ -762,10 +763,10 @@
     sol:
       ptr += MINBPC(enc);
       if (ptr == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
@@ -777,9 +778,9 @@
   return XML_TOK_PARTIAL;
 }
 
-static
-int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
-		       const char **nextTokPtr)
+static int PTRCALL
+PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_NONE;
@@ -788,7 +789,7 @@
     if (n & (MINBPC(enc) - 1)) {
       n &= ~(MINBPC(enc) - 1);
       if (n == 0)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       end = ptr + n;
     }
   }
@@ -833,8 +834,8 @@
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
       if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-	*nextTokPtr = ptr; \
-	return XML_TOK_DATA_CHARS; \
+        *nextTokPtr = ptr; \
+        return XML_TOK_DATA_CHARS; \
       } \
       ptr += n; \
       break;
@@ -842,18 +843,18 @@
 #undef LEAD_CASE
     case BT_RSQB:
       if (ptr + MINBPC(enc) != end) {
-	 if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
-	   ptr += MINBPC(enc);
-	   break;
-	 }
-	 if (ptr + 2*MINBPC(enc) != end) {
-	   if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
-	     ptr += MINBPC(enc);
-	     break;
-	   }
-	   *nextTokPtr = ptr + 2*MINBPC(enc);
-	   return XML_TOK_INVALID;
-	 }
+         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+           ptr += MINBPC(enc);
+           break;
+         }
+         if (ptr + 2*MINBPC(enc) != end) {
+           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+             ptr += MINBPC(enc);
+             break;
+           }
+           *nextTokPtr = ptr + 2*MINBPC(enc);
+           return XML_TOK_INVALID;
+         }
       }
       /* fall through */
     case BT_AMP:
@@ -876,12 +877,12 @@
 
 /* ptr points to character following "%" */
 
-static
-int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
-			const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
 {
   if (ptr == end)
-    return XML_TOK_PARTIAL;
+    return -XML_TOK_PERCENT;
   switch (BYTE_TYPE(enc, ptr)) {
   CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
   case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
@@ -905,9 +906,9 @@
   return XML_TOK_PARTIAL;
 }
 
-static
-int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
-			  const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
 {
   if (ptr == end)
     return XML_TOK_PARTIAL;
@@ -932,10 +933,10 @@
   return -XML_TOK_POUND_NAME;
 }
 
-static
-int PREFIX(scanLit)(int open, const ENCODING *enc,
-		    const char *ptr, const char *end,
-		    const char **nextTokPtr)
+static int PTRCALL
+PREFIX(scanLit)(int open, const ENCODING *enc,
+                const char *ptr, const char *end,
+                const char **nextTokPtr)
 {
   while (ptr != end) {
     int t = BYTE_TYPE(enc, ptr);
@@ -945,16 +946,16 @@
     case BT_APOS:
       ptr += MINBPC(enc);
       if (t != open)
-	break;
+        break;
       if (ptr == end)
-	return -XML_TOK_LITERAL;
+        return -XML_TOK_LITERAL;
       *nextTokPtr = ptr;
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_S: case BT_CR: case BT_LF:
       case BT_GT: case BT_PERCNT: case BT_LSQB:
-	return XML_TOK_LITERAL;
+        return XML_TOK_LITERAL;
       default:
-	return XML_TOK_INVALID;
+        return XML_TOK_INVALID;
       }
     default:
       ptr += MINBPC(enc);
@@ -964,9 +965,9 @@
   return XML_TOK_PARTIAL;
 }
 
-static
-int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
-		      const char **nextTokPtr)
+static int PTRCALL
+PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
 {
   int tok;
   if (ptr == end)
@@ -976,7 +977,7 @@
     if (n & (MINBPC(enc) - 1)) {
       n &= ~(MINBPC(enc) - 1);
       if (n == 0)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       end = ptr + n;
     }
   }
@@ -989,44 +990,47 @@
     {
       ptr += MINBPC(enc);
       if (ptr == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_EXCL:
-	return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+        return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
       case BT_QUEST:
-	return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
       case BT_NMSTRT:
       case BT_HEX:
       case BT_NONASCII:
       case BT_LEAD2:
       case BT_LEAD3:
       case BT_LEAD4:
-	*nextTokPtr = ptr - MINBPC(enc);
-	return XML_TOK_INSTANCE_START;
+        *nextTokPtr = ptr - MINBPC(enc);
+        return XML_TOK_INSTANCE_START;
       }
       *nextTokPtr = ptr;
       return XML_TOK_INVALID;
     }
   case BT_CR:
-    if (ptr + MINBPC(enc) == end)
+    if (ptr + MINBPC(enc) == end) {
+      *nextTokPtr = end;
+      /* indicate that this might be part of a CR/LF pair */
       return -XML_TOK_PROLOG_S;
+    }
     /* fall through */
   case BT_S: case BT_LF:
     for (;;) {
       ptr += MINBPC(enc);
       if (ptr == end)
-	break;
+        break;
       switch (BYTE_TYPE(enc, ptr)) {
       case BT_S: case BT_LF:
-	break;
+        break;
       case BT_CR:
-	/* don't split CR/LF pair */
-	if (ptr + MINBPC(enc) != end)
-	  break;
-	/* fall through */
+        /* don't split CR/LF pair */
+        if (ptr + MINBPC(enc) != end)
+          break;
+        /* fall through */
       default:
-	*nextTokPtr = ptr;
-	return XML_TOK_PROLOG_S;
+        *nextTokPtr = ptr;
+        return XML_TOK_PROLOG_S;
       }
     }
     *nextTokPtr = ptr;
@@ -1045,10 +1049,10 @@
       return -XML_TOK_CLOSE_BRACKET;
     if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
       if (ptr + MINBPC(enc) == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
-	*nextTokPtr = ptr + 2*MINBPC(enc);
-	return XML_TOK_COND_SECT_CLOSE;
+        *nextTokPtr = ptr + 2*MINBPC(enc);
+        return XML_TOK_COND_SECT_CLOSE;
       }
     }
     *nextTokPtr = ptr;
@@ -1147,40 +1151,40 @@
       ptr += MINBPC(enc);
       switch (tok) {
       case XML_TOK_NAME:
-	if (ptr == end)
-	  return XML_TOK_PARTIAL;
-	tok = XML_TOK_PREFIXED_NAME;
-	switch (BYTE_TYPE(enc, ptr)) {
-	CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-	default:
-	  tok = XML_TOK_NMTOKEN;
-	  break;
-	}
-	break;
+        if (ptr == end)
+          return XML_TOK_PARTIAL;
+        tok = XML_TOK_PREFIXED_NAME;
+        switch (BYTE_TYPE(enc, ptr)) {
+        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+        default:
+          tok = XML_TOK_NMTOKEN;
+          break;
+        }
+        break;
       case XML_TOK_PREFIXED_NAME:
-	tok = XML_TOK_NMTOKEN;
-	break;
+        tok = XML_TOK_NMTOKEN;
+        break;
       }
       break;
 #endif
     case BT_PLUS:
       if (tok == XML_TOK_NMTOKEN)  {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_NAME_PLUS;
     case BT_AST:
       if (tok == XML_TOK_NMTOKEN)  {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_NAME_ASTERISK;
     case BT_QUEST:
       if (tok == XML_TOK_NMTOKEN)  {
-	*nextTokPtr = ptr;
-	return XML_TOK_INVALID;
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
       }
       *nextTokPtr = ptr + MINBPC(enc);
       return XML_TOK_NAME_QUESTION;
@@ -1192,9 +1196,9 @@
   return -tok;
 }
 
-static
-int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-			      const char **nextTokPtr)
+static int PTRCALL
+PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
+                          const char *end, const char **nextTokPtr)
 {
   const char *start;
   if (ptr == end)
@@ -1208,7 +1212,7 @@
 #undef LEAD_CASE
     case BT_AMP:
       if (ptr == start)
-	return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_LT:
@@ -1217,27 +1221,27 @@
       return XML_TOK_INVALID;
     case BT_LF:
       if (ptr == start) {
-	*nextTokPtr = ptr + MINBPC(enc);
-	return XML_TOK_DATA_NEWLINE;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_DATA_NEWLINE;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_CR:
       if (ptr == start) {
-	ptr += MINBPC(enc);
-	if (ptr == end)
-	  return XML_TOK_TRAILING_CR;
-	if (BYTE_TYPE(enc, ptr) == BT_LF)
-	  ptr += MINBPC(enc);
-	*nextTokPtr = ptr;
-	return XML_TOK_DATA_NEWLINE;
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_TRAILING_CR;
+        if (BYTE_TYPE(enc, ptr) == BT_LF)
+          ptr += MINBPC(enc);
+        *nextTokPtr = ptr;
+        return XML_TOK_DATA_NEWLINE;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_S:
       if (ptr == start) {
-	*nextTokPtr = ptr + MINBPC(enc);
-	return XML_TOK_ATTRIBUTE_VALUE_S;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_ATTRIBUTE_VALUE_S;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
@@ -1250,9 +1254,9 @@
   return XML_TOK_DATA_CHARS;
 }
 
-static
-int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-			   const char **nextTokPtr)
+static int PTRCALL
+PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
+                       const char *end, const char **nextTokPtr)
 {
   const char *start;
   if (ptr == end)
@@ -1266,33 +1270,33 @@
 #undef LEAD_CASE
     case BT_AMP:
       if (ptr == start)
-	return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_PERCNT:
       if (ptr == start) {
-	int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
-				       end, nextTokPtr);
-	return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+        int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+                                       end, nextTokPtr);
+        return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_LF:
       if (ptr == start) {
-	*nextTokPtr = ptr + MINBPC(enc);
-	return XML_TOK_DATA_NEWLINE;
+        *nextTokPtr = ptr + MINBPC(enc);
+        return XML_TOK_DATA_NEWLINE;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
     case BT_CR:
       if (ptr == start) {
-	ptr += MINBPC(enc);
-	if (ptr == end)
-	  return XML_TOK_TRAILING_CR;
-	if (BYTE_TYPE(enc, ptr) == BT_LF)
-	  ptr += MINBPC(enc);
-	*nextTokPtr = ptr;
-	return XML_TOK_DATA_NEWLINE;
+        ptr += MINBPC(enc);
+        if (ptr == end)
+          return XML_TOK_TRAILING_CR;
+        if (BYTE_TYPE(enc, ptr) == BT_LF)
+          ptr += MINBPC(enc);
+        *nextTokPtr = ptr;
+        return XML_TOK_DATA_NEWLINE;
       }
       *nextTokPtr = ptr;
       return XML_TOK_DATA_CHARS;
@@ -1307,9 +1311,9 @@
 
 #ifdef XML_DTD
 
-static
-int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
-			     const char **nextTokPtr)
+static int PTRCALL
+PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
+                         const char *end, const char **nextTokPtr)
 {
   int level = 0;
   if (MINBPC(enc) > 1) {
@@ -1324,30 +1328,30 @@
     INVALID_CASES(ptr, nextTokPtr)
     case BT_LT:
       if ((ptr += MINBPC(enc)) == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
-	if ((ptr += MINBPC(enc)) == end)
-	  return XML_TOK_PARTIAL;
-	if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
-	  ++level;
-	  ptr += MINBPC(enc);
-	}
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+          ++level;
+          ptr += MINBPC(enc);
+        }
       }
       break;
     case BT_RSQB:
       if ((ptr += MINBPC(enc)) == end)
-	return XML_TOK_PARTIAL;
+        return XML_TOK_PARTIAL;
       if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
-	if ((ptr += MINBPC(enc)) == end)
-	  return XML_TOK_PARTIAL;
-	if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
-	  ptr += MINBPC(enc);
-	  if (level == 0) {
-	    *nextTokPtr = ptr;
-	    return XML_TOK_IGNORE_SECT;
-	  }
-	  --level;
-	}
+        if ((ptr += MINBPC(enc)) == end)
+          return XML_TOK_PARTIAL;
+        if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+          ptr += MINBPC(enc);
+          if (level == 0) {
+            *nextTokPtr = ptr;
+            return XML_TOK_IGNORE_SECT;
+          }
+          --level;
+        }
       }
       break;
     default:
@@ -1360,9 +1364,9 @@
 
 #endif /* XML_DTD */
 
-static
-int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-		       const char **badPtr)
+static int PTRCALL
+PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **badPtr)
 {
   ptr += MINBPC(enc);
   end -= MINBPC(enc);
@@ -1392,22 +1396,22 @@
       break;
     case BT_S:
       if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
-	*badPtr = ptr;
-	return 0;
+        *badPtr = ptr;
+        return 0;
       }
       break;
     case BT_NAME:
     case BT_NMSTRT:
       if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
-	break;
+        break;
     default:
       switch (BYTE_TO_ASCII(enc, ptr)) {
       case 0x24: /* $ */
       case 0x40: /* @ */
-	break;
+        break;
       default:
-	*badPtr = ptr;
-	return 0;
+        *badPtr = ptr;
+        return 0;
       }
       break;
     }
@@ -1415,28 +1419,29 @@
   return 1;
 }
 
-/* This must only be called for a well-formed start-tag or empty element tag.
-Returns the number of attributes.  Pointers to the first attsMax attributes 
-are stored in atts. */
+/* This must only be called for a well-formed start-tag or empty
+   element tag.  Returns the number of attributes.  Pointers to the
+   first attsMax attributes are stored in atts.
+*/
 
-static
-int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
-		    int attsMax, ATTRIBUTE *atts)
+static int PTRCALL
+PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+                int attsMax, ATTRIBUTE *atts)
 {
   enum { other, inName, inValue } state = inName;
   int nAtts = 0;
   int open = 0; /* defined when state == inValue;
-		   initialization just to shut up compilers */
+                   initialization just to shut up compilers */
 
   for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define START_NAME \
       if (state == other) { \
-	if (nAtts < attsMax) { \
-	  atts[nAtts].name = ptr; \
-	  atts[nAtts].normalized = 1; \
-	} \
-	state = inName; \
+        if (nAtts < attsMax) { \
+          atts[nAtts].name = ptr; \
+          atts[nAtts].normalized = 1; \
+        } \
+        state = inName; \
       }
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
@@ -1450,47 +1455,47 @@
 #undef START_NAME
     case BT_QUOT:
       if (state != inValue) {
-	if (nAtts < attsMax)
-	  atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        if (nAtts < attsMax)
+          atts[nAtts].valuePtr = ptr + MINBPC(enc);
         state = inValue;
         open = BT_QUOT;
       }
       else if (open == BT_QUOT) {
         state = other;
-	if (nAtts < attsMax)
-	  atts[nAtts].valueEnd = ptr;
-	nAtts++;
+        if (nAtts < attsMax)
+          atts[nAtts].valueEnd = ptr;
+        nAtts++;
       }
       break;
     case BT_APOS:
       if (state != inValue) {
-	if (nAtts < attsMax)
-	  atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        if (nAtts < attsMax)
+          atts[nAtts].valuePtr = ptr + MINBPC(enc);
         state = inValue;
         open = BT_APOS;
       }
       else if (open == BT_APOS) {
         state = other;
-	if (nAtts < attsMax)
-	  atts[nAtts].valueEnd = ptr;
-	nAtts++;
+        if (nAtts < attsMax)
+          atts[nAtts].valueEnd = ptr;
+        nAtts++;
       }
       break;
     case BT_AMP:
       if (nAtts < attsMax)
-	atts[nAtts].normalized = 0;
+        atts[nAtts].normalized = 0;
       break;
     case BT_S:
       if (state == inName)
         state = other;
       else if (state == inValue
-	       && nAtts < attsMax
-	       && atts[nAtts].normalized
-	       && (ptr == atts[nAtts].valuePtr
-		   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
-		   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
-	           || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
-	atts[nAtts].normalized = 0;
+               && nAtts < attsMax
+               && atts[nAtts].normalized
+               && (ptr == atts[nAtts].valuePtr
+                   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+                   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+                   || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+        atts[nAtts].normalized = 0;
       break;
     case BT_CR: case BT_LF:
       /* This case ensures that the first attribute name is counted
@@ -1498,12 +1503,12 @@
       if (state == inName)
         state = other;
       else if (state == inValue && nAtts < attsMax)
-	atts[nAtts].normalized = 0;
+        atts[nAtts].normalized = 0;
       break;
     case BT_GT:
     case BT_SOL:
       if (state != inValue)
-	return nAtts;
+        return nAtts;
       break;
     default:
       break;
@@ -1512,32 +1517,36 @@
   /* not reached */
 }
 
-static
-int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+static int PTRFASTCALL
+PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
 {
   int result = 0;
   /* skip &# */
   ptr += 2*MINBPC(enc);
   if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
-    for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+    for (ptr += MINBPC(enc);
+         !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
+         ptr += MINBPC(enc)) {
       int c = BYTE_TO_ASCII(enc, ptr);
       switch (c) {
       case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
       case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
-	result <<= 4;
-	result |= (c - ASCII_0);
-	break;
-      case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F:
-	result <<= 4;
-	result += 10 + (c - ASCII_A);
-	break;
-      case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f:
-	result <<= 4;
-	result += 10 + (c - ASCII_a);
-	break;
+        result <<= 4;
+        result |= (c - ASCII_0);
+        break;
+      case ASCII_A: case ASCII_B: case ASCII_C:
+      case ASCII_D: case ASCII_E: case ASCII_F:
+        result <<= 4;
+        result += 10 + (c - ASCII_A);
+        break;
+      case ASCII_a: case ASCII_b: case ASCII_c:
+      case ASCII_d: case ASCII_e: case ASCII_f:
+        result <<= 4;
+        result += 10 + (c - ASCII_a);
+        break;
       }
       if (result >= 0x110000)
-	return -1;
+        return -1;
     }
   }
   else {
@@ -1546,23 +1555,24 @@
       result *= 10;
       result += (c - ASCII_0);
       if (result >= 0x110000)
-	return -1;
+        return -1;
     }
   }
   return checkCharRefNumber(result);
 }
 
-static
-int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
+static int PTRCALL
+PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+                             const char *end)
 {
   switch ((end - ptr)/MINBPC(enc)) {
   case 2:
     if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
       switch (BYTE_TO_ASCII(enc, ptr)) {
       case ASCII_l:
-	return ASCII_LT;
+        return ASCII_LT;
       case ASCII_g:
-	return ASCII_GT;
+        return ASCII_GT;
       }
     }
     break;
@@ -1570,9 +1580,9 @@
     if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
       ptr += MINBPC(enc);
       if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
-	ptr += MINBPC(enc);
-	if (CHAR_MATCHES(enc, ptr, ASCII_p))
-	  return ASCII_AMP;
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_p))
+          return ASCII_AMP;
       }
     }
     break;
@@ -1581,23 +1591,23 @@
     case ASCII_q:
       ptr += MINBPC(enc);
       if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
-	ptr += MINBPC(enc);
-	if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
-	  ptr += MINBPC(enc);
-  	  if (CHAR_MATCHES(enc, ptr, ASCII_t))
-	    return ASCII_QUOT;
-	}
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+          ptr += MINBPC(enc);
+          if (CHAR_MATCHES(enc, ptr, ASCII_t))
+            return ASCII_QUOT;
+        }
       }
       break;
     case ASCII_a:
       ptr += MINBPC(enc);
       if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
-	ptr += MINBPC(enc);
-	if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
-	  ptr += MINBPC(enc);
-  	  if (CHAR_MATCHES(enc, ptr, ASCII_s))
-	    return ASCII_APOS;
-	}
+        ptr += MINBPC(enc);
+        if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+          ptr += MINBPC(enc);
+          if (CHAR_MATCHES(enc, ptr, ASCII_s))
+            return ASCII_APOS;
+        }
       }
       break;
     }
@@ -1605,20 +1615,20 @@
   return 0;
 }
 
-static
-int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+static int PTRCALL
+PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
 {
   for (;;) {
     switch (BYTE_TYPE(enc, ptr1)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
       if (*ptr1++ != *ptr2++) \
-	return 0;
+        return 0;
     LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
 #undef LEAD_CASE
       /* fall through */
       if (*ptr1++ != *ptr2++)
-	return 0;
+        return 0;
       break;
     case BT_NONASCII:
     case BT_NMSTRT:
@@ -1630,23 +1640,23 @@
     case BT_NAME:
     case BT_MINUS:
       if (*ptr2++ != *ptr1++)
-	return 0;
+        return 0;
       if (MINBPC(enc) > 1) {
-	if (*ptr2++ != *ptr1++)
-	  return 0;
-	if (MINBPC(enc) > 2) {
-	  if (*ptr2++ != *ptr1++)
-	    return 0;
+        if (*ptr2++ != *ptr1++)
+          return 0;
+        if (MINBPC(enc) > 2) {
+          if (*ptr2++ != *ptr1++)
+            return 0;
           if (MINBPC(enc) > 3) {
-	    if (*ptr2++ != *ptr1++)
-      	      return 0;
-	  }
-	}
+            if (*ptr2++ != *ptr1++)
+              return 0;
+          }
+        }
       }
       break;
     default:
       if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
-	return 1;
+        return 1;
       switch (BYTE_TYPE(enc, ptr2)) {
       case BT_LEAD2:
       case BT_LEAD3:
@@ -1660,18 +1670,18 @@
       case BT_DIGIT:
       case BT_NAME:
       case BT_MINUS:
-	return 0;
+        return 0;
       default:
-	return 1;
+        return 1;
       }
     }
   }
   /* not reached */
 }
 
-static
-int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
-			     const char *end1, const char *ptr2)
+static int PTRCALL
+PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+                         const char *end1, const char *ptr2)
 {
   for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
     if (ptr1 == end1)
@@ -1682,8 +1692,8 @@
   return ptr1 == end1;
 }
 
-static
-int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+static int PTRFASTCALL
+PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
 {
   const char *start = ptr;
   for (;;) {
@@ -1709,8 +1719,8 @@
   }
 }
 
-static
-const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+static const char * PTRFASTCALL
+PREFIX(skipS)(const ENCODING *enc, const char *ptr)
 {
   for (;;) {
     switch (BYTE_TYPE(enc, ptr)) {
@@ -1725,13 +1735,13 @@
   }
 }
 
-static
-void PREFIX(updatePosition)(const ENCODING *enc,
-			    const char *ptr,
-			    const char *end,
-			    POSITION *pos)
+static void PTRCALL
+PREFIX(updatePosition)(const ENCODING *enc,
+                       const char *ptr,
+                       const char *end,
+                       POSITION *pos)
 {
-  while (ptr != end) {
+  while (ptr < end) {
     switch (BYTE_TYPE(enc, ptr)) {
 #define LEAD_CASE(n) \
     case BT_LEAD ## n: \
@@ -1748,7 +1758,7 @@
       pos->lineNumber++;
       ptr += MINBPC(enc);
       if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
-	ptr += MINBPC(enc);
+        ptr += MINBPC(enc);
       pos->columnNumber = (unsigned)-1;
       break;
     default:
@@ -1766,3 +1776,4 @@
 #undef CHECK_NAME_CASES
 #undef CHECK_NMSTRT_CASE
 #undef CHECK_NMSTRT_CASES
+
diff --git a/xml/expat/lib/xmltok_ns.c b/xml/expat/lib/xmltok_ns.c
index 2185973..5610eb9 100644
--- a/xml/expat/lib/xmltok_ns.c
+++ b/xml/expat/lib/xmltok_ns.c
@@ -1,22 +1,25 @@
-const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
+const ENCODING *
+NS(XmlGetUtf8InternalEncoding)(void)
 {
   return &ns(internal_utf8_encoding).enc;
 }
 
-const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
+const ENCODING *
+NS(XmlGetUtf16InternalEncoding)(void)
 {
-#if XML_BYTE_ORDER == 12
+#if BYTEORDER == 1234
   return &ns(internal_little2_encoding).enc;
-#elif XML_BYTE_ORDER == 21
+#elif BYTEORDER == 4321
   return &ns(internal_big2_encoding).enc;
 #else
   const short n = 1;
-  return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
+  return (*(const char *)&n
+          ? &ns(internal_little2_encoding).enc
+          : &ns(internal_big2_encoding).enc);
 #endif
 }
 
-static
-const ENCODING *NS(encodings)[] = {
+static const ENCODING *NS(encodings)[] = {
   &ns(latin1_encoding).enc,
   &ns(ascii_encoding).enc,
   &ns(utf8_encoding).enc,
@@ -26,21 +29,25 @@
   &ns(utf8_encoding).enc /* NO_ENC */
 };
 
-static
-int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
-		       const char **nextTokPtr)
+static int PTRCALL
+NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
 {
-  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+                  XML_PROLOG_STATE, ptr, end, nextTokPtr);
 }
 
-static
-int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
-		       const char **nextTokPtr)
+static int PTRCALL
+NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
 {
-  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc,
+                  XML_CONTENT_STATE, ptr, end, nextTokPtr);
 }
 
-int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
+int
+NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
+                    const char *name)
 {
   int i = getEncodingIndex(name);
   if (i == UNKNOWN_ENC)
@@ -54,8 +61,8 @@
   return 1;
 }
 
-static
-const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+static const ENCODING *
+NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
 {
 #define ENCODING_MAX 128
   char buf[ENCODING_MAX];
@@ -73,26 +80,27 @@
   return NS(encodings)[i];
 }
 
-int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
-			const ENCODING *enc,
-			const char *ptr,
-			const char *end,
-			const char **badPtr,
-			const char **versionPtr,
-			const char **versionEndPtr,
-			const char **encodingName,
-			const ENCODING **encoding,
-			int *standalone)
+int
+NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+                    const ENCODING *enc,
+                    const char *ptr,
+                    const char *end,
+                    const char **badPtr,
+                    const char **versionPtr,
+                    const char **versionEndPtr,
+                    const char **encodingName,
+                    const ENCODING **encoding,
+                    int *standalone)
 {
   return doParseXmlDecl(NS(findEncoding),
-			isGeneralTextEntity,
-			enc,
-			ptr,
-			end,
-			badPtr,
-			versionPtr,
-			versionEndPtr,
-			encodingName,
-			encoding,
-			standalone);
+                        isGeneralTextEntity,
+                        enc,
+                        ptr,
+                        end,
+                        badPtr,
+                        versionPtr,
+                        versionEndPtr,
+                        encodingName,
+                        encoding,
+                        standalone);
 }
diff --git a/xml/expat/win32/MANIFEST.txt b/xml/expat/win32/MANIFEST.txt
new file mode 100644
index 0000000..66b780e
--- /dev/null
+++ b/xml/expat/win32/MANIFEST.txt
@@ -0,0 +1,29 @@
+                     Overview of the Expat distribution
+
+The Expat distribution creates several subdirectories on your system.
+Some of these directories contain components of interest to all Expat
+users, and some contain material of interest to developers who wish to
+use Expat in their applications.  In the list below, <top> is the
+directory you specified to the installer.
+
+    Directory           Contents
+    --------------------------------------------------------------------
+    <top>\              The XML well-formedness checker and some general
+                        information files.
+
+    <top>\Doc\          API documentation for developers.
+
+    <top>\Libs\         Pre-compiled dynamic libraries for developers.
+
+    <top>\StaticLibs\   Pre-compiled static libraries for developers.
+
+    <top>\Source\       Source code, which may interest some developers,
+                        including a workspace for Microsft Visual C++.
+                        The source code includes the parser, the well-
+                        formedness checker, and a couple of small sample
+                        applications.
+
+    <top>\Source\bcb5\  Project files for Borland C++ Builder 5 and BCC
+                        5.5.
+
+    <top>\Unistall\     The uninstaller and its data files.
diff --git a/xml/expat/win32/expat.iss b/xml/expat/win32/expat.iss
new file mode 100644
index 0000000..5bb9639
--- /dev/null
+++ b/xml/expat/win32/expat.iss
@@ -0,0 +1,62 @@
+; Basic setup script for the Inno Setep installer builder.  For more
+; information on the free installer builder, see www.jrsoftware.org.
+;
+; This script was contributed by Tim Peters.
+; The current version is used with Inno Setup 2.0.19.
+
+[Setup]
+AppName=expat
+AppId=expat
+AppVersion=1.95.7
+AppVerName=expat 1.95.7
+AppCopyright=Copyright © 1998-2003 Thai Open Source Software Center, Clark Cooper, and the Expat maintainers
+DefaultDirName={sd}\Expat-1.95.7
+AppPublisher=The Expat Developers
+AppPublisherURL=http://www.libexpat.org/
+AppSupportURL=http://www.libexpat.org/
+AppUpdatesURL=http://www.libexpat.org/
+UninstallDisplayName=Expat XML Parser (version 1.95.7)
+UninstallFilesDir={app}\Uninstall
+
+Compression=bzip/9
+SourceDir=..
+OutputDir=win32
+DisableStartupPrompt=yes
+AllowNoIcons=yes
+DisableProgramGroupPage=yes
+DisableReadyPage=yes
+
+[Files]
+CopyMode: alwaysoverwrite; Source: xmlwf\Release\*.exe;        DestDir: "{app}"
+CopyMode: alwaysoverwrite; Source: win32\MANIFEST.txt;         DestDir: "{app}"
+CopyMode: alwaysoverwrite; Source: Changes;                    DestDir: "{app}"; DestName: Changes.txt
+CopyMode: alwaysoverwrite; Source: COPYING;                    DestDir: "{app}"; DestName: COPYING.txt
+CopyMode: alwaysoverwrite; Source: README;                     DestDir: "{app}"; DestName: README.txt
+CopyMode: alwaysoverwrite; Source: doc\*.html;                 DestDir: "{app}\Doc"
+CopyMode: alwaysoverwrite; Source: doc\*.css;                  DestDir: "{app}\Doc"
+CopyMode: alwaysoverwrite; Source: doc\*.png;                  DestDir: "{app}\Doc"
+CopyMode: alwaysoverwrite; Source: lib\Release\*.dll;          DestDir: "{app}\Libs"
+CopyMode: alwaysoverwrite; Source: lib\Release\*.lib;          DestDir: "{app}\Libs"
+CopyMode: alwaysoverwrite; Source: lib\Release-w\*.dll;        DestDir: "{app}\Libs"
+CopyMode: alwaysoverwrite; Source: lib\Release-w\*.lib;        DestDir: "{app}\Libs"
+CopyMode: alwaysoverwrite; Source: lib\Release_static\*.lib;   DestDir: "{app}\StaticLibs"
+CopyMode: alwaysoverwrite; Source: lib\Release-w_static\*.lib; DestDir: "{app}\StaticLibs"
+CopyMode: alwaysoverwrite; Source: expat.dsw;                  DestDir: "{app}\Source"
+CopyMode: alwaysoverwrite; Source: win32\README.txt;           DestDir: "{app}\Source"
+CopyMode: alwaysoverwrite; Source: bcb5\*.*;                   DestDir: "{app}\Source\bcb5"
+CopyMode: alwaysoverwrite; Source: lib\*.c;                    DestDir: "{app}\Source\lib"
+CopyMode: alwaysoverwrite; Source: lib\*.h;                    DestDir: "{app}\Source\lib"
+CopyMode: alwaysoverwrite; Source: lib\*.def;                  DestDir: "{app}\Source\lib"
+CopyMode: alwaysoverwrite; Source: lib\*.dsp;                  DestDir: "{app}\Source\lib"
+CopyMode: alwaysoverwrite; Source: examples\*.c;               DestDir: "{app}\Source\examples"
+CopyMode: alwaysoverwrite; Source: examples\*.dsp;             DestDir: "{app}\Source\examples"
+CopyMode: alwaysoverwrite; Source: tests\*.c;                  DestDir: "{app}\Source\tests"
+CopyMode: alwaysoverwrite; Source: tests\*.h;                  DestDir: "{app}\Source\tests"
+CopyMode: alwaysoverwrite; Source: tests\README.txt;           DestDir: "{app}\Source\tests"
+CopyMode: alwaysoverwrite; Source: xmlwf\*.c*;                 DestDir: "{app}\Source\xmlwf"
+CopyMode: alwaysoverwrite; Source: xmlwf\*.h;                  DestDir: "{app}\Source\xmlwf"
+CopyMode: alwaysoverwrite; Source: xmlwf\*.dsp;                DestDir: "{app}\Source\xmlwf"
+
+[Messages]
+WelcomeLabel1=Welcome to the Expat XML Parser Setup Wizard
+WelcomeLabel2=This will install [name/ver] on your computer.%n%nExpat is an XML parser with a C-language API, and is primarily made available to allow developers to build applications which use XML using a portable API and fast implementation.%n%nIt is strongly recommended that you close all other applications you have running before continuing. This will help prevent any conflicts during the installation process.