diff --git a/src/xercesc/dom/deprecated/DOMParser.cpp b/src/xercesc/dom/deprecated/DOMParser.cpp
index c0d1d4ee0996a89056f43667d86b2e41f25bdf9f..7255e1cecbbb100698060330f91428cc1cd55db4 100644
--- a/src/xercesc/dom/deprecated/DOMParser.cpp
+++ b/src/xercesc/dom/deprecated/DOMParser.cpp
@@ -961,6 +961,7 @@ void DOMParser::doctypeDecl
     , const XMLCh* const    publicId
     , const XMLCh* const    systemId
     , const bool            hasIntSubset
+    , const bool            hasExtSubset
 )
 {
 	DOM_DocumentType dt;
diff --git a/src/xercesc/dom/deprecated/DOMParser.hpp b/src/xercesc/dom/deprecated/DOMParser.hpp
index ec192f2fdd9dd650e6005ec312cf99a43da3b932..cce6b4640a660d4c4aa6f19bf2738a0149e1e4f3 100644
--- a/src/xercesc/dom/deprecated/DOMParser.hpp
+++ b/src/xercesc/dom/deprecated/DOMParser.hpp
@@ -1501,6 +1501,7 @@ public :
         , const XMLCh* const    publicId
         , const XMLCh* const    systemId
         , const bool            hasIntSubset
+        , const bool            hasExtSubset = false
     );
 
     virtual void doctypePI
diff --git a/src/xercesc/internal/XMLScanner.cpp b/src/xercesc/internal/XMLScanner.cpp
index ca545701683606b4bf95dcedb779dd52b5cd58dc..30ec9f2280dc8ab2f630f99fa3d15776e44fda23 100644
--- a/src/xercesc/internal/XMLScanner.cpp
+++ b/src/xercesc/internal/XMLScanner.cpp
@@ -2457,7 +2457,7 @@ void XMLScanner::scanDocTypeDecl()
     //  call the doctype event.
     //
     if (fDocTypeHandler)
-        fDocTypeHandler->doctypeDecl(*rootDecl, pubId, sysId, hasIntSubset);
+        fDocTypeHandler->doctypeDecl(*rootDecl, pubId, sysId, hasIntSubset, hasExtSubset);
 
     //
     //  Ok, if we had an internal subset, we are just past the [ character
@@ -4531,7 +4531,7 @@ Grammar* XMLScanner::loadDTDGrammar(const InputSource& src,
         rootDecl->setExternalElemDeclaration(true);
         Janitor<DTDElementDecl> janSrc(rootDecl);
 
-        fDocTypeHandler->doctypeDecl(*rootDecl, src.getPublicId(), src.getSystemId(), false);
+        fDocTypeHandler->doctypeDecl(*rootDecl, src.getPublicId(), src.getSystemId(), false, true);
     }
 
     // Create DTDScanner
diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp
index 65ab0a5b022f4c6d6bfc252696f69995038bd57e..2bedf856748cdf75ffe713b46be9a9d352a87f71 100644
--- a/src/xercesc/parsers/AbstractDOMParser.cpp
+++ b/src/xercesc/parsers/AbstractDOMParser.cpp
@@ -978,6 +978,7 @@ void AbstractDOMParser::doctypeDecl
     , const XMLCh* const    publicId
     , const XMLCh* const    systemId
     , const bool            hasIntSubset
+    , const bool            hasExtSubset
 )
 {
     fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
diff --git a/src/xercesc/parsers/AbstractDOMParser.hpp b/src/xercesc/parsers/AbstractDOMParser.hpp
index 08046b303e962ae643c4ae9d177d4e51b81f392d..4f2f8d038439059035acb1762c9e831cc8db290e 100644
--- a/src/xercesc/parsers/AbstractDOMParser.hpp
+++ b/src/xercesc/parsers/AbstractDOMParser.hpp
@@ -1063,6 +1063,7 @@ public :
         , const XMLCh* const    publicId
         , const XMLCh* const    systemId
         , const bool            hasIntSubset
+        , const bool            hasExtSubset = false
     );
 
     virtual void doctypePI
diff --git a/src/xercesc/parsers/SAX2XMLReaderImpl.cpp b/src/xercesc/parsers/SAX2XMLReaderImpl.cpp
index 2ffb050248801e113fb8a0659b1dee0e13be6616..3d09515822ee2db82ee4c34efa6ac8b423e80141 100644
--- a/src/xercesc/parsers/SAX2XMLReaderImpl.cpp
+++ b/src/xercesc/parsers/SAX2XMLReaderImpl.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2002/08/14 15:20:38  knoaman
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.9  2002/07/11 18:27:20  knoaman
  * Grammar caching/preparsing - initial implementation.
  *
@@ -1055,12 +1058,15 @@ void SAX2XMLReaderImpl::doctypeComment(const XMLCh* const commentText)
 void SAX2XMLReaderImpl::doctypeDecl(const   DTDElementDecl& elemDecl
                             , const XMLCh* const    publicId
                             , const XMLCh* const    systemId
-                            , const bool            hasIntSubset)
+                            , const bool            hasIntSubset
+                            , const bool            hasExtSubset)
 {
-   // Call the installed LexicalHandler.
-   if (fLexicalHandler)
+    // Call the installed LexicalHandler.
+    if (fLexicalHandler && (hasIntSubset || hasExtSubset))
         fLexicalHandler->startDTD(elemDecl.getFullName(), publicId, systemId);
 
+    fHasExternalSubset = hasExtSubset;
+
     // Unused by SAX DTDHandler interface at this time
 }
 
@@ -1214,8 +1220,6 @@ void SAX2XMLReaderImpl::startIntSubset()
 
 void SAX2XMLReaderImpl::startExtSubset()
 {
-    fHasExternalSubset = true;
-
     if (fLexicalHandler)
         fLexicalHandler->startEntity(gDTDEntityStr);
 }
diff --git a/src/xercesc/parsers/SAX2XMLReaderImpl.hpp b/src/xercesc/parsers/SAX2XMLReaderImpl.hpp
index 060535ccdac21875231a29ccb31300f4ec9e434f..9c7cb7833f08efbb61fb9293ac675e4eebb8b84a 100644
--- a/src/xercesc/parsers/SAX2XMLReaderImpl.hpp
+++ b/src/xercesc/parsers/SAX2XMLReaderImpl.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.13  2002/08/14 15:20:38  knoaman
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.12  2002/07/11 18:27:04  knoaman
  * Grammar caching/preparsing - initial implementation.
  *
@@ -1433,6 +1436,8 @@ public :
       *                 system id of the DTD file.
       * @param hasIntSubset A flag indicating if this XML file contains any
       *                     internal subset.
+      * @param hasExtSubset A flag indicating if this XML file contains any
+      *                     external subset. Default is false.
       */
     virtual void doctypeDecl
     (
@@ -1440,6 +1445,7 @@ public :
         , const XMLCh* const    publicId
         , const XMLCh* const    systemId
         , const bool            hasIntSubset
+        , const bool            hasExtSubset = false
     );
 
     /**
diff --git a/src/xercesc/parsers/SAXParser.cpp b/src/xercesc/parsers/SAXParser.cpp
index a349dde06c5e8ee0286044500a2284d22549c681..9e8da44a42335f40c28c9f0ce8a1f9cf1aad77c1 100644
--- a/src/xercesc/parsers/SAXParser.cpp
+++ b/src/xercesc/parsers/SAXParser.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.8  2002/08/14 15:20:38  knoaman
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.7  2002/07/11 18:27:04  knoaman
  * Grammar caching/preparsing - initial implementation.
  *
@@ -943,7 +946,8 @@ void SAXParser::doctypeComment(const XMLCh* const)
 void SAXParser::doctypeDecl(const   DTDElementDecl& elemDecl
                             , const XMLCh* const    publicId
                             , const XMLCh* const    systemId
-                            , const bool            hasIntSubset)
+                            , const bool            hasIntSubset
+                            , const bool            hasExtSubset)
 {
     // Unused by SAX DTDHandler interface at this time
 }
diff --git a/src/xercesc/parsers/SAXParser.hpp b/src/xercesc/parsers/SAXParser.hpp
index b7910ef3004322c15fc77d1012d1900786a56c02..ec1bf8f22eb8bbb3472d758b02c164b0cdda9b28 100644
--- a/src/xercesc/parsers/SAXParser.hpp
+++ b/src/xercesc/parsers/SAXParser.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.13  2002/08/14 15:20:38  knoaman
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
  * Revision 1.12  2002/07/11 18:27:03  knoaman
  * Grammar caching/preparsing - initial implementation.
  *
@@ -1547,6 +1550,8 @@ public :
       *                 system id of the DTD file.
       * @param hasIntSubset A flag indicating if this XML file contains any
       *                     internal subset.
+      * @param hasExtSubset A flag indicating if this XML file contains any
+      *                     external subset. Default is false.
       */
     virtual void doctypeDecl
     (
@@ -1554,6 +1559,7 @@ public :
         , const XMLCh* const    publicId
         , const XMLCh* const    systemId
         , const bool            hasIntSubset
+        , const bool            hasExtSubset = false
     );
 
     /**
diff --git a/src/xercesc/validators/DTD/DocTypeHandler.hpp b/src/xercesc/validators/DTD/DocTypeHandler.hpp
index 72dba627539e5539f44990c0e30d742f562ae032..ede4202fc8621047d84d52ca379390f598678e6c 100644
--- a/src/xercesc/validators/DTD/DocTypeHandler.hpp
+++ b/src/xercesc/validators/DTD/DocTypeHandler.hpp
@@ -56,8 +56,11 @@
 
 /*
  * $Log$
- * Revision 1.1  2002/02/01 22:22:43  peiyongz
- * Initial revision
+ * Revision 1.2  2002/08/14 15:20:38  knoaman
+ * [Bug 3111] Problem with LexicalHandler::startDTD() and LexicalHandler::endDTD().
+ *
+ * Revision 1.1.1.1  2002/02/01 22:22:43  peiyongz
+ * sane_include
  *
  * Revision 1.5  2001/06/19 16:43:46  tng
  * Correct description of DocTypeHandler
@@ -134,6 +137,7 @@ public:
         , const XMLCh* const    publicId
         , const XMLCh* const    systemId
         , const bool            hasIntSubset
+        , const bool            hasExtSubset = false
     ) = 0;
 
     virtual void doctypePI