diff --git a/Projects/Win32/VC6/xerces-all/SAXCount/SAXCount.dsp b/Projects/Win32/VC6/xerces-all/SAXCount/SAXCount.dsp
index dcb89e8f3a9ab6e6c6bd700380d5ae853ac39947..966cde32c36021c8bce4400c99aff5b4212fdd2f 100644
--- a/Projects/Win32/VC6/xerces-all/SAXCount/SAXCount.dsp
+++ b/Projects/Win32/VC6/xerces-all/SAXCount/SAXCount.dsp
@@ -67,7 +67,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /G6 /MDd /Za /W3 /Gm /GX /ZI /Od /I "..\..\..\..\..\src" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_WINDOWS" /D "PLATFORM_WIN32" /FD /c
+# ADD CPP /nologo /G6 /MDd /Za /W3 /Gm /GX /ZI /Od /I "..\..\..\..\..\src" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_WINDOWS" /D "PLATFORM_WIN32" /FR /FD /c
 # SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
diff --git a/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp b/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
index eb52a7d9b9723678f4e62c0f0923b302596278d2..35e47f8f797ae69877f7f3c70c396a7daa40c3e5 100644
--- a/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
+++ b/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
@@ -70,7 +70,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MDd /Za /W3 /Gm /GX /Zi /Od /I "..\..\src" /I "..\..\src\dom" /I "..\..\..\..\..\src" /D "PROJ_XMLPARSER" /D "PROJ_XMLUTIL" /D "PROJ_PARSERS" /D "PROJ_SAX4C" /D "PROJ_DOM" /D "PROJ_VALIDATORS" /D "XML_SINGLEDLL" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "XML_USE_WIN32_TRANSCODER" /D "XML_USE_WIN32_MSGLOADER" /D "XML_USE_NETACCESSOR_WINSOCK" /FD /c
+# ADD CPP /nologo /G6 /MDd /Za /W3 /Gm /GX /Zi /Od /I "..\..\src" /I "..\..\src\dom" /I "..\..\..\..\..\src" /D "_CRTDBG_MAP_ALLOC" /D "PROJ_XMLPARSER" /D "PROJ_XMLUTIL" /D "PROJ_PARSERS" /D "PROJ_SAX4C" /D "PROJ_DOM" /D "PROJ_VALIDATORS" /D "XML_SINGLEDLL" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "XML_USE_WIN32_TRANSCODER" /D "XML_USE_WIN32_MSGLOADER" /D "XML_USE_NETACCESSOR_WINSOCK" /FR /FD /c
 # SUBTRACT CPP /YX
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
@@ -139,11 +139,6 @@ SOURCE=..\..\..\..\..\src\util\Transcoders\Win32\Win32TransService.cpp
 
 SOURCE=..\..\..\..\..\src\util\Transcoders\Win32\Win32TransService.hpp
 # End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\..\src\util\Transcoders\Win32\Win32TransService2.cpp
-# ADD CPP /Ze
-# End Source File
 # End Group
 # Begin Group "NetAccessors"
 
diff --git a/samples/DOMPrint/DOMPrint.cpp b/samples/DOMPrint/DOMPrint.cpp
index eb0e597f30f4309f0951e0c994be4b9d419eea9b..c8f3b162ba9f7b039988ece8a2ad692589beb339 100644
--- a/samples/DOMPrint/DOMPrint.cpp
+++ b/samples/DOMPrint/DOMPrint.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.10  2000/05/09 00:22:27  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.9  2000/04/25 20:27:44  aruna1
  * DOM_XMLDecl type node introduced to get the information of the
  * XML Declaration in a document and store it part of the tree
@@ -136,6 +142,7 @@
 #include <parsers/DOMParser.hpp>
 #include <dom/DOM_Node.hpp>
 #include <dom/DOM_NamedNodeMap.hpp>
+#include <dom/DomMemDebug.hpp>
 #include "DOMTreeErrorReporter.hpp"
 #include <string.h>
 #include <stdlib.h>
@@ -206,6 +213,7 @@ int main(int argC, char* argV[])
     if (argC < 2)
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 1;
     }
 
@@ -213,6 +221,7 @@ int main(int argC, char* argV[])
     if (!strcmp(argV[1], "-?"))
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 2;
     }
 
@@ -251,6 +260,7 @@ int main(int argC, char* argV[])
          else
         {
             usage();
+            XMLPlatformUtils::Terminate();
             return 1;
         }
     }
@@ -262,22 +272,23 @@ int main(int argC, char* argV[])
     if (parmInd + 1 != argC)
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 1;
     }
     xmlFile = argV[parmInd];
 
     //
-    //  Create our validator, then attach an error handler to the parser.
+    //  Create our parser, then attach an error handler to the parser.
     //  The parser will call back to methods of the ErrorHandler if it
     //  discovers errors during the course of parsing the XML document.
     //
-    DOMParser parser;
-    parser.setDoValidation(doValidation);
-    parser.setDoNamespaces(doNamespaces);
+    DOMParser *parser = new DOMParser;
+    parser->setDoValidation(doValidation);
+    parser->setDoNamespaces(doNamespaces);
     ErrorHandler *errReporter = new DOMTreeErrorReporter();
-    parser.setErrorHandler(errReporter);
-	parser.setExpandEntityReferences(doExpand);
-    parser.setToCreateXMLDeclTypeNode(doCreateXMLDecl);
+    parser->setErrorHandler(errReporter);
+	parser->setExpandEntityReferences(doExpand);
+    parser->setToCreateXMLDeclTypeNode(doCreateXMLDecl);
     //
     //  Parse the XML file, catching any XML exceptions that might propogate
     //  out of it.
@@ -285,7 +296,7 @@ int main(int argC, char* argV[])
     bool errorsOccured = false;
     try
     {
-        parser.parse(xmlFile);
+        parser->parse(xmlFile);
     }
 
     catch (const XMLException& e)
@@ -298,19 +309,25 @@ int main(int argC, char* argV[])
     // If the parse was successful, output the document data from the DOM tree
     if (!errorsOccured)
     {
-        DOM_Node doc = parser.getDocument();
+        DOM_Node doc = parser->getDocument();
 		cout << doc << endl;
     }
 
     //
-    //  Clean up the element counter object. The parser does not adopt handlers
+    //  Clean up the error handler. The parser does not adopt handlers
     //  since they could be many objects or one object installed for multiple
     //  handlers.
     //
     delete errReporter;
 
+    //
+    //  Delete the parser itself.  Must be done prior to calling Terminate, below.
+    //
+    delete parser;
+
     // And call the termination method
     XMLPlatformUtils::Terminate();
+    // DomMemDebug().print();
 
     //
 	//  The DOM document and its contents are reference counted, and need
diff --git a/samples/SAXCount/SAXCount.cpp b/samples/SAXCount/SAXCount.cpp
index ce2e360d3388536b1d37d5b702c3096f2b5891ed..105068ca65341d7c51e17af2835c19084896759e 100644
--- a/samples/SAXCount/SAXCount.cpp
+++ b/samples/SAXCount/SAXCount.cpp
@@ -1,85 +1,91 @@
 /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- *    if any, must include the following acknowledgment:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgment may appear in the software itself,
- *    if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- *    not be used to endorse or promote products derived from this
- *    software without prior written permission. For written
- *    permission, please contact apache\@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- *    nor may "Apache" appear in their name, without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com .  For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in
+*    the documentation and/or other materials provided with the
+*    distribution.
+*
+* 3. The end-user documentation included with the redistribution,
+*    if any, must include the following acknowledgment:
+*       "This product includes software developed by the
+*        Apache Software Foundation (http://www.apache.org/)."
+*    Alternately, this acknowledgment may appear in the software itself,
+*    if and wherever such third-party acknowledgments normally appear.
+*
+* 4. The names "Xerces" and "Apache Software Foundation" must
+*    not be used to endorse or promote products derived from this
+*    software without prior written permission. For written
+*    permission, please contact apache\@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache",
+*    nor may "Apache" appear in their name, without prior written
+*    permission of the Apache Software Foundation.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation, and was
+* originally based on software copyright (c) 1999, International
+* Business Machines, Inc., http://www.ibm.com .  For more information
+* on the Apache Software Foundation, please see
+* <http://www.apache.org/>.
+*/
 
 /*
- * $Log$
- * Revision 1.5  2000/03/03 01:29:31  roddey
- * Added a scanReset()/parseReset() method to the scanner and
- * parsers, to allow for reset after early exit from a progressive parse.
- * Added calls to new Terminate() call to all of the samples. Improved
- * documentation in SAX and DOM parsers.
- *
- * Revision 1.4  2000/03/02 19:53:47  roddey
- * This checkin includes many changes done while waiting for the
- * 1.1.0 code to be finished. I can't list them all here, but a list is
- * available elsewhere.
- *
- * Revision 1.3  2000/02/11 02:39:10  abagchi
- * Removed StrX::transcode
- *
- * Revision 1.2  2000/02/06 07:47:23  rahulj
- * Year 2K copyright swat.
- *
- * Revision 1.1.1.1  1999/11/09 01:09:30  twl
- * Initial checkin
- *
- * Revision 1.7  1999/11/08 20:43:40  rahul
- * Swat for adding in Product name and CVS comment log variable.
- *
- */
+* $Log$
+* Revision 1.6  2000/05/09 00:22:29  andyh
+* Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+* allocated memory; memory leak checking tools will no longer report
+* that leaks exist.  (DOM GetElementsByTagID temporarily removed
+* as part of this.)
+*
+* Revision 1.5  2000/03/03 01:29:31  roddey
+* Added a scanReset()/parseReset() method to the scanner and
+* parsers, to allow for reset after early exit from a progressive parse.
+* Added calls to new Terminate() call to all of the samples. Improved
+* documentation in SAX and DOM parsers.
+*
+* Revision 1.4  2000/03/02 19:53:47  roddey
+* This checkin includes many changes done while waiting for the
+* 1.1.0 code to be finished. I can't list them all here, but a list is
+* available elsewhere.
+*
+* Revision 1.3  2000/02/11 02:39:10  abagchi
+* Removed StrX::transcode
+*
+* Revision 1.2  2000/02/06 07:47:23  rahulj
+* Year 2K copyright swat.
+*
+* Revision 1.1.1.1  1999/11/09 01:09:30  twl
+* Initial checkin
+*
+* Revision 1.7  1999/11/08 20:43:40  rahul
+* Swat for adding in Product name and CVS comment log variable.
+*
+*/
 
 
 // ---------------------------------------------------------------------------
@@ -94,12 +100,12 @@
 void usage()
 {
     cout << "\nUsage:\n"
-         << "    SAXCount [-v -n] <XML file>\n\n"
-         << "    -v  Do a validating parse. Defaults to non-validating.\n"
-         << "    -n  Enable namespace processing. Defaults to off.\n\n"
-         << "This program prints the number of elements, attributes,\n"
-         << "white spaces and other non-white space characters in the "
-         << "input file.\n" << endl;
+        << "    SAXCount [-v -n] <XML file>\n\n"
+        << "    -v  Do a validating parse. Defaults to non-validating.\n"
+        << "    -n  Enable namespace processing. Defaults to off.\n\n"
+        << "This program prints the number of elements, attributes,\n"
+        << "white spaces and other non-white space characters in the "
+        << "input file.\n" << endl;
 }
 
 
@@ -111,58 +117,60 @@ int main(int argC, char* argV[])
     // Initialize the XML4C2 system
     try
     {
-         XMLPlatformUtils::Initialize();
+        XMLPlatformUtils::Initialize();
     }
-
+    
     catch (const XMLException& toCatch)
     {
-         cerr << "Error during initialization! Message:\n"
-              << StrX(toCatch.getMessage()) << endl;
-         return 1;
+        cerr << "Error during initialization! Message:\n"
+            << StrX(toCatch.getMessage()) << endl;
+        return 1;
     }
-
+    
     // Check command line and extract arguments.
     if (argC < 2)
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 1;
     }
-
+    
     const char* xmlFile;
     bool        doValidation    = false;
     bool        doNamespaces    = false;
-
+    
     // See if non validating dom parser configuration is requested.
     if ((argC == 2) && !strcmp(argV[1], "-?"))
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 2;
     }
-
+    
     int argInd;
     for (argInd = 1; argInd < argC; argInd++)
     {
         // Break out on first non-dash parameter
         if (argV[argInd][0] != '-')
             break;
-
+        
         if (!strcmp(argV[argInd], "-v")
-        ||  !strcmp(argV[argInd], "-V"))
+            ||  !strcmp(argV[argInd], "-V"))
         {
             doValidation = true;
         }
-         else if (!strcmp(argV[argInd], "-n")
-              ||  !strcmp(argV[argInd], "-N"))
+        else if (!strcmp(argV[argInd], "-n")
+            ||  !strcmp(argV[argInd], "-N"))
         {
             doNamespaces = true;
         }
-         else
+        else
         {
             cerr << "Unknown option '" << argV[argInd]
-                 << "', ignoring it\n" << endl;
+                << "', ignoring it\n" << endl;
         }
     }
-
+    
     //
     //  There should be only one and only one parameter left, and that
     //  should be the file name.
@@ -170,18 +178,20 @@ int main(int argC, char* argV[])
     if (argInd != argC - 1)
     {
         usage();
+        XMLPlatformUtils::Terminate();
         return 1;
     }
     xmlFile = argV[argInd];
-
+    
     //
     //  Create a SAX parser object. Then, according to what we were told on
     //  the command line, set it to validate or not.
     //
     SAXParser parser;
+
     parser.setDoValidation(doValidation);
     parser.setDoNamespaces(doNamespaces);
-
+    
     //
     //  Create our SAX handler object and install it on the parser, as the
     //  document and error handler.
@@ -189,8 +199,9 @@ int main(int argC, char* argV[])
     SAXCountHandlers handler;
     parser.setDocumentHandler(&handler);
     parser.setErrorHandler(&handler);
+    
 
-    //
+   //
     //  Get the starting time and kick off the parse of the indicated
     //  file. Catch any exceptions that might propogate out of it.
     //
@@ -202,28 +213,37 @@ int main(int argC, char* argV[])
         const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
         duration = endMillis - startMillis;
     }
-
+    
     catch (const XMLException& e)
     {
         cerr << "\nError during parsing: '" << xmlFile << "'\n"
-             << "Exception message is:  \n"
-             << StrX(e.getMessage()) << "\n" << endl;
+            << "Exception message is:  \n"
+            << StrX(e.getMessage()) << "\n" << endl;
+        XMLPlatformUtils::Terminate();
         return -1;
     }
 
+    catch (...)
+    {
+        cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
+        XMLPlatformUtils::Terminate();
+        return -1;
+    }
+
+    
     // Print out the stats that we collected and time taken
     if (!handler.getSawErrors())
     {
         cout << xmlFile << ": " << duration << " ms ("
-             << handler.getElementCount() << " elems, "
-             << handler.getAttrCount() << " attrs, "
-             << handler.getSpaceCount() << " spaces, "
-             << handler.getCharacterCount() << " chars)" << endl;
+            << handler.getElementCount() << " elems, "
+            << handler.getAttrCount() << " attrs, "
+            << handler.getSpaceCount() << " spaces, "
+            << handler.getCharacterCount() << " chars)" << endl;
     }
-
+    
     // And call the termination method
     XMLPlatformUtils::Terminate();
-
+    
     return 0;
 }
 
diff --git a/src/dom/DOMString.cpp b/src/dom/DOMString.cpp
index 6ae2cf4f0bee9ef26412a2ecafe5e476b70ba4ca..fcbce52fe79775bb8b5c624a5971471237bb75e4 100644
--- a/src/dom/DOMString.cpp
+++ b/src/dom/DOMString.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.16  2000/05/09 00:22:29  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.15  2000/03/28 19:43:13  roddey
  * Fixes for signed/unsigned warnings. New work for two way transcoding
  * stuff.
@@ -142,6 +148,12 @@
 #include <string.h>
 
  
+//----------------------------------------------
+//
+//  Forward decls
+//
+//----------------------------------------------
+static void DOMStringTerminate();
 
 //----------------------------------------------
 //
@@ -221,15 +233,18 @@ static const int allocGroupSize = 1024;   // Number of string handles to allocat
                                           //  as a chunk from the system's
                                           //  memory allocator.
 
+DOMStringHandle *DOMStringHandle::blockListPtr = 0;  // Point to the head of the list
+                                          //  of larger blocks in which DOMStringHandles
+                                          //  are allocated.
 
 //
 //  There is one global mutex that is used to synchronize access to the
 //     allocator free list for DOMStringHandles.  This function gets that
 //     mutex, and will create it on the first attempt to get it.
 //
+static XMLMutex* DOMStringHandleMutex = 0;   // Mutex will be deleted by ~DOMStringHandle.
 XMLMutex& DOMStringHandle::getMutex()
 {
-    static XMLMutex* DOMStringHandleMutex = 0;
     if (!DOMStringHandleMutex)
     {
         XMLMutex* tmpMutex = new XMLMutex;
@@ -239,6 +254,7 @@ XMLMutex& DOMStringHandle::getMutex()
             delete tmpMutex;
         }
     }
+    
     return *DOMStringHandleMutex;
 }
 
@@ -260,12 +276,20 @@ void *DOMStringHandle::operator new(size_t sizeToAlloc)
         // Allocate a new batch of them, using the system's 
         // operator new to get a chunk of memory.
         //
-        // Link all of these new StringHandles into our free list
-        //
-        DOMStringHandle *dsg = 
+       DOMStringHandle *dsg = 
             ::new DOMStringHandle[allocGroupSize];
-        int   i;
-        for (i=0; i<allocGroupSize-1; i++) {
+
+        // Link the block itself into the list of blocks.  The purpose of this is to
+        //   let us locate and delete the blocks when shutting down.
+        //
+        *(DOMStringHandle **)dsg = blockListPtr;
+        blockListPtr = dsg;
+
+
+        // Link all of the new storage for StringHandles into the StringHandle free list
+        int   i;    //   Start with index 1;  index 0 is reserved for linking the 
+                    //   larger allocation blocks together.
+        for (i=1; i<allocGroupSize-1; i++) {
             *(void **)&dsg[i] = freeListPtr;
             freeListPtr = &dsg[i];
         }
@@ -284,12 +308,34 @@ void *DOMStringHandle::operator new(size_t sizeToAlloc)
 //
 void DOMStringHandle::operator delete(void *pMem)
 {
-    XMLMutexLock   lock(&getMutex());    // Lock the DOMStringHandle mutex for the
-                                         //    duration of this function.
-   *(void **)pMem = freeListPtr;
-    freeListPtr = pMem;
-};
+    {
+        XMLMutexLock   lock(&getMutex());    // Lock the DOMStringHandle mutex for the
+        //    duration of this function.
+        *(void **)pMem = freeListPtr;
+        freeListPtr = pMem;
+    }
+    
+    // If ALL of the string handles are gone, delete the storage blocks used for the
+    //   handles as well.  This will generally only happen on PlatFormUtils::Terminate(),
+    //   since any use of the DOM will cache some commonly used DOMStrings
+    //   forever (until Terminate).
+    if (DOMString::gLiveStringHandleCount == 0)
+    {
+        DOMStringHandle *pThisBlock, *pNextBlock;
+        for (pThisBlock = blockListPtr; pThisBlock != 0; pThisBlock = pNextBlock)
+        {
+            pNextBlock = *(DOMStringHandle **)pThisBlock;
+            delete [] pThisBlock;
+        }
+        blockListPtr = 0;
+        freeListPtr  = 0;
+
+        DOMStringTerminate();            //  Clean up everything else related to DOMString.
+    }
     
+    
+};
+
 
 void DOMStringHandle::addRef()
 {
@@ -303,8 +349,8 @@ void DOMStringHandle::removeRef()
     if (result==0)
     {
         fDSData->removeRef();
-        delete this;
         XMLPlatformUtils::atomicDecrement(DOMString::gLiveStringHandleCount);
+        delete this;
     };
 };
 
@@ -410,9 +456,9 @@ DOMString::DOMString(const XMLCh *data, unsigned int dataLength)
 //          codepage to Unicode that is to be used when
 //          a DOMString is constructed from a char *.
 //
+static XMLLCPTranscoder* gDomConverter = 0;
 XMLLCPTranscoder*  getDomConverter()
 {
-    static XMLLCPTranscoder* gDomConverter = 0;
     if (!gDomConverter) 
     {
         XMLLCPTranscoder* transcoder =
@@ -423,7 +469,7 @@ XMLLCPTranscoder*  getDomConverter()
 
         if (XMLPlatformUtils::compareAndSwap((void **)&gDomConverter,
         transcoder, 0) != 0)
-            delete gDomConverter;
+            delete transcoder;
     }
     return gDomConverter;
 };
@@ -1127,3 +1173,18 @@ DOMString operator + (XMLCh lhs, const DOMString& rhs)
 
 
 
+static void DOMStringTerminate()        // Termination function cleans up all lazily created
+{                                       //   resources used by the DOMString implementation.
+                                        //   Called when no DOMStrings remain in the app.  (We
+                                        //   know this from reference counting.)
+
+        delete DOMStringHandleMutex;    //  Delete the synchronization mutex,
+        DOMStringHandleMutex = 0;       
+
+        delete gDomConverter;           //  Delete the local code page converter.
+        gDomConverter = 0;
+};
+
+
+
+
diff --git a/src/dom/DOMStringImpl.hpp b/src/dom/DOMStringImpl.hpp
index 5323a1112af9721f936388fd4cdb21407fa6a3ba..e351445c8f87426ee9734652cdde9e045996245b 100644
--- a/src/dom/DOMStringImpl.hpp
+++ b/src/dom/DOMStringImpl.hpp
@@ -59,6 +59,12 @@
 
 /*
  * $Log$
+ * Revision 1.8  2000/05/09 00:22:30  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.7  2000/03/02 19:53:52  roddey
  * This checkin includes many changes done while waiting for the
  * 1.1.0 code to be finished. I can't list them all here, but a list is
@@ -118,20 +124,29 @@ public:
 class  DOMStringHandle
 {
 public:
-            unsigned int     fLength;
-            int              fRefCount;
-            DOMStringData    *fDSData;
+            unsigned int     fLength;              // The logical length of the DOMString.
+                                                   //  This may be shorter than the buffer length.
+            int              fRefCount;            // The number of DOMString objects pointing to
+                                                   //  this string handle.
+            DOMStringData    *fDSData;             // Pointer to the string buffer. May be null.
+
+    void    *operator new( size_t sizeToAlloc);    // StringHandles have custom, optimized
+    void    operator delete( void *pvMem );        //   memory allocation.
+
 
-    void    *operator new( size_t sizeToAlloc);
-    void    operator delete( void *pvMem );
 private:
-    static  void *freeListPtr;
+    static  void             *freeListPtr;         // Head of the linked list of unallocated String Handles
+
+    static  DOMStringHandle  *blockListPtr;        // Head of the linked list of memory blocks from which
+                                                   //  string handles are sub-allocated.
+
 public:
     static  DOMStringHandle  *createNewStringHandle(unsigned int bufLength);
             DOMStringHandle  *cloneStringHandle();
     inline  void             addRef();
     inline  void             removeRef();
                              ~DOMStringHandle() {};
+    static  void             DOMStringCleanup();
 private:
     inline                   DOMStringHandle() {};
     static inline  XMLMutex &getMutex();
diff --git a/src/dom/DOM_DOMImplementation.cpp b/src/dom/DOM_DOMImplementation.cpp
index f81652911d0775bcd142f0e97911c9611a5e8ad1..66dedf27e28c3e0fb6b7be0bbb0b2d7e0a7f7200 100644
--- a/src/dom/DOM_DOMImplementation.cpp
+++ b/src/dom/DOM_DOMImplementation.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.9  2000/05/09 00:22:31  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.8  2000/04/27 02:52:42  lehors
  * global reorganization similar to what I've done in Java,
  * nodes now are much smaller.
@@ -115,7 +121,8 @@
 #include "DocumentImpl.hpp"
 #include "DocumentTypeImpl.hpp"
 #include "DStringPool.hpp"
-#include "util/PlatformUtils.hpp"
+#include <util/XMLDeleterFor.hpp>
+#include <util/PlatformUtils.hpp>
 
 //
 //  Static constants.  These are lazily initialized on first usage.
@@ -174,7 +181,18 @@ DOM_DOMImplementation &DOM_DOMImplementation::getImplementation() {
     {
         DOM_DOMImplementation *t = new DOM_DOMImplementation;
         if (XMLPlatformUtils::compareAndSwap((void **)&gDomimp, t, 0) != 0)
+        {
             delete t;
+        }
+        else
+        {
+            
+            XMLPlatformUtils::registerLazyData
+                (
+                new XMLDeleterFor<DOM_DOMImplementation>(gDomimp)
+                );
+        }
+        
     }
     return *gDomimp;
 };
diff --git a/src/dom/DOM_Document.cpp b/src/dom/DOM_Document.cpp
index bfcadcedb61d28d62d6a6233b6ac8b941b1e4beb..a391da1972ade439f758ceec1553990d0abb8e64 100644
--- a/src/dom/DOM_Document.cpp
+++ b/src/dom/DOM_Document.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.9  2000/05/09 00:22:31  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.8  2000/04/25 20:29:33  aruna1
  * DOM_XMLDecl type node introduced to get the information of the
  * XML Declaration in a document and store it part of the tree
@@ -271,12 +277,6 @@ DOM_Element         DOM_Document::getElementById(const DOMString &elementId)
         return DOM_Element(((DocumentImpl *)fImpl)->getElementById(elementId));
 }
 
-// Non-standard accessory function
-
-void DOM_Document::putIdentifier(const DOMString &elementId, const DOM_Element &ele)
-{
-       ((DocumentImpl*)fImpl)->putIdentifier(elementId,ele);
-}
 
 DOM_XMLDecl DOM_Document::createXMLDecl(const DOMString& version, const DOMString& encoding, const DOMString& standalone)
 {
diff --git a/src/dom/DStringPool.cpp b/src/dom/DStringPool.cpp
index 0283616112b21a1448094b8598c8dcc980794ca7..833302ba558584109024dcadd5d3eae19f295300 100644
--- a/src/dom/DStringPool.cpp
+++ b/src/dom/DStringPool.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.4  2000/05/09 00:22:31  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.3  2000/03/02 19:53:58  roddey
  * This checkin includes many changes done while waiting for the
  * 1.1.0 code to be finished. I can't list them all here, but a list is
@@ -77,6 +83,7 @@
 //
 
 #include "DStringPool.hpp"
+#include <util/XMLDeleterFor.hpp>
 #include <util/XMLString.hpp>
 #include <util/PlatformUtils.hpp>
 
@@ -190,6 +197,16 @@ const DOMString &DStringPool::getStaticString(const char *in, DOMString **loc)
                                             //   pass them around by value.
         if (XMLPlatformUtils::compareAndSwap((void **)loc, t, 0) != 0)
             delete t;
+        else
+        {
+            // Register this string for deletion.  Doing each string individually
+            //   may be a little heavyweight, but will work for the time being
+            //   for arranging the deletion of eveything on Termination of XML.
+            XMLPlatformUtils::registerLazyData
+                (
+                new XMLDeleterFor<DOMString>(*loc)
+                );
+        }
     }
     return **loc;
 }
diff --git a/src/dom/DocumentImpl.cpp b/src/dom/DocumentImpl.cpp
index 2d065d3c7dcb7fddf159cc90ae57266848363037..f0e5047c40d6670111cf1fb6d3d6ebbd74dfb7b5 100644
--- a/src/dom/DocumentImpl.cpp
+++ b/src/dom/DocumentImpl.cpp
@@ -88,29 +88,6 @@
 #include "NodeIteratorImpl.hpp"
 #include "DOM_Document.hpp"
 
-// ---------------------------------------------------------------------------
-//  StringPool::PoolElem: Constructors and Destructor
-// ---------------------------------------------------------------------------
-DocumentImpl::PoolElem::PoolElem( const DOMString string
-                                  , const DOM_Element &elem) :
-    fElem((DOM_Element&)elem)
-    , fString(string)
-{
-}
-
-DocumentImpl::PoolElem::~PoolElem()
-{
-}
-
-// ---------------------------------------------------------------------------
-//  DocumentImpl::PoolElem: Public methods
-// ---------------------------------------------------------------------------
-const XMLCh* DocumentImpl::PoolElem::getKey() const
-{
-    return fString.rawBuffer();
-}
-
-
 
 DocumentImpl::DocumentImpl()
     : ParentNode(this)
@@ -118,7 +95,6 @@ DocumentImpl::DocumentImpl()
     docType=null;
     docElement=null;
     namePool = new DStringPool(257);
-    identifiers = new RefHashTableOf<PoolElem>(109);
     iterators = 0L;
     treeWalkers = 0L;
 };
@@ -137,7 +113,6 @@ DocumentImpl::DocumentImpl(const DOMString &fNamespaceURI,
     docElement=null;
     appendChild(createElementNS(fNamespaceURI, qualifiedName));  //root element
     namePool = new DStringPool(257);
-	identifiers = new RefHashTableOf<PoolElem>(109);
     iterators = 0L;
     treeWalkers = 0L;
 }
@@ -178,9 +153,6 @@ DocumentImpl::~DocumentImpl()
         delete treeWalkers;
     }
     
-    if (identifiers != 0L) {
-	    delete identifiers;
-    }
 
     delete namePool;
     // Do not delete docType and docElement pointers here.
@@ -679,21 +651,9 @@ DeepNodeListImpl *DocumentImpl::getElementsByTagNameNS(const DOMString &fNamespa
 
 ElementImpl *DocumentImpl::getElementById(const DOMString &elementId)
 {
-	PoolElem *elem = identifiers->get(elementId.rawBuffer());
-	if (elem)
-	{
-		return (ElementImpl*)elem->fElem.fImpl;
-	}
-
 	return null;
 }
 
-// Non-standard accessory functions */
-
-void DocumentImpl::putIdentifier(const DOMString &elementId, const DOM_Element &ele)
-{
-	identifiers->put(new PoolElem(elementId, ele));
-}
 
 //Return the index > 0 of ':' in the given qualified name qName="prefix:localName".
 //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
diff --git a/src/dom/DocumentImpl.hpp b/src/dom/DocumentImpl.hpp
index e9638ae1949bc098195987ee8f1c577139a6eff9..816a8dd60e77772cccdcc67bbbfd0be1ce90693a 100644
--- a/src/dom/DocumentImpl.hpp
+++ b/src/dom/DocumentImpl.hpp
@@ -108,17 +108,6 @@ private:
     // -----------------------------------------------------------------------
     //  Private data types
     // -----------------------------------------------------------------------
-    class PoolElem
-    {
-        public :
-            PoolElem(const DOMString string, const DOM_Element &elem);
-            ~PoolElem();
-
-            const XMLCh* getKey() const;
-
-            DOM_Element		 fElem;
-            DOMString        fString;
-    };
 
    	void setDocumentType(DocumentTypeImpl *doctype);
 
@@ -126,7 +115,6 @@ private:
     ElementImpl                 *docElement;
     DStringPool                 *namePool;
 
-    RefHashTableOf<PoolElem>	*identifiers;
     NodeIterators               *iterators;
     TreeWalkers                 *treeWalkers;
     friend class NodeIteratorImpl;
@@ -183,9 +171,6 @@ public:
 	const DOMString &localName);
     virtual ElementImpl         *getElementById(const DOMString &elementId);
 
-	// Non-standard accessory functions
-    virtual void		         putIdentifier(const DOMString &elementId, const DOM_Element &ele);
-
     //Return the index > 0 of ':' in the given qualified name qName="prefix:localName".
     //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
     static  int                 indexofQualifiedName(const DOMString & qName);
diff --git a/src/internal/XMLScanner.cpp b/src/internal/XMLScanner.cpp
index 1a05c4e3d915acf88daeb8af9b82a296e9e49a97..2aeda5057bfee9db214233375e38d79a8d70edc0 100644
--- a/src/internal/XMLScanner.cpp
+++ b/src/internal/XMLScanner.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.17  2000/05/09 00:22:36  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.16  2000/05/05 01:44:29  rahulj
  * Fixed defect in progressive parsing 'parseNext()' reported by Tim
  * Johnston <tim@gntsoftware.com>. Fix provided by Dean Roddey.
@@ -291,10 +297,16 @@ void XMLScanner::scanDocument(  const   XMLCh* const    systemId
         //  it has to be fully qualified. If not, then assume we are just
         //  mistaking a file for a URL.
         //
+
         XMLURL tmpURL(systemId);
-        if (tmpURL.isRelative())
-            ThrowXML(MalformedURLException, XMLExcepts::URL_NoProtocolPresent);
-        srcToUse = new URLInputSource(tmpURL);
+        if (tmpURL.isRelative()) {
+            srcToUse = new LocalFileInputSource(systemId);
+        }
+        else
+        {
+            srcToUse = new URLInputSource(tmpURL);
+        }
+        
     }
 
     catch(const MalformedURLException&)
diff --git a/src/parsers/DOMParser.cpp b/src/parsers/DOMParser.cpp
index d7eb072041d468232dcc26a3fca875854d24bcfa..6e907b77f8cfa6f819906609334042cead9f3de7 100644
--- a/src/parsers/DOMParser.cpp
+++ b/src/parsers/DOMParser.cpp
@@ -601,7 +601,7 @@ void DOMParser::startElement(const  XMLElementDecl&         elemDecl
             // Register identifiers
             if (oneAttrib->getType()==XMLAttDef::ID)
             {
-               fDocument.putIdentifier(oneAttrib->getValue(), elem);
+                // When we record ID attributes, here is the place to do it.
             }
             attr->setSpecified(oneAttrib->getSpecified());
         }
@@ -609,14 +609,14 @@ void DOMParser::startElement(const  XMLElementDecl&         elemDecl
         elem = fDocument.createElement(elemDecl.getFullName());
         ElementImpl *elemImpl = (ElementImpl *) elem.fImpl;
         for (unsigned int index = 0; index < attrCount; ++index) {
-           const XMLAttr* oneAttrib = attrList.elementAt(index);
-           AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
-           // Register identifiers
-           if (oneAttrib->getType()==XMLAttDef::ID)
-           {
-              fDocument.putIdentifier(oneAttrib->getValue(), elem);
-	   }
-           attr->setSpecified(oneAttrib->getSpecified());
+            const XMLAttr* oneAttrib = attrList.elementAt(index);
+            AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
+            // Register identifiers
+            if (oneAttrib->getType()==XMLAttDef::ID)
+            {
+                // When we record ID attributes, here is the place to do it.
+            }
+            attr->setSpecified(oneAttrib->getSpecified());
         }
     }
     
@@ -850,7 +850,8 @@ void DOMParser::doctypeDecl
 	dt = fDocument.getImplementation().createDocumentType(elemDecl.getFullName(), publicId, systemId);
     fDocumentType = (DocumentTypeImpl*)dt.fImpl;
 	((DocumentImpl*)fDocument.fImpl)->setDocumentType(fDocumentType);
-	populateDocumentType();
+
+	populateDocumentType();                  //  Add the entities and notations to this DocType.
 	
 }
 
diff --git a/src/util/PlatformUtils.cpp b/src/util/PlatformUtils.cpp
index e4d7ada383bf31bc2b45c1ea5dfbfb32319881f9..d26c6c5d39a4b92c7c4153e541fce26fc3fdfee3 100644
--- a/src/util/PlatformUtils.cpp
+++ b/src/util/PlatformUtils.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.8  2000/05/09 00:22:40  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.7  2000/03/24 19:50:29  roddey
  * Clear the 'initialized' flag when the termination call is made. Probably
  * not required technically, but...
@@ -110,7 +116,7 @@
 //      the static data of the platform utilities class and here locally.
 // ---------------------------------------------------------------------------
 static XMLMutex*                gSyncMutex = 0;
-static RefVectorOf<XMLDeleter>  gLazyData(512);
+static RefVectorOf<XMLDeleter>* gLazyData;
 static bool                     gInitFlag = false;
 
 
@@ -140,6 +146,9 @@ void XMLPlatformUtils::Initialize()
     // Create the local sync mutex
     gSyncMutex = new XMLMutex;
 
+    // Create the array for saving lazily allocated objects to be deleted at termination
+    gLazyData= new RefVectorOf<XMLDeleter>(512);
+
     //
     //  Call the platform init method, which is implemented in each of the
     //  per-platform implementation cpp files. This one does the very low
@@ -247,7 +256,7 @@ void XMLPlatformUtils::registerLazyData(XMLDeleter* const deleter)
 {
     // Just add a copy of this object to the vector. MUST be synchronized
     XMLMutexLock lock(gSyncMutex);
-    gLazyData.addElement(deleter);
+    gLazyData->addElement(deleter);
 }
 
 
@@ -262,11 +271,11 @@ void XMLPlatformUtils::cleanupLazyData()
     //  Also, note that we don't synchronize here because this is happening
     //  during shutdown.
     //
-    while (gLazyData.size())
+    while (gLazyData->size())
     {
         try
         {
-            gLazyData.removeLastElement();
+            gLazyData->removeLastElement();
         }
 
         catch(...)
@@ -274,4 +283,6 @@ void XMLPlatformUtils::cleanupLazyData()
             // We don't try to report errors here, just fall through
         }
     }
+    delete gLazyData;
+    gLazyData = 0;
 }
diff --git a/src/util/Platforms/Win32/Win32PlatformUtils.cpp b/src/util/Platforms/Win32/Win32PlatformUtils.cpp
index 6d9777db6d1fb8c395fb2d1644a9fd529e432828..d067fefcf4a9610f58271909977dcf9472eeb2f5 100644
--- a/src/util/Platforms/Win32/Win32PlatformUtils.cpp
+++ b/src/util/Platforms/Win32/Win32PlatformUtils.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.21  2000/05/09 00:22:41  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.20  2000/04/18 23:26:01  andyh
  * Fix problem on NT with conflict between Korean Won Sign (0x20A9)
  * and backslash in file path names.
@@ -156,6 +162,10 @@
 #include <util/XMLUni.hpp>
 #include <windows.h>
 
+#ifdef _DEBUG
+#include <crtdbg.h>
+#endif
+
 //
 //  These control which transcoding service is used by the Win32 version.
 //  They allow this to be controlled from the build process by just defining
@@ -803,6 +813,24 @@ XMLTransService* XMLPlatformUtils::makeTransService()
 //
 void XMLPlatformUtils::platformInit()
 {
+
+#if 1 && _DEBUG
+    //  Enable this code for memeory leak testing
+    
+   // Send all reports to STDOUT
+   _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
+   _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
+   _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
+   _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
+   _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
+   _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
+
+    int tmpDbgFlag;
+    tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+    tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
+    _CrtSetDbgFlag(tmpDbgFlag);
+#endif
+
     // Figure out if we are on NT and save that flag for later use
     OSVERSIONINFO   OSVer;
     OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
diff --git a/src/util/Transcoders/Win32/Win32TransService.cpp b/src/util/Transcoders/Win32/Win32TransService.cpp
index a3762c466335e555e29f1ea0de44e1035909e9cc..fecc3da41894810897bf7d09d193c3826f107261 100644
--- a/src/util/Transcoders/Win32/Win32TransService.cpp
+++ b/src/util/Transcoders/Win32/Win32TransService.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.13  2000/05/09 00:22:44  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.12  2000/03/20 19:13:04  roddey
  * Fixed a compilation bug in one of the exception throwing calls.
  *
@@ -111,14 +117,17 @@
 // ---------------------------------------------------------------------------
 //  Includes
 // ---------------------------------------------------------------------------
+#include <util/PlatformUtils.hpp>
 #include <util/TranscodingException.hpp>
 #include <util/XMLException.hpp>
 #include <util/XMLString.hpp>
 #include <util/XMLUni.hpp>
+#include <util/RefHashTableOf.hpp>
 #include "Win32TransService.hpp"
 #include <windows.h>
 
 
+
 // ---------------------------------------------------------------------------
 //  Local, const data
 // ---------------------------------------------------------------------------
@@ -129,17 +138,365 @@ static const XMLCh gMyServiceId[] =
 
 
 
+
+
+
+// ---------------------------------------------------------------------------
+//  This is the simple CPMapEntry class. It just contains an encoding name
+//  and a code page for that encoding.
+// ---------------------------------------------------------------------------
+class CPMapEntry
+{
+public :
+    // -----------------------------------------------------------------------
+    //  Constructors and Destructor
+    // -----------------------------------------------------------------------
+    CPMapEntry
+    (
+        const   XMLCh* const    encodingName
+        , const unsigned int    cpId
+        , const unsigned int    ieId
+    );
+
+    CPMapEntry
+    (
+        const   char* const     encodingName
+        , const unsigned int    cpId
+        , const unsigned int    ieId
+    );
+
+    ~CPMapEntry();
+
+
+    // -----------------------------------------------------------------------
+    //  Getter methods
+    // -----------------------------------------------------------------------
+    const XMLCh* getEncodingName() const;
+    const XMLCh* getKey() const;
+    unsigned int getWinCP() const;
+    unsigned int getIEEncoding() const;
+
+
+private :
+    // -----------------------------------------------------------------------
+    //  Unimplemented constructors and operators
+    // -----------------------------------------------------------------------
+    CPMapEntry();
+    CPMapEntry(const CPMapEntry&);
+    void operator=(const CPMapEntry&);
+
+
+    // -----------------------------------------------------------------------
+    //  Private data members
+    //
+    //  fEncodingName
+    //      This is the encoding name for the code page that this instance
+    //      represents.
+    //
+    //  fCPId
+    //      This is the Windows specific code page for the encoding that this
+    //      instance represents.
+    //
+    //  fIEId
+    //      This is the IE encoding id. Its not used at this time, but we
+    //      go ahead and get it and store it just in case for later.
+    // -----------------------------------------------------------------------
+    XMLCh*          fEncodingName;
+    unsigned int    fCPId;
+    unsigned int    fIEId;
+};
+
+// ---------------------------------------------------------------------------
+//  CPMapEntry: Constructors and Destructor
+// ---------------------------------------------------------------------------
+CPMapEntry::CPMapEntry( const   char* const     encodingName
+                        , const unsigned int    cpId
+                        , const unsigned int    ieId) :
+    fEncodingName(0)
+    , fCPId(cpId)
+    , fIEId(ieId)
+{
+    // Transcode the name to Unicode and store that copy
+    const unsigned int srcLen = strlen(encodingName);
+    const unsigned int targetLen = ::mbstowcs(0, encodingName, srcLen);
+    fEncodingName = new XMLCh[targetLen + 1];
+    ::mbstowcs(fEncodingName, encodingName, srcLen);
+    fEncodingName[targetLen] = 0;
+
+    //
+    //  Upper case it because we are using a hash table and need to be
+    //  sure that we find all case combinations.
+    //
+    ::wcsupr(fEncodingName);
+}
+
+CPMapEntry::CPMapEntry( const   XMLCh* const    encodingName
+                        , const unsigned int    cpId
+                        , const unsigned int    ieId) :
+
+    fEncodingName(0)
+    , fCPId(cpId)
+    , fIEId(ieId)
+{
+    fEncodingName = XMLString::replicate(encodingName);
+
+    //
+    //  Upper case it because we are using a hash table and need to be
+    //  sure that we find all case combinations.
+    //
+    ::wcsupr(fEncodingName);
+}
+
+CPMapEntry::~CPMapEntry()
+{
+    delete [] fEncodingName;
+}
+
+
+// ---------------------------------------------------------------------------
+//  CPMapEntry: Getter methods
+// ---------------------------------------------------------------------------
+const XMLCh* CPMapEntry::getEncodingName() const
+{
+    return fEncodingName;
+}
+
+const XMLCh* CPMapEntry::getKey() const
+{
+    return fEncodingName;
+}
+
+unsigned int CPMapEntry::getWinCP() const
+{
+    return fCPId;
+}
+
+unsigned int CPMapEntry::getIEEncoding() const
+{
+    return fIEId;
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+//
+//  class Win32TransService Implementation ...
+//
+//---------------------------------------------------------------------------
+
+
 // ---------------------------------------------------------------------------
 //  Win32TransService: Constructors and Destructor
 // ---------------------------------------------------------------------------
 Win32TransService::Win32TransService()
 {
-    // Call the init method to set up our code page map
-    initCPMap();
+    fCPMap = new RefHashTableOf<CPMapEntry>(109);
+
+    //
+    //  Open up the registry key that contains the info we want. Note that,
+    //  if this key does not exist, then we just return. It will just mean
+    //  that we don't have any support except for intrinsic encodings supported
+    //  by the parser itself (and the LCP support of course.
+    //
+    HKEY charsetKey;
+    if (::RegOpenKeyExA
+    (
+        HKEY_CLASSES_ROOT
+        , "MIME\\Database\\Charset"
+        , 0
+        , KEY_READ
+        , &charsetKey))
+    {
+        return;
+    }
+
+    //
+    //  Read in the registry keys that hold the code page ids. Skip for now
+    //  those entries which indicate that they are aliases for some other
+    //  encodings. We'll come back and do a second round for those and look
+    //  up the original name and get the code page id.
+    //
+    //  Note that we have to use A versions here so that this will run on
+    //  98, and transcode the strings to Unicode.
+    //
+    const unsigned int nameBufSz = 1024;
+    char nameBuf[nameBufSz + 1];
+    unsigned int subIndex = 0;
+    unsigned long theSize;
+    while (true)
+    {
+        // Get the name of the next key
+        theSize = nameBufSz;
+        if (::RegEnumKeyExA
+        (
+            charsetKey
+            , subIndex
+            , nameBuf
+            , &theSize
+            , 0, 0, 0, 0) == ERROR_NO_MORE_ITEMS)
+        {
+            break;
+        }
+
+        // Open this subkey
+        HKEY encodingKey;
+        if (::RegOpenKeyExA
+        (
+            charsetKey
+            , nameBuf
+            , 0
+            , KEY_READ
+            , &encodingKey))
+        {
+            XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
+        }
+
+        //
+        //  Lts see if its an alias. If so, then ignore it in this first
+        //  loop. Else, we'll add a new entry for this one.
+        //
+        if (!isAlias(encodingKey))
+        {
+            //
+            //  Lets get the two values out of this key that we are
+            //  interested in. There should be a code page entry and an
+            //  IE entry.
+            //
+            unsigned long theType;
+            unsigned int CPId;
+            unsigned int IEId;
+
+            theSize = sizeof(unsigned int);
+            if (::RegQueryValueExA
+            (
+                encodingKey
+                , "Codepage"
+                , 0
+                , &theType
+                , (unsigned char*)&CPId
+                , &theSize) != ERROR_SUCCESS)
+            {
+                XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
+            }
+
+            //
+            //  If this is not a valid Id, and it might not be because its
+            //  not loaded on this system, then don't take it.
+            //
+            if (::IsValidCodePage(CPId))
+            {
+                theSize = sizeof(unsigned int);
+                if (::RegQueryValueExA
+                (
+                    encodingKey
+                    , "InternetEncoding"
+                    , 0
+                    , &theType
+                    , (unsigned char*)&IEId
+                    , &theSize) != ERROR_SUCCESS)
+                {
+                    XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
+                }
+
+                CPMapEntry* newEntry = new CPMapEntry(nameBuf, CPId, IEId);
+                fCPMap->put(newEntry);
+            }
+        }
+
+        // And now close the subkey handle and bump the subkey index
+        ::RegCloseKey(encodingKey);
+        subIndex++;
+    }
+
+    //
+    //  Now loop one more time and this time we do just the aliases. For
+    //  each one we find, we look up that name in the map we've already
+    //  built and add a new entry with this new name and the same id
+    //  values we stored for the original.
+    //
+    subIndex = 0;
+    char aliasBuf[nameBufSz + 1];
+    while (true)
+    {
+        // Get the name of the next key
+        theSize = nameBufSz;
+        if (::RegEnumKeyExA
+        (
+            charsetKey
+            , subIndex
+            , nameBuf
+            , &theSize
+            , 0, 0, 0, 0) == ERROR_NO_MORE_ITEMS)
+        {
+            break;
+        }
+
+        // Open this subkey
+        HKEY encodingKey;
+        if (::RegOpenKeyExA
+        (
+            charsetKey
+            , nameBuf
+            , 0
+            , KEY_READ
+            , &encodingKey))
+        {
+            XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
+        }
+
+        //
+        //  If its an alias, look up the name in the map. If we find it,
+        //  then construct a new one with the new name and the aliased
+        //  ids.
+        //
+        if (isAlias(encodingKey, aliasBuf, nameBufSz))
+        {
+            const unsigned int srcLen = strlen(aliasBuf);
+            const unsigned int targetLen = ::mbstowcs(0, aliasBuf, srcLen);
+            XMLCh* uniAlias = new XMLCh[targetLen + 1];
+            ::mbstowcs(uniAlias, aliasBuf, srcLen);
+            uniAlias[targetLen] = 0;
+            ::wcsupr(uniAlias);
+
+            // Look up the alias name
+            CPMapEntry* aliasedEntry = fCPMap->get(uniAlias);
+            if (aliasedEntry)
+            {
+                //
+                //  If the name is actually different, then take it.
+                //  Otherwise, don't take it. They map aliases that are
+                //  just different case.
+                //
+                if (::wcscmp(uniAlias, aliasedEntry->getEncodingName()))
+                {
+                    CPMapEntry* newEntry = new CPMapEntry
+                    (
+                        uniAlias
+                        , aliasedEntry->getWinCP()
+                        , aliasedEntry->getIEEncoding()
+                    );
+                    fCPMap->put(newEntry);
+                }
+            }
+            delete [] uniAlias;
+        }
+
+        // And now close the subkey handle and bump the subkey index
+        ::RegCloseKey(encodingKey);
+        subIndex++;
+    }
+
+    // And close the main key handle
+    ::RegCloseKey(charsetKey);
+
 }
 
 Win32TransService::~Win32TransService()
 {
+    delete fCPMap;
 }
 
 
@@ -197,6 +554,74 @@ void Win32TransService::upperCase(XMLCh* const toUpperCase) const
 }
 
 
+bool Win32TransService::isAlias(const   HKEY            encodingKey
+                    ,       char* const     aliasBuf 
+                    , const unsigned int    nameBufSz )
+{
+    unsigned long theType;
+    unsigned long theSize = nameBufSz;
+    return (::RegQueryValueExA
+    (
+        encodingKey
+        , "AliasForCharset"
+        , 0
+        , &theType
+        , (unsigned char*)aliasBuf
+        , &theSize
+    ) == ERROR_SUCCESS);
+}
+
+
+XMLTranscoder*
+Win32TransService::makeNewXMLTranscoder(const   XMLCh* const            encodingName
+                                        ,       XMLTransService::Codes& resValue
+                                        , const unsigned int            blockSize)
+{
+    const unsigned int upLen = 1024;
+    XMLCh upEncoding[upLen + 1];
+
+    //
+    //  Get an upper cased copy of the encoding name, since we use a hash
+    //  table and we store them all in upper case.
+    //
+    ::wcsncpy(upEncoding, encodingName, upLen);
+    upEncoding[upLen] = 0;
+    ::wcsupr(upEncoding);
+
+    // Now to try to find this guy in the CP map
+    CPMapEntry* theEntry = fCPMap->get(upEncoding);
+
+    // If not found, then return a null pointer
+    if (!theEntry)
+    {
+        resValue = XMLTransService::UnsupportedEncoding;
+        return 0;
+    }
+
+    // We found it, so return a Win32 transcoder for this encoding
+    return new Win32Transcoder
+    (
+        encodingName
+        , theEntry->getWinCP()
+        , theEntry->getIEEncoding()
+        , blockSize
+    );
+}
+
+
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+//
+//  class Win32Transcoder Implementation ...
+//
+//---------------------------------------------------------------------------
+
+
 // ---------------------------------------------------------------------------
 //  Win32Transcoder: Constructors and Destructor
 // ---------------------------------------------------------------------------
@@ -419,6 +844,14 @@ bool Win32Transcoder::canTranscodeTo(const unsigned int toCheck) const
 }
 
 
+
+
+//---------------------------------------------------------------------------
+//
+//  class Win32Transcoder Implementation ...
+//
+//---------------------------------------------------------------------------
+
 // ---------------------------------------------------------------------------
 //  Win32LCPTranscoder: Constructors and Destructor
 // ---------------------------------------------------------------------------
@@ -565,3 +998,9 @@ bool Win32LCPTranscoder::transcode( const   XMLCh* const    toTranscode
     toFill[maxBytes] = 0;
     return true;
 }
+
+
+
+
+
+
diff --git a/src/util/Transcoders/Win32/Win32TransService.hpp b/src/util/Transcoders/Win32/Win32TransService.hpp
index 9648b7e06c635a25290527aeee266473b2f7f10d..bab7adee644c9af5d7d55c3346e1eb118927e921 100644
--- a/src/util/Transcoders/Win32/Win32TransService.hpp
+++ b/src/util/Transcoders/Win32/Win32TransService.hpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.10  2000/05/09 00:22:45  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.9  2000/03/18 00:00:04  roddey
  * Initial updates for two way transcoding support
  *
@@ -98,7 +104,18 @@
 #define WIN32TRANSSERVICE_HPP
 
 #include <util/TransService.hpp>
+#include <util/RefHashTableOf.hpp>
+#include <windows.h>
+
+class CPMapEntry;
+
 
+
+//---------------------------------------------------------------------------
+//
+//  class Win32TransService
+//
+//---------------------------------------------------------------------------
 class XMLUTIL_EXPORT Win32TransService : public XMLTransService
 {
 public :
@@ -106,7 +123,7 @@ public :
     //  Constructors and Destructor
     // -----------------------------------------------------------------------
     Win32TransService();
-    ~Win32TransService();
+    virtual ~Win32TransService();
 
 
     // -----------------------------------------------------------------------
@@ -155,15 +172,36 @@ private :
     Win32TransService(const Win32TransService&);
     void operator=(const Win32TransService&);
 
+    //      This is a hash table of entries which map encoding names to their
+    //      Windows specific code pages. The code page allows us to create
+    //      transcoders for those encodings. The encoding names come from XML
+    //      files.
+    //
+    //      This map is shared unsynchronized among all threads of the process,
+    //      which is cool since it will be read only once its initialized.
 
-    // -----------------------------------------------------------------------
-    //  Private helper methods, implemented in Win32TransService2.cpp!
-    // -----------------------------------------------------------------------
-    void initCPMap();
+
+
+    static bool isAlias(const   HKEY            encodingKey
+                    ,       char* const     aliasBuf = 0
+                    , const unsigned int    nameBufSz = 0);
+
+
+    RefHashTableOf<CPMapEntry>    *fCPMap;
 };
 
 
 
+
+
+
+
+//---------------------------------------------------------------------------
+//
+//  class Win32Transcoder
+//
+//---------------------------------------------------------------------------
+
 class XMLUTIL_EXPORT Win32Transcoder : public XMLTranscoder
 {
 public :
@@ -231,6 +269,13 @@ private :
 
 
 
+
+
+//---------------------------------------------------------------------------
+//
+//  class Win32LCPTranscoder
+//
+//---------------------------------------------------------------------------
 class XMLUTIL_EXPORT Win32LCPTranscoder : public XMLLCPTranscoder
 {
 public :
diff --git a/src/util/Transcoders/Win32/Win32TransService2.cpp b/src/util/Transcoders/Win32/Win32TransService2.cpp
index 56b3ec4c6f7464c200ed1574f7b477d09e96800d..08debf47b07a377ac65f4cae3010af679d373555 100644
--- a/src/util/Transcoders/Win32/Win32TransService2.cpp
+++ b/src/util/Transcoders/Win32/Win32TransService2.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.3  2000/05/09 00:22:45  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.2  2000/03/18 00:00:04  roddey
  * Initial updates for two way transcoding support
  *
@@ -75,424 +81,3 @@
 #include <windows.h>
 
 
-// ---------------------------------------------------------------------------
-//  This is the simple CPMapEntry class. It just contains an encoding name
-//  and a code page for that encoding.
-// ---------------------------------------------------------------------------
-class CPMapEntry
-{
-public :
-    // -----------------------------------------------------------------------
-    //  Constructors and Destructor
-    // -----------------------------------------------------------------------
-    CPMapEntry
-    (
-        const   XMLCh* const    encodingName
-        , const unsigned int    cpId
-        , const unsigned int    ieId
-    );
-
-    CPMapEntry
-    (
-        const   char* const     encodingName
-        , const unsigned int    cpId
-        , const unsigned int    ieId
-    );
-
-    ~CPMapEntry();
-
-
-    // -----------------------------------------------------------------------
-    //  Getter methods
-    // -----------------------------------------------------------------------
-    const XMLCh* getEncodingName() const;
-    const XMLCh* getKey() const;
-    unsigned int getWinCP() const;
-    unsigned int getIEEncoding() const;
-
-
-private :
-    // -----------------------------------------------------------------------
-    //  Unimplemented constructors and operators
-    // -----------------------------------------------------------------------
-    CPMapEntry();
-    CPMapEntry(const CPMapEntry&);
-    void operator=(const CPMapEntry&);
-
-
-    // -----------------------------------------------------------------------
-    //  Private data members
-    //
-    //  fEncodingName
-    //      This is the encoding name for the code page that this instance
-    //      represents.
-    //
-    //  fCPId
-    //      This is the Windows specific code page for the encoding that this
-    //      instance represents.
-    //
-    //  fIEId
-    //      This is the IE encoding id. Its not used at this time, but we
-    //      go ahead and get it and store it just in case for later.
-    // -----------------------------------------------------------------------
-    XMLCh*          fEncodingName;
-    unsigned int    fCPId;
-    unsigned int    fIEId;
-};
-
-
-
-// ---------------------------------------------------------------------------
-//  Local data
-//
-//  gCPMap
-//      This is hash table of entries which map encoding names to their
-//      Windows specific code pages. The code page allows us to create
-//      transcoders for those encodings. The encoding names come from XML
-//      files.
-//
-//      This map is shared unsynchronized among all threads of the process,
-//      which is cool since it will be read only once its initialized.
-// ---------------------------------------------------------------------------
-RefHashTableOf<CPMapEntry>   gCPMap(109);
-
-
-// ---------------------------------------------------------------------------
-//  CPMapEntry: Constructors and Destructor
-// ---------------------------------------------------------------------------
-CPMapEntry::CPMapEntry( const   char* const     encodingName
-                        , const unsigned int    cpId
-                        , const unsigned int    ieId) :
-    fEncodingName(0)
-    , fCPId(cpId)
-    , fIEId(ieId)
-{
-    // Transcode the name to Unicode and store that copy
-    const unsigned int srcLen = strlen(encodingName);
-    const unsigned int targetLen = ::mbstowcs(0, encodingName, srcLen);
-    fEncodingName = new XMLCh[targetLen + 1];
-    ::mbstowcs(fEncodingName, encodingName, srcLen);
-    fEncodingName[targetLen] = 0;
-
-    //
-    //  Upper case it because we are using a hash table and need to be
-    //  sure that we find all case combinations.
-    //
-    ::wcsupr(fEncodingName);
-}
-
-CPMapEntry::CPMapEntry( const   XMLCh* const    encodingName
-                        , const unsigned int    cpId
-                        , const unsigned int    ieId) :
-
-    fEncodingName(0)
-    , fCPId(cpId)
-    , fIEId(ieId)
-{
-    fEncodingName = XMLString::replicate(encodingName);
-
-    //
-    //  Upper case it because we are using a hash table and need to be
-    //  sure that we find all case combinations.
-    //
-    ::wcsupr(fEncodingName);
-}
-
-CPMapEntry::~CPMapEntry()
-{
-    delete [] fEncodingName;
-}
-
-
-// ---------------------------------------------------------------------------
-//  CPMapEntry: Getter methods
-// ---------------------------------------------------------------------------
-const XMLCh* CPMapEntry::getEncodingName() const
-{
-    return fEncodingName;
-}
-
-const XMLCh* CPMapEntry::getKey() const
-{
-    return fEncodingName;
-}
-
-unsigned int CPMapEntry::getWinCP() const
-{
-    return fCPId;
-}
-
-unsigned int CPMapEntry::getIEEncoding() const
-{
-    return fIEId;
-}
-
-
-
-// ---------------------------------------------------------------------------
-//  Local methods
-// ---------------------------------------------------------------------------
-static bool isAlias(const   HKEY            encodingKey
-                    ,       char* const     aliasBuf = 0
-                    , const unsigned int    nameBufSz = 0)
-{
-    unsigned long theType;
-    unsigned long theSize = nameBufSz;
-    return (::RegQueryValueExA
-    (
-        encodingKey
-        , "AliasForCharset"
-        , 0
-        , &theType
-        , (unsigned char*)aliasBuf
-        , &theSize
-    ) == ERROR_SUCCESS);
-}
-
-
-// ---------------------------------------------------------------------------
-//  Win32TransService: The protected virtual transcoding service API
-// ---------------------------------------------------------------------------
-XMLTranscoder*
-Win32TransService::makeNewXMLTranscoder(const   XMLCh* const            encodingName
-                                        ,       XMLTransService::Codes& resValue
-                                        , const unsigned int            blockSize)
-{
-    const unsigned int upLen = 1024;
-    XMLCh upEncoding[upLen + 1];
-
-    //
-    //  Get an upper cased copy of the encoding name, since we use a hash
-    //  table and we store them all in upper case.
-    //
-    ::wcsncpy(upEncoding, encodingName, upLen);
-    upEncoding[upLen] = 0;
-    ::wcsupr(upEncoding);
-
-    // Now to try to find this guy in the CP map
-    CPMapEntry* theEntry = gCPMap.get(upEncoding);
-
-    // If not found, then return a null pointer
-    if (!theEntry)
-    {
-        resValue = XMLTransService::UnsupportedEncoding;
-        return 0;
-    }
-
-    // We found it, so return a Win32 transcoder for this encoding
-    return new Win32Transcoder
-    (
-        encodingName
-        , theEntry->getWinCP()
-        , theEntry->getIEEncoding()
-        , blockSize
-    );
-}
-
-
-
-// ---------------------------------------------------------------------------
-//  Win32TransService: Private helper methods
-// ---------------------------------------------------------------------------
-void Win32TransService::initCPMap()
-{
-    //
-    //  Open up the registry key that contains the info we want. Note that,
-    //  if this key does not exist, then we just return. It will just mean
-    //  that we don't have any support except for intrinsic encodings supported
-    //  by the parser itself (and the LCP support of course.
-    //
-    HKEY charsetKey;
-    if (::RegOpenKeyExA
-    (
-        HKEY_CLASSES_ROOT
-        , "MIME\\Database\\Charset"
-        , 0
-        , KEY_READ
-        , &charsetKey))
-    {
-        return;
-    }
-
-    //
-    //  Read in the registry keys that hold the code page ids. Skip for now
-    //  those entries which indicate that they are aliases for some other
-    //  encodings. We'll come back and do a second round for those and look
-    //  up the original name and get the code page id.
-    //
-    //  Note that we have to use A versions here so that this will run on
-    //  98, and transcode the strings to Unicode.
-    //
-    const unsigned int nameBufSz = 1024;
-    char nameBuf[nameBufSz + 1];
-    unsigned int subIndex = 0;
-    unsigned long theSize;
-    while (true)
-    {
-        // Get the name of the next key
-        theSize = nameBufSz;
-        if (::RegEnumKeyExA
-        (
-            charsetKey
-            , subIndex
-            , nameBuf
-            , &theSize
-            , 0, 0, 0, 0) == ERROR_NO_MORE_ITEMS)
-        {
-            break;
-        }
-
-        // Open this subkey
-        HKEY encodingKey;
-        if (::RegOpenKeyExA
-        (
-            charsetKey
-            , nameBuf
-            , 0
-            , KEY_READ
-            , &encodingKey))
-        {
-            XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
-        }
-
-        //
-        //  Lts see if its an alias. If so, then ignore it in this first
-        //  loop. Else, we'll add a new entry for this one.
-        //
-        if (!isAlias(encodingKey))
-        {
-            //
-            //  Lets get the two values out of this key that we are
-            //  interested in. There should be a code page entry and an
-            //  IE entry.
-            //
-            unsigned long theType;
-            unsigned int CPId;
-            unsigned int IEId;
-
-            theSize = sizeof(unsigned int);
-            if (::RegQueryValueExA
-            (
-                encodingKey
-                , "Codepage"
-                , 0
-                , &theType
-                , (unsigned char*)&CPId
-                , &theSize) != ERROR_SUCCESS)
-            {
-                XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
-            }
-
-            //
-            //  If this is not a valid Id, and it might not be because its
-            //  not loaded on this system, then don't take it.
-            //
-            if (::IsValidCodePage(CPId))
-            {
-                theSize = sizeof(unsigned int);
-                if (::RegQueryValueExA
-                (
-                    encodingKey
-                    , "InternetEncoding"
-                    , 0
-                    , &theType
-                    , (unsigned char*)&IEId
-                    , &theSize) != ERROR_SUCCESS)
-                {
-                    XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
-                }
-
-                CPMapEntry* newEntry = new CPMapEntry(nameBuf, CPId, IEId);
-                gCPMap.put(newEntry);
-            }
-        }
-
-        // And now close the subkey handle and bump the subkey index
-        ::RegCloseKey(encodingKey);
-        subIndex++;
-    }
-
-    //
-    //  Now loop one more time and this time we do just the aliases. For
-    //  each one we find, we look up that name in the map we've already
-    //  built and add a new entry with this new name and the same id
-    //  values we stored for the original.
-    //
-    subIndex = 0;
-    char aliasBuf[nameBufSz + 1];
-    while (true)
-    {
-        // Get the name of the next key
-        theSize = nameBufSz;
-        if (::RegEnumKeyExA
-        (
-            charsetKey
-            , subIndex
-            , nameBuf
-            , &theSize
-            , 0, 0, 0, 0) == ERROR_NO_MORE_ITEMS)
-        {
-            break;
-        }
-
-        // Open this subkey
-        HKEY encodingKey;
-        if (::RegOpenKeyExA
-        (
-            charsetKey
-            , nameBuf
-            , 0
-            , KEY_READ
-            , &encodingKey))
-        {
-            XMLPlatformUtils::panic(XMLPlatformUtils::Panic_NoTransService);
-        }
-
-        //
-        //  If its an alias, look up the name in the map. If we find it,
-        //  then construct a new one with the new name and the aliased
-        //  ids.
-        //
-        if (isAlias(encodingKey, aliasBuf, nameBufSz))
-        {
-            const unsigned int srcLen = strlen(aliasBuf);
-            const unsigned int targetLen = ::mbstowcs(0, aliasBuf, srcLen);
-            XMLCh* uniAlias = new XMLCh[targetLen + 1];
-            ::mbstowcs(uniAlias, aliasBuf, srcLen);
-            uniAlias[targetLen] = 0;
-            ::wcsupr(uniAlias);
-
-            // Look up the alias name
-            CPMapEntry* aliasedEntry = gCPMap.get(uniAlias);
-            if (aliasedEntry)
-            {
-                //
-                //  If the name is actually different, then take it.
-                //  Otherwise, don't take it. They map aliases that are
-                //  just different case.
-                //
-                if (::wcscmp(uniAlias, aliasedEntry->getEncodingName()))
-                {
-                    CPMapEntry* newEntry = new CPMapEntry
-                    (
-                        uniAlias
-                        , aliasedEntry->getWinCP()
-                        , aliasedEntry->getIEEncoding()
-                    );
-                    gCPMap.put(newEntry);
-                }
-            }
-             else
-            {
-                delete [] uniAlias;
-            }
-        }
-
-        // And now close the subkey handle and bump the subkey index
-        ::RegCloseKey(encodingKey);
-        subIndex++;
-    }
-
-    // And close the main key handle
-    ::RegCloseKey(charsetKey);
-}
diff --git a/src/util/XMLException.cpp b/src/util/XMLException.cpp
index 21324e53cbe9e4be7ca26586ea0bf97e87ec666e..800c6a8add0cd05dcc0d59be2b3e0f49437fc3cc 100644
--- a/src/util/XMLException.cpp
+++ b/src/util/XMLException.cpp
@@ -56,6 +56,12 @@
 
 /*
  * $Log$
+ * Revision 1.5  2000/05/09 00:22:40  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.4  2000/03/02 19:54:48  roddey
  * This checkin includes many changes done while waiting for the
  * 1.1.0 code to be finished. I can't list them all here, but a list is
@@ -83,6 +89,7 @@
 // ---------------------------------------------------------------------------
 #include <util/Mutexes.hpp>
 #include <util/PlatformUtils.hpp>
+#include <util/XMLDeleterFor.hpp>
 #include <util/XMLException.hpp>
 #include <util/XMLMsgLoader.hpp>
 #include <util/XMLString.hpp>
@@ -122,9 +129,18 @@ static XMLMutex& gMsgMutex()
         XMLMutex* tmpMutex = new XMLMutex;
         if (XMLPlatformUtils::compareAndSwap((void**)&msgMutex, tmpMutex, 0))
         {
-            // Someone beat us to it, so let's clean up ours
+            // Some other thread beat us to it, so let's clean up ours.
             delete tmpMutex;
         }
+        else
+        {
+            // This is the real mutex.  Register it for deletion at Termination.
+            XMLPlatformUtils::registerLazyData
+                (
+                new XMLDeleterFor<XMLMutex>(msgMutex)
+                );
+        }
+        
     }
     return *msgMutex;
 }
@@ -151,8 +167,17 @@ static XMLMsgLoader& gGetMsgLoader()
         gLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgExceptDomain);
         if (!gLoader)
             XMLPlatformUtils::panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
-    }
 
+        //
+        // Register this XMLMsgLoader for deletion at Termination.
+        //
+        XMLPlatformUtils::registerLazyData
+            (
+            new XMLDeleterFor<XMLMsgLoader>(gLoader)
+            );
+        
+    }
+    
     // We got it, so return it
     return *gLoader;
 }
diff --git a/tests/DOM/DOMMemTest/DOMMemTest.cpp b/tests/DOM/DOMMemTest/DOMMemTest.cpp
index 3fffe143950a4766fc668a2a7141c52c2dd1ab0d..13dd5c4a4603707452f32b4cb48515dc14cbae56 100644
--- a/tests/DOM/DOMMemTest/DOMMemTest.cpp
+++ b/tests/DOM/DOMMemTest/DOMMemTest.cpp
@@ -66,6 +66,12 @@
 
 /*
  * $Log$
+ * Revision 1.22  2000/05/09 00:22:48  andyh
+ * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
+ * allocated memory; memory leak checking tools will no longer report
+ * that leaks exist.  (DOM GetElementsByTagID temporarily removed
+ * as part of this.)
+ *
  * Revision 1.21  2000/04/18 01:07:28  aruna1
  * Rectified memory leak caused by doctype-getNodeName()
  *
@@ -191,23 +197,15 @@ void tassert(bool c, char *file, int line)
 }
 
 
-
-
-int  main()
+//---------------------------------------------------------------------------------------
+//
+//   DOMStringTests    tests of class DOMString
+//
+//---------------------------------------------------------------------------------------
+void    DOMStringTests()
 {
     DomMemDebug     entryMemState, exitMemState;
-
-	try {
-		XMLPlatformUtils::Initialize();
-	}
-	catch (const XMLException& toCatch) {
-        char *pMessage = XMLString::transcode(toCatch.getMessage());
-        fprintf(stderr, "Error during XMLPlatformUtils::Initialize(). \n"
-                        "  Message is: %s\n", pMessage);
-        delete [] pMessage;
-        return -1;
-    }
-
+    
     //
     //  Test 1.  Basic operations on a simple string.
     //
@@ -223,29 +221,28 @@ int  main()
         TASSERT(foo.charAt(3) == 0);
     }
     TESTEPILOG
-
-
-    //
-    //  Construct from XMLCh *
-    //
-    TESTPROLOG
+        
+        //
+        //  Construct from XMLCh *
+        //
+        TESTPROLOG
     {
         //  ToDo - this test will fail on EBCDIC machines.  !!
-
+        
         XMLCh a[] = {'H', 'e', 'l', 'l', 'o', 0};
         DOMString x(a);
         DOMString y = "Hello";
         TASSERT(x.equals(y));
-
+        
         DOMString z(a+2, 3);
         TASSERT(z.equals("llo"));
     }
     TESTEPILOG
-
-    //
-    //  Test 2.  Empty strings shouldn't leave anything lying around
-    //
-    TESTPROLOG;
+        
+        //
+        //  Test 2.  Empty strings shouldn't leave anything lying around
+        //
+        TESTPROLOG;
     {
         DOMString a;
         DOMString b;
@@ -253,18 +250,18 @@ int  main()
         a = 0;
         TASSERT(a==0);
         TASSERT((a!=0) == false);
-
+        
         DOMString c(0);
         TASSERT(c==0);
         TASSERT(c==a);
     }
     TESTEPILOG
-
-
-    //
-    //  Test 3.   Clones should be equal. 
-    TESTPROLOG;
-   {
+        
+        
+        //
+        //  Test 3.   Clones should be equal. 
+        TESTPROLOG;
+    {
         DOMString a = "hello";
         DOMString b = a.clone();
         TASSERT(a.equals(b));
@@ -275,12 +272,12 @@ int  main()
         TASSERT(a.equals(""));
     }
     TESTEPILOG
-
-
-    //
-    //  Test 4.  Copy construction and assignemnt
-    //
-    TESTPROLOG;
+        
+        
+        //
+        //  Test 4.  Copy construction and assignemnt
+        //
+        TESTPROLOG;
     {
         DOMString a = "Test 04";
         DOMString b(a);
@@ -295,32 +292,32 @@ int  main()
         // printf ("   test04 should have 1 handle, 1 buffer here.  "); 
     }
     TESTEPILOG
-
-
-    //
-    // Test 5  AppendData, degenerate cases.
-    //
-    TESTPROLOG;
+        
+        
+        //
+        // Test 5  AppendData, degenerate cases.
+        //
+        TESTPROLOG;
     {
         DOMString a;
         DOMString b = "Test 05";
-
+        
         a.appendData(b);
         TASSERT(a.equals(b));
         TASSERT(a!=b);
         TASSERT(a.equals("Test 05"));
     };
     TESTEPILOG
-
-
-    //
-    //  Test 6  Append data, degenerate case 2
-    //
-    TESTPROLOG;
+        
+        
+        //
+        //  Test 6  Append data, degenerate case 2
+        //
+        TESTPROLOG;
     {
         DOMString a;
         DOMString b = "Test 06";
-
+        
         b.appendData(a);
         TASSERT(!a.equals(b));
         TASSERT(a!=b);
@@ -328,52 +325,52 @@ int  main()
         TASSERT(a==0);
     }
     TESTEPILOG
-
-
-    //
-    //  Test 7  Append Data, Common case, no extra space in original buffer.
-    //          Also, operator +=, which is a convenience alias for appendData.
-    //
-    TESTPROLOG;
+        
+        
+        //
+        //  Test 7  Append Data, Common case, no extra space in original buffer.
+        //          Also, operator +=, which is a convenience alias for appendData.
+        //
+        TESTPROLOG;
     {
         DOMString a = "Test 07";
         DOMString b = "append";
-
+        
         a.appendData(b);
         TASSERT(a.equals("Test 07append"));
         TASSERT(b.equals("append"));
-
+        
         a.appendData((XMLCh)0x31);
         TASSERT(a.equals("Test 07append1"));
-
+        
         XMLCh  s[] = {0x32, 0x33, 0x00};
         a.appendData(s);
         TASSERT(a.equals("Test 07append123"));
-
+        
         a = "Test 07a ";
         a += b;
         TASSERT(a.equals("Test 07a append"));
-       
+        
         a += (XMLCh)0x31;
         TASSERT(a.equals("Test 07a append1"));
-
+        
         a += s;
         TASSERT(a.equals("Test 07a append123"));
-
+        
     }
     TESTEPILOG
-
-
-    //
-    //  Test 8 Append Data, with plenty of extra space in buffer.
-    //
-    TESTPROLOG;
+        
+        
+        //
+        //  Test 8 Append Data, with plenty of extra space in buffer.
+        //
+        TESTPROLOG;
     {
         DOMString a;
-		a.reserve(100);
+        a.reserve(100);
         DOMString b("Test 08");
         DOMString c("append");
-
+        
         TASSERT(a != 0);  // (The String object has an identity, even if no contents)
         TASSERT(a.length() == 0);
         a.appendData(b);
@@ -386,26 +383,26 @@ int  main()
         TASSERT(c.equals("append"));
     };
     TESTEPILOG
-
-
-
-    //
-    //  Test 9 Append Data, with plenty of extra space in buffer, but with
-    //                      a clone, so that the original buffer can not be modified.
-    //
-    TESTPROLOG;
+        
+        
+        
+        //
+        //  Test 9 Append Data, with plenty of extra space in buffer, but with
+        //                      a clone, so that the original buffer can not be modified.
+        //
+        TESTPROLOG;
     {
         DOMString a;
-		a.reserve(100);
+        a.reserve(100);
         DOMString b("Test 09");
         DOMString c("append");
-
+        
         TASSERT(a.length() == 0);
         a.appendData(b);
         TASSERT(a.equals(b));
         TASSERT(a.equals("Test 09"));
         TASSERT(a != b);
-
+        
         DOMString d = a.clone();
         TASSERT(a.equals("Test 09"));
         TASSERT(b.equals("Test 09"));
@@ -413,7 +410,7 @@ int  main()
         TASSERT(a != b);
         TASSERT(a != d);
         TASSERT(b != d);
-
+        
         a.appendData(c);
         TASSERT(a.equals("Test 09append"));
         TASSERT(b.equals("Test 09"));
@@ -421,8 +418,8 @@ int  main()
         TASSERT(d.equals("Test 09"));
     };
     TESTEPILOG;
-
-
+    
+    
     //
     // Test 10   DOMString Operator +
     //
@@ -432,25 +429,25 @@ int  main()
         DOMString b("DOMString ");
         XMLCh     s[] = {0x58, 0x4d, 0x4c, 0x20, 0x00};   // Unicode "XML "
         XMLCh     Z   = 0x5A;                             // Unicode 'Z'
-
+        
         a = b + b;
         TASSERT(a.equals("DOMString DOMString "));
-
+        
         a = b + s;
         TASSERT(a.equals("DOMString XML "));
-
+        
         a = s + b;
         TASSERT(a.equals("XML DOMString "));
-
+        
         a = b + Z;
         TASSERT(a.equals("DOMString Z"));
-
+        
         a = Z + b;
         TASSERT(a.equals("ZDOMString "));
     }
     TESTEPILOG;
-
-
+    
+    
     //
     // Test 11   DOMString::subStringData(unsigned int offset, unsigned int count)
     //
@@ -458,33 +455,33 @@ int  main()
     {
         DOMString srcString("This is the source string.");
         //                   01234567890123456789012345
-
+        
         DOMString This = srcString.substringData(0,4);
         DOMString is   = srcString.substringData(5,2);
         DOMString dot  = srcString.substringData(25,1);
         DOMString offEnd = srcString.substringData(19, 1000);
-
+        
         TASSERT(This.equals("This"));
         TASSERT(is  .equals("is"));
         TASSERT(dot .equals("."));
         TASSERT(offEnd.equals("string."));
-
+        
         EXCEPTION_TEST(srcString.substringData(-1, 10), DOM_DOMException::INDEX_SIZE_ERR);
         EXCEPTION_TEST(srcString.substringData(26, 1), DOM_DOMException::INDEX_SIZE_ERR);
-
+        
         srcString.insertData(0, "x");   // Changing the source should not alter previously
-                                        //   extracted substrings.
-
+        //   extracted substrings.
+        
         TASSERT(This.equals("This"));
         TASSERT(is  .equals("is"));
         TASSERT(dot .equals("."));
         TASSERT(offEnd.equals("string."));
         TASSERT(srcString.equals("xThis is the source string."));
-
+        
     }
     TESTEPILOG;
-
-
+    
+    
     //
     // Test 12   DOMString::insertData(unsigned int offset, DOMString &src)
     //
@@ -492,36 +489,97 @@ int  main()
     {
         DOMString aString("This is a string.");
         //                 01234567890123456
-
+        
         aString.insertData(17, " Added at end.");
         TASSERT(aString.equals("This is a string. Added at end."));
-
+        
         aString = "This is a string.";
         EXCEPTION_TEST(aString.insertData(18, "x"), DOM_DOMException::INDEX_SIZE_ERR);
         TASSERT(aString.equals("This is a string."));
-
+        
         aString = 0;
         aString.reserve(100);
         aString.appendData("This is a string.");
         aString.insertData(17, " Added at end.");
         TASSERT(aString.equals("This is a string. Added at end."));
-
+        
         aString.insertData(0, "So ");
         TASSERT(aString.equals("So This is a string. Added at end."));
-
+        
         aString.insertData(2, "x");
         TASSERT(aString.equals("Sox This is a string. Added at end."));
-
+        
         EXCEPTION_TEST(aString.substringData(-1, 1), DOM_DOMException::INDEX_SIZE_ERR);
+        
+        
+    }
+    TESTEPILOG;
+    
 
+	//
+	// Minimal test of DOMString::transcode()
+	//
+	TESTPROLOG;
+	{
+		static char testStr[] = "This is our test string.";
 
-    }
+		DOMString DOMTestStr = testStr;
+		char *roundTripString = DOMTestStr.transcode();
+		TASSERT(strcmp(testStr, roundTripString) == 0);
+		delete [] roundTripString;
+
+        DOMString domstr2 = DOMString::transcode(testStr);
+        TASSERT(domstr2.equals(DOMTestStr));
+	}
     TESTEPILOG;
 
 
+    //
+    //  String bugs submitted by David Chung
+    //
+	TESTPROLOG;
+	{
+        DOMString greeting("hello");
+        greeting.appendData(greeting);
+        TASSERT(greeting.equals("hellohello"));
+
+ 
+        // Test DOMString.insertData, when source string is the same as the destination.
+        //   Implementation forces creation of a new buffer.
+        //                            
+        DOMString greeting2("Hello              ");
+        //                   0123456789012345678
+        greeting2.deleteData(5, 14);    // Leave unused space at end of buffer.
+        TASSERT(greeting2.equals("Hello"));
+
+        greeting2.insertData(2, greeting2); 
+        TASSERT(greeting2.equals("HeHellollo"));
+
+
+        // DOMString.insertData().  Original buffer has space, and is retained.
+        DOMString greeting3("Hello              ");
+        //                   0123456789012345678
+        greeting3.deleteData(5, 14);    // Leave unused space at end of buffer.
+        TASSERT(greeting3.equals("Hello"));  
+
+        greeting3.insertData(2, "ByeBye"); 
+        TASSERT(greeting3.equals("HeByeByello"));
+
+    }
+    TESTEPILOG;
+
+}
 
 
 
+//---------------------------------------------------------------------------------------
+//
+//   DOMBasicTests    Basic DOM Level 1 tests
+//
+//---------------------------------------------------------------------------------------
+void DOMBasicTests()
+{
+        DomMemDebug     entryMemState, exitMemState;
     //
     //  Test Doc01      Create a new empty document
     //
@@ -946,57 +1004,18 @@ int  main()
     TESTEPILOG;
 
 
-	//
-	// Minimal test of DOMString::transcode()
-	//
-	TESTPROLOG;
-	{
-		static char testStr[] = "This is our test string.";
-
-		DOMString DOMTestStr = testStr;
-		char *roundTripString = DOMTestStr.transcode();
-		TASSERT(strcmp(testStr, roundTripString) == 0);
-		delete [] roundTripString;
-
-        DOMString domstr2 = DOMString::transcode(testStr);
-        TASSERT(domstr2.equals(DOMTestStr));
-	}
-    TESTEPILOG;
-
-
-    //
-    //  String bugs submitted by David Chung
-    //
-	TESTPROLOG;
-	{
-        DOMString greeting("hello");
-        greeting.appendData(greeting);
-        TASSERT(greeting.equals("hellohello"));
-
- 
-        // Test DOMString.insertData, when source string is the same as the destination.
-        //   Implementation forces creation of a new buffer.
-        //                            
-        DOMString greeting2("Hello              ");
-        //                   0123456789012345678
-        greeting2.deleteData(5, 14);    // Leave unused space at end of buffer.
-        TASSERT(greeting2.equals("Hello"));
-
-        greeting2.insertData(2, greeting2); 
-        TASSERT(greeting2.equals("HeHellollo"));
-
+}
 
-        // DOMString.insertData().  Original buffer has space, and is retained.
-        DOMString greeting3("Hello              ");
-        //                   0123456789012345678
-        greeting3.deleteData(5, 14);    // Leave unused space at end of buffer.
-        TASSERT(greeting3.equals("Hello"));  
 
-        greeting3.insertData(2, "ByeBye"); 
-        TASSERT(greeting3.equals("HeByeByello"));
+//---------------------------------------------------------------------------------------
+//
+//   DOMNSTests    DOM Name Space tests
+//
+//---------------------------------------------------------------------------------------
+void DOMNSTests()
+{
+        DomMemDebug     entryMemState, exitMemState;
 
-    }
-    TESTEPILOG;
 
 
     //
@@ -1612,19 +1631,51 @@ int  main()
     }
     TESTEPILOG;
 
-
+    //
+    // 
+    //
+    TESTPROLOG;
     {
-        
 
 
     }
- 
+    TESTEPILOG;
+
+}
+
+
+
+//---------------------------------------------------------------------------------------
+//
+//   main
+//
+//---------------------------------------------------------------------------------------
+int  main()
+{
+    try {
+        XMLPlatformUtils::Initialize();
+    }
+    catch (const XMLException& toCatch) {
+        char *pMessage = XMLString::transcode(toCatch.getMessage());
+        fprintf(stderr, "Error during XMLPlatformUtils::Initialize(). \n"
+            "  Message is: %s\n", pMessage);
+        delete [] pMessage;
+        return -1;
+    }
+    
+    
+    DOMStringTests();
+    DOMBasicTests();
+    DOMNSTests();
+
     //
-    //  Print Final allocation stats for full test
+    //  Print Final allocation stats for full set of tests
     //
+    XMLPlatformUtils::Terminate();
     DomMemDebug().print();
-    
     return 0;
-    };
-    
-            
+
+};
+
+
+