diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp
index 690458bf77a4d732527b5eea28b1f932ca534661..fe2b2d2b7c02f7c96c428cc2f4b7bb903d115684 100644
--- a/src/xercesc/internal/IGXMLScanner.cpp
+++ b/src/xercesc/internal/IGXMLScanner.cpp
@@ -1371,7 +1371,14 @@ void IGXMLScanner::scanDocTypeDecl()
         // this will break getRootElemId on DTDGrammar when
         // cached grammars are in use, but 
         // why would one use this anyway???
-        ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+        try {
+            ((DTDGrammar*)fGrammar)->setRootElemId(fGrammar->putElemDecl(rootDecl));
+        }
+        catch(const XMLException&)
+        {
+            delete rootDecl;
+            throw;
+        }
     } else
     {
         // attach this to the undeclared element pool so that it gets deleted
diff --git a/src/xercesc/internal/XMLReader.cpp b/src/xercesc/internal/XMLReader.cpp
index cacead230a99abcad54552da44a27e8b3432168b..fedfb15e3eec72f4a80d5e326943c56d0eaa5dc1 100644
--- a/src/xercesc/internal/XMLReader.cpp
+++ b/src/xercesc/internal/XMLReader.cpp
@@ -70,6 +70,7 @@
 #include <xercesc/util/TransService.hpp>
 #include <xercesc/util/XMLEBCDICTranscoder.hpp>
 #include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/Janitor.hpp>
 
 
 XERCES_CPP_NAMESPACE_BEGIN
@@ -1321,6 +1322,9 @@ void XMLReader::doInitDecode()
                 {
                     fCharsAvail = 0;
                     fRawBufIndex = 0;
+                    fMemoryManager->deallocate(fPublicId);
+                    fMemoryManager->deallocate(fEncodingStr);
+                    ArrayJanitor<XMLCh> janValue(fSystemId, fMemoryManager);
                     ThrowXMLwithMemMgr1
                     (
                         TranscodingException
@@ -1397,6 +1401,9 @@ void XMLReader::doInitDecode()
                 {
                     fCharsAvail = 0;
                     fRawBufIndex = 0;
+                    fMemoryManager->deallocate(fPublicId);
+                    fMemoryManager->deallocate(fEncodingStr);
+                    ArrayJanitor<XMLCh> janValue(fSystemId, fMemoryManager);
                     ThrowXMLwithMemMgr1
                     (
                         TranscodingException
@@ -1514,6 +1521,9 @@ void XMLReader::doInitDecode()
 
         default :
             // It should never be anything else here
+            fMemoryManager->deallocate(fPublicId);
+            fMemoryManager->deallocate(fEncodingStr);                    
+            fMemoryManager->deallocate(fSystemId);
             ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Reader_BadAutoEncoding, fMemoryManager);
             break;
     }
diff --git a/src/xercesc/internal/XMLScanner.cpp b/src/xercesc/internal/XMLScanner.cpp
index df4d3db431ac52580eee0ea9f08f69bd676538ea..f7ea19a22d32ddf1763e6981ef61614fff0a7c5a 100644
--- a/src/xercesc/internal/XMLScanner.cpp
+++ b/src/xercesc/internal/XMLScanner.cpp
@@ -782,6 +782,13 @@ void XMLScanner::initValidator(XMLValidator* theValidator) {
 //  These methods are called whenever the scanner wants to emit an error.
 //  It handles getting the message loaded, doing token replacement, etc...
 //  and then calling the error handler, if its installed.
+bool XMLScanner::emitErrorWillThrowException(const XMLErrs::Codes toEmit)
+{
+    if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
+        return true;
+    return false;
+}
+
 void XMLScanner::emitError(const XMLErrs::Codes toEmit)
 {
     // Bump the error count if it is not a warning
@@ -820,7 +827,7 @@ void XMLScanner::emitError(const XMLErrs::Codes toEmit)
     }
 
     // Bail out if its fatal an we are to give up on the first fatal error
-    if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
+    if (emitErrorWillThrowException(toEmit))
         throw toEmit;
 }
 
@@ -867,7 +874,7 @@ void XMLScanner::emitError( const   XMLErrs::Codes    toEmit
     }
 
     // Bail out if its fatal an we are to give up on the first fatal error
-    if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
+    if (emitErrorWillThrowException(toEmit))
         throw toEmit;
 }
 
@@ -914,7 +921,7 @@ void XMLScanner::emitError( const   XMLErrs::Codes    toEmit
     }
 
     // Bail out if its fatal an we are to give up on the first fatal error
-    if (XMLErrs::isFatal(toEmit) && fExitOnFirstFatal && !fInException)
+    if (emitErrorWillThrowException(toEmit))
         throw toEmit;
 }
 
diff --git a/src/xercesc/internal/XMLScanner.hpp b/src/xercesc/internal/XMLScanner.hpp
index 430ae9dcc418f39b00d4f4cabc8cb2022d3de2cf..4569d79548028c0f6c774c8f876a4f15bd68e131 100644
--- a/src/xercesc/internal/XMLScanner.hpp
+++ b/src/xercesc/internal/XMLScanner.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.32  2003/12/31 15:40:00  cargilld
+ * Release memory when an error is encountered.
+ *
  * Revision 1.31  2003/11/28 21:18:32  knoaman
  * Make use of canonical representation in PSVIElement
  *
@@ -429,6 +432,7 @@ public :
     // -----------------------------------------------------------------------
     //  Error emitter methods
     // -----------------------------------------------------------------------
+    bool emitErrorWillThrowException(const XMLErrs::Codes toEmit);
     void emitError(const XMLErrs::Codes toEmit);
     void emitError
     (
diff --git a/src/xercesc/validators/DTD/DTDScanner.cpp b/src/xercesc/validators/DTD/DTDScanner.cpp
index 08bff4044d365b65d72d1d8f179eff2dea643236..48c6e035efcc44a4566059d68dd1071ae6d05789 100644
--- a/src/xercesc/validators/DTD/DTDScanner.cpp
+++ b/src/xercesc/validators/DTD/DTDScanner.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.31  2003/12/31 15:40:00  cargilld
+ * Release memory when an error is encountered.
+ *
  * Revision 1.30  2003/12/17 00:18:40  cargilld
  * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data.
  *
@@ -1322,7 +1325,13 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse)
         if (tmpNode != curNode)
         {
             if (gotSpaces)
+            {
+                if (fScanner->emitErrorWillThrowException(XMLErrs::UnexpectedWhitespace))
+                {
+                    delete tmpNode;
+                }
                 fScanner->emitError(XMLErrs::UnexpectedWhitespace);
+            }
             fReaderMgr->getNextChar();
             curNode = tmpNode;
         }
@@ -1447,7 +1456,15 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse)
                     curReader = fReaderMgr->getCurrentReaderNum();
 
                     // Recurse to handle this new guy
-                    ContentSpecNode* subNode = scanChildren(elemDecl, bufToUse);
+                    ContentSpecNode* subNode;
+                    try {
+                        subNode = scanChildren(elemDecl, bufToUse);
+                    }
+                    catch (const XMLErrs::Codes)
+                    {
+                        delete headNode;
+                        throw;
+                    }
 
                     // If it failed, we are done, clean up here and return failure
                     if (!subNode)
@@ -1542,6 +1559,7 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse)
              else
             {
                 // Cannot be valid
+                delete headNode;  // emitError may do a throw so need to clean-up first
                 if (opCh == chComma)
                 {
                     fScanner->emitError(XMLErrs::ExpectedChoiceOrCloseParen);
@@ -1553,8 +1571,7 @@ DTDScanner::scanChildren(const DTDElementDecl& elemDecl, XMLBuffer& bufToUse)
                         XMLErrs::ExpectedSeqOrCloseParen
                         , elemDecl.getFullName()
                     );
-                }
-                delete headNode;
+                }                
                 return 0;
             }
         }
@@ -3421,6 +3438,10 @@ bool DTDScanner::scanMixed(DTDElementDecl& toFill)
             //  Tell them they can't have reps in mixed model, but eat
             //  it and keep going if we are allowed to.
             //
+            if (fScanner->emitErrorWillThrowException(XMLErrs::NoRepInMixed))
+            {
+                delete headNode;
+            }
             fScanner->emitError(XMLErrs::NoRepInMixed);
         }
          else if (fReaderMgr->skippedSpace())
@@ -3446,7 +3467,13 @@ bool DTDScanner::scanMixed(DTDElementDecl& toFill)
                     starSkipped = false;
 
                     if (starRequired)
+                    {
+                        if (fScanner->emitErrorWillThrowException(XMLErrs::UnterminatedContentModel))
+                        {
+                            delete headNode;
+                        }
                         fScanner->emitError(XMLErrs::ExpectedAsterisk);
+                    }
                 }
 
                 //