diff --git a/src/xercesc/internal/DGXMLScanner.cpp b/src/xercesc/internal/DGXMLScanner.cpp
index c1230dd3a2b5e6524f42996701061c403e3b9e80..59da37a65c6c84a88ad5bc06fc4706710dbfb89e 100644
--- a/src/xercesc/internal/DGXMLScanner.cpp
+++ b/src/xercesc/internal/DGXMLScanner.cpp
@@ -974,7 +974,7 @@ void DGXMLScanner::scanDocTypeDecl()
             fReaderMgr.pushReader(reader, declDTD);
 
             // Tell it its not in an include section
-            dtdScanner.scanExtSubsetDecl(false);
+            dtdScanner.scanExtSubsetDecl(false, true);
         }
     }
 }
@@ -1729,7 +1729,7 @@ Grammar* DGXMLScanner::loadDTDGrammar(const InputSource& src,
     dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
 
     // Tell it its not in an include section
-    dtdScanner.scanExtSubsetDecl(false);
+    dtdScanner.scanExtSubsetDecl(false, true);
 
     if (fValidate) {
         //  validate the DTD scan so far
diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp
index 71c89363424d0e65bcaa4e183b86c369342f6777..1a42b29c4a5ea0fb6e6f8c86d0ccc5d8ad42f68a 100644
--- a/src/xercesc/internal/IGXMLScanner.cpp
+++ b/src/xercesc/internal/IGXMLScanner.cpp
@@ -1061,7 +1061,7 @@ void IGXMLScanner::scanEndTag(bool& gotData)
     }
     if(!isRoot && fGrammarType == Grammar::SchemaGrammarType)
         ((SchemaElementDecl *)fElemStack.topElement()->fThisElement)->updateValidityFromElement(topElem->fThisElement, fGrammarType);
-    
+
     // If we have a doc handler, tell it about the end tag
     if (fDocHandler)
     {
@@ -1371,7 +1371,7 @@ void IGXMLScanner::scanDocTypeDecl()
             fReaderMgr.pushReader(reader, declDTD);
 
             // Tell it its not in an include section
-            dtdScanner.scanExtSubsetDecl(false);
+            dtdScanner.scanExtSubsetDecl(false, true);
         }
     }
 }
@@ -2135,7 +2135,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                     );
                     errorBeforeElementFound = true;
                 }
-                else if(errorCondition) 
+                else if(errorCondition)
                     laxBeforeElementFound = true;
             }
         }
@@ -2279,7 +2279,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                 , elemDecl->getFullName()
             );
 
-            if(fGrammarType == Grammar::SchemaGrammarType) 
+            if(fGrammarType == Grammar::SchemaGrammarType)
                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
         }
     }
@@ -2362,7 +2362,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                             , prefixBuf.getRawBuffer()
                         );
 
-                        if(fGrammarType == Grammar::SchemaGrammarType) 
+                        if(fGrammarType == Grammar::SchemaGrammarType)
                             ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
 
                     }
@@ -2403,7 +2403,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
             if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))
                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
 
-            if(fGrammarType == Grammar::SchemaGrammarType) 
+            if(fGrammarType == Grammar::SchemaGrammarType)
                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
 
         }
@@ -2487,7 +2487,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                     , elemDecl->getFullName()
                     , elemDecl->getFormattedContentModel()
                 );
-                if(fGrammarType == Grammar::SchemaGrammarType) 
+                if(fGrammarType == Grammar::SchemaGrammarType)
                     ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
 
             }
@@ -2888,7 +2888,7 @@ Grammar* IGXMLScanner::loadDTDGrammar(const InputSource& src,
     dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);
 
     // Tell it its not in an include section
-    dtdScanner.scanExtSubsetDecl(false);
+    dtdScanner.scanExtSubsetDecl(false, true);
 
     if (fValidate) {
         //  validate the DTD scan so far
diff --git a/src/xercesc/validators/DTD/DTDScanner.cpp b/src/xercesc/validators/DTD/DTDScanner.cpp
index 210c57e8f012f4452e969217841d4313e596f2c1..7c242049013160e7c0b416a90a357764a0d86883 100644
--- a/src/xercesc/validators/DTD/DTDScanner.cpp
+++ b/src/xercesc/validators/DTD/DTDScanner.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.23  2003/02/05 22:07:09  tng
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.22  2003/01/20 22:01:38  tng
  * Need to check text decl when expanding PE
  *
@@ -483,7 +486,7 @@ bool DTDScanner::expandPERef( const   bool    scanExternal
             const unsigned int readerNum = fReaderMgr->getCurrentReaderNum();
             try
             {
-                scanExtSubsetDecl(false);
+                scanExtSubsetDecl(false, false);
             }
 
             catch(...)
@@ -2496,7 +2499,7 @@ bool DTDScanner::scanEq()
 //  DTD or an external DTD subset is encountered, and their contents pushed
 //  onto the reader stack. This method will scan that contents.
 //
-void DTDScanner::scanExtSubsetDecl(const bool inIncludeSect)
+void DTDScanner::scanExtSubsetDecl(const bool inIncludeSect, const bool isDTD)
 {
     // Indicate we are in the external subset now
     FlagJanitor<bool> janContentFlag(&fInternalSubset, false);
@@ -2715,7 +2718,7 @@ void DTDScanner::scanExtSubsetDecl(const bool inIncludeSect)
     }
 
     // If we have a doc type handler, tell it the ext subset ends
-    if (fDocTypeHandler)
+    if (fDocTypeHandler && isDTD)
         fDocTypeHandler->endExtSubset();
 }
 
@@ -3146,7 +3149,7 @@ void DTDScanner::scanMarkupDecl(const bool parseTextDecl)
                 //  Recurse back to the ext subset call again, telling it its
                 //  in an include section.
                 //
-                scanExtSubsetDecl(true);
+                scanExtSubsetDecl(true, false);
 
                 //
                 //  And see if we got back to the same level. If not, then its
diff --git a/src/xercesc/validators/DTD/DTDScanner.hpp b/src/xercesc/validators/DTD/DTDScanner.hpp
index 36b79f678b7980db5f58e268cea7cc606b81de58..d05a371a4119d1160ba787f327b8dd98fbf08623 100644
--- a/src/xercesc/validators/DTD/DTDScanner.hpp
+++ b/src/xercesc/validators/DTD/DTDScanner.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.6  2003/02/05 22:07:09  tng
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.5  2002/12/04 02:47:25  knoaman
  * scanner re-organization.
  *
@@ -161,7 +164,7 @@ public:
             DocTypeHandler* const handlerToSet
     );
 
-    void scanExtSubsetDecl(const bool inIncludeSect);
+    void scanExtSubsetDecl(const bool inIncludeSect, const bool isDTD);
     bool scanInternalSubset();
     bool scanId
     (