diff --git a/src/xercesc/idom/IDAttrNSImpl.cpp b/src/xercesc/idom/IDAttrNSImpl.cpp
index f36f97c0e6a9a69e18a2ee0c6e79b0c9466fb78b..1ffcdfb2c655c2ba8798269e5fac54e8b72b4586 100644
--- a/src/xercesc/idom/IDAttrNSImpl.cpp
+++ b/src/xercesc/idom/IDAttrNSImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -116,7 +116,7 @@ IDAttrImpl(ownerDoc, qualifiedName)
 
     const XMLCh * URI = xmlnsAlone ?
                 xmlnsURI : IDNodeImpl::mapPrefix(fPrefix, namespaceURI, IDOM_Node::ATTRIBUTE_NODE);
-    this -> fNamespaceURI = URI == 0 ? XMLUni::fgZeroLenString : ((IDDocumentImpl *)ownerDoc)->getPooledString(URI);
+    this -> fNamespaceURI = (URI == 0) ? 0 : ((IDDocumentImpl *)ownerDoc)->getPooledString(URI);
 };
 
 IDAttrNSImpl::IDAttrNSImpl(const IDAttrNSImpl &other, bool deep) :
@@ -157,7 +157,7 @@ void IDAttrNSImpl::setPrefix(const XMLCh *prefix)
     if (fNode.isReadOnly())
         throw IDOM_DOMException(IDOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
         0);
-    if (fNamespaceURI == 0 || XMLString::compareString(fLocalName, xmlns) == 0)
+    if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull || XMLString::compareString(fLocalName, xmlns) == 0)
         throw IDOM_DOMException(IDOM_DOMException::NAMESPACE_ERR, 0);
 
     if (prefix != 0 && !IDDocumentImpl::isXMLName(prefix))
diff --git a/src/xercesc/idom/IDDocumentImpl.cpp b/src/xercesc/idom/IDDocumentImpl.cpp
index 3f04bb459b2319053bbbe7353fdad30d16f0ca37..0b87280816e374289195e1c6f837b749421c984d 100644
--- a/src/xercesc/idom/IDDocumentImpl.cpp
+++ b/src/xercesc/idom/IDDocumentImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -150,10 +150,15 @@ IDDocumentImpl::IDDocumentImpl(const XMLCh *fNamespaceURI,
       fChanges(0),
       fNodeListPool(0)
 {
-
-   fNamePool    = new (this) IDStringPool(257, this);
-	setDocumentType(doctype);
-   appendChild(createElementNS(fNamespaceURI, qualifiedName));  //root element
+    fNamePool    = new (this) IDStringPool(257, this);
+    try {
+        setDocumentType(doctype);
+        appendChild(createElementNS(fNamespaceURI, qualifiedName));  //root element
+    }
+    catch (...) {
+        this->deleteHeap();
+        throw;
+    }
 }
 
 void IDDocumentImpl::setDocumentType(IDOM_DocumentType *doctype)
@@ -181,6 +186,20 @@ void IDDocumentImpl::setDocumentType(IDOM_DocumentType *doctype)
 
 IDDocumentImpl::~IDDocumentImpl()
 {
+    //  Clean up the fNodeListPool
+    if (fNodeListPool)
+        fNodeListPool->cleanup();
+
+    //  Clean up the RefVector
+    if (fIterators)
+        fIterators->cleanup();
+
+    if (fTreeWalkers)
+        fTreeWalkers->cleanup();
+
+    if (fRanges)
+        fRanges->cleanup();
+
     //  Delete the heap for this document.  This uncerimoniously yanks the storage
     //      out from under all of the nodes in the document.  Destructors are NOT called.
     this->deleteHeap();
@@ -665,23 +684,21 @@ IDOM_Element *IDDocumentImpl::getElementById(const XMLCh *elementId) const
 
 
 //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".
+//Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd" or "abcd:".
 int IDDocumentImpl::indexofQualifiedName(const XMLCh * qName)
 {
-    //Check if s = prefix:localName, name or malformed
-    int firstOccurence = XMLString::indexOf(qName, chColon);
-    int lastOccurence  = XMLString::lastIndexOf(qName, chColon);
-
-    if (firstOccurence != lastOccurence || firstOccurence == 0) {
-        // Error.  More than two ':'s, or ':' is first char.
-        return -1;
+    int qNameLen = XMLString::stringLen(qName);
+    int index = -1, count = 0;
+    for (int i = 0; i < qNameLen; ++i) {
+        if (qName[i] == chColon) {
+            index = i;
+            ++count;	//number of ':' found
+        }
     }
 
-    if (firstOccurence == -1) {
-        //  No colons in the name
-        firstOccurence = 0;
-    }
-    return firstOccurence;
+    if (qNameLen == 0 || count > 1 || index == 0 || index == qNameLen-1)
+        return -1;
+    return count == 0 ? 0 : index;
 }
 
 
@@ -831,9 +848,10 @@ int             IDDocumentImpl::changes() const{
            void                IDDocumentImpl::normalize()                             {fNode.normalize (); };
            IDOM_Node          *IDDocumentImpl::replaceChild(IDOM_Node *newChild, IDOM_Node *oldChild)
                                                                             {return fParent.replaceChild (newChild, oldChild); };
-           bool                IDDocumentImpl::supports(const XMLCh *feature, const XMLCh *version) const
-                                                                            {return fNode.supports (feature, version); };
+           bool                IDDocumentImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
+                                                                            {return fNode.isSupported (feature, version); };
            void                IDDocumentImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); };
+           bool                IDDocumentImpl::hasAttributes() const                   {return fNode.hasAttributes(); };
 
 
 //-----------------------------------------------------------------------
diff --git a/src/xercesc/idom/IDDocumentTypeImpl.cpp b/src/xercesc/idom/IDDocumentTypeImpl.cpp
index d7ce4cd881c3d9f406e35b977862aaab3c267fd7..4921c8a16f61d811663fad482e4b78858fbbf9ba 100644
--- a/src/xercesc/idom/IDDocumentTypeImpl.cpp
+++ b/src/xercesc/idom/IDDocumentTypeImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,9 @@ IDDocumentTypeImpl::IDDocumentTypeImpl(IDOM_Document *ownerDoc,
     }
     else {
         name = XMLString::replicate(dtName);
+        entities = new IDNamedNodeMapImpl(this);
+        notations= new IDNamedNodeMapImpl(this);
+        elements = new IDNamedNodeMapImpl(this);
     }
 };
 
@@ -123,6 +126,9 @@ IDDocumentTypeImpl::IDDocumentTypeImpl(IDOM_Document *ownerDoc,
         publicId = XMLString::replicate(pubId);
         systemId = XMLString::replicate(sysId);
         name = XMLString::replicate(qualifiedName);
+        entities = new IDNamedNodeMapImpl(this);
+        notations= new IDNamedNodeMapImpl(this);
+        elements = new IDNamedNodeMapImpl(this);
     }
 };
 
@@ -144,10 +150,6 @@ IDDocumentTypeImpl::IDDocumentTypeImpl(const IDDocumentTypeImpl &other, bool dee
         name = other.name;
         if (deep)
             fParent.cloneChildren(&other);
-        entities = ((IDNamedNodeMapImpl *)other.entities)->cloneMap(this);
-        notations= ((IDNamedNodeMapImpl *)other.notations)->cloneMap(this);
-        elements = ((IDNamedNodeMapImpl *)other.notations)->cloneMap(this);
-
         //DOM Level 2
         publicId		= other.publicId;
         systemId		= other.systemId;
@@ -159,6 +161,11 @@ IDDocumentTypeImpl::IDDocumentTypeImpl(const IDDocumentTypeImpl &other, bool dee
         systemId = XMLString::replicate(other.systemId);
         internalSubset = XMLString::replicate(other.internalSubset);
     }
+
+    entities = ((IDNamedNodeMapImpl *)other.entities)->cloneMap(this);
+    notations= ((IDNamedNodeMapImpl *)other.notations)->cloneMap(this);
+    elements = ((IDNamedNodeMapImpl *)other.elements)->cloneMap(this);
+
 }
 
 
@@ -176,6 +183,10 @@ IDDocumentTypeImpl::~IDDocumentTypeImpl()
 
         temp = (XMLCh*) internalSubset;
         delete [] temp;
+
+        delete entities;
+        delete notations;
+        delete elements;
     }
 }
 
@@ -217,12 +228,21 @@ void IDDocumentTypeImpl::setOwnerDocument(IDOM_Document *doc) {
             name = docImpl->cloneString(name);
             delete [] temp;
 
-            entities = new (docImpl) IDNamedNodeMapImpl(this);
-            notations= new (docImpl) IDNamedNodeMapImpl(this);
-            elements = new (docImpl) IDNamedNodeMapImpl(this);
-
             fNode.setOwnerDocument(doc);
             fParent.setOwnerDocument(doc);
+
+            IDOM_NamedNodeMap* entitiesTemp = ((IDNamedNodeMapImpl *)entities)->cloneMap(this);
+            IDOM_NamedNodeMap* notationsTemp = ((IDNamedNodeMapImpl *)notations)->cloneMap(this);
+            IDOM_NamedNodeMap* elementsTemp = ((IDNamedNodeMapImpl *)elements)->cloneMap(this);
+
+            delete entities;
+            delete notations;
+            delete elements;
+
+            entities = entitiesTemp;
+            notations = notationsTemp;
+            elements = elementsTemp;
+
         }
     }
 }
@@ -374,7 +394,8 @@ void        IDDocumentTypeImpl::setInternalSubset(const XMLCh *value)
            IDOM_Node          *IDDocumentTypeImpl::removeChild(IDOM_Node *oldChild)        {return fParent.removeChild (oldChild); };
            IDOM_Node          *IDDocumentTypeImpl::replaceChild(IDOM_Node *newChild, IDOM_Node *oldChild)
                                                                             {return fParent.replaceChild (newChild, oldChild); };
-           bool                IDDocumentTypeImpl::supports(const XMLCh *feature, const XMLCh *version) const
-                                                                            {return fNode.supports (feature, version); };
+           bool                IDDocumentTypeImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
+                                                                            {return fNode.isSupported (feature, version); };
            void                IDDocumentTypeImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); };
+           bool                IDDocumentTypeImpl::hasAttributes() const                   {return fNode.hasAttributes(); };
 
diff --git a/src/xercesc/idom/IDElementNSImpl.cpp b/src/xercesc/idom/IDElementNSImpl.cpp
index 23482ca5242dec7b05bfd4f1c2859df8852f3219..8524585e035ad2d979f4c2f375d9e415be42444f 100644
--- a/src/xercesc/idom/IDElementNSImpl.cpp
+++ b/src/xercesc/idom/IDElementNSImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,7 +104,7 @@ IDElementNSImpl::IDElementNSImpl(IDOM_Document *ownerDoc,
     }
 
     const XMLCh * URI = IDNodeImpl::mapPrefix(fPrefix, namespaceURI, IDOM_Node::ELEMENT_NODE);
-    this -> fNamespaceURI = URI == 0 ? XMLUni::fgZeroLenString : ((IDDocumentImpl *)ownerDoc)->getPooledString(URI);
+    this -> fNamespaceURI = (URI == 0) ? 0 : ((IDDocumentImpl *)ownerDoc)->getPooledString(URI);
 };
 
 IDElementNSImpl::IDElementNSImpl(const IDElementNSImpl &other, bool deep) :
@@ -146,7 +146,7 @@ void IDElementNSImpl::setPrefix(const XMLCh *prefix)
     if(prefix != 0 && !IDDocumentImpl::isXMLName(prefix))
         throw IDOM_DOMException(IDOM_DOMException::INVALID_CHARACTER_ERR,0);
 
-    if (fNamespaceURI == 0)
+    if (fNamespaceURI == 0 || fNamespaceURI[0] == chNull)
         throw IDOM_DOMException(IDOM_DOMException::NAMESPACE_ERR, 0);
 
     if (prefix == 0 || *prefix == 0) {
diff --git a/src/xercesc/idom/IDNodeImpl.cpp b/src/xercesc/idom/IDNodeImpl.cpp
index d22079bd36c6a177c5aa468371f34ee1fda168c5..4a0287dcb612bde12d48662dbb6617026525ee0d 100644
--- a/src/xercesc/idom/IDNodeImpl.cpp
+++ b/src/xercesc/idom/IDNodeImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,8 @@
 #include "IDDOMImplementation.hpp"
 
 #include <xercesc/util/XMLUniDefs.hpp>
+#include <xercesc/util/XMLRegisterCleanup.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
 #include <stdio.h>
 #include <assert.h>
 
@@ -86,7 +88,19 @@ const unsigned short IDNodeImpl::USERDATA     = 0x1<<9;
 const unsigned short IDNodeImpl::LEAFNODETYPE = 0x1<<10;
 const unsigned short IDNodeImpl::CHILDNODE    = 0x1<<11;
 
+// -----------------------------------------------------------------------
+//  Reset the singleton gEmptyNodeList
+// -----------------------------------------------------------------------
+static IDNodeListImpl *gEmptyNodeList;  // make a singleton empty node list
+static void reinitEmptyNodeList()
+{
+	delete gEmptyNodeList;
+	gEmptyNodeList = 0;
+}
 
+// -----------------------------------------------------------------------
+//  IDNodeImpl Functions
+// -----------------------------------------------------------------------
 IDNodeImpl::IDNodeImpl(IDOM_Node *ownerNode)
 {
     this->flags = 0;
@@ -133,9 +147,23 @@ IDOM_NamedNodeMap * IDNodeImpl::getAttributes() const {
 };
 
 
-static IDOM_NodeList *gEmptyNodeList;  // idom_revisit - make a singleton empty node list somewhere, shomehow.
 IDOM_NodeList *IDNodeImpl::getChildNodes() const {
-    return gEmptyNodeList;       // overridden in ParentNode
+	static XMLRegisterCleanup emptyNodeListCleanup;
+
+    if (gEmptyNodeList == 0)
+    {
+        IDOM_NodeList *t = new IDNodeListImpl(0);
+        if (XMLPlatformUtils::compareAndSwap((void **)&gEmptyNodeList, t, 0) != 0)
+        {
+            delete t;
+        }
+        else
+        {
+            emptyNodeListCleanup.registerCleanup(reinitEmptyNodeList);
+        }
+
+    }
+    return (IDOM_NodeList *)gEmptyNodeList;
 };
 
 
@@ -288,7 +316,7 @@ void IDNodeImpl::normalize()
 };
 
 
-bool IDNodeImpl::supports(const XMLCh *feature, const XMLCh *version) const
+bool IDNodeImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
 {
     return IDOM_DOMImplementation::getImplementation()->hasFeature(feature, version);
 }
@@ -315,6 +343,11 @@ void IDNodeImpl::setPrefix(const XMLCh *fPrefix)
 }
 
 
+bool IDNodeImpl::hasAttributes() const {
+    return 0;                   // overridden in ElementImpl
+};
+
+
 
 
 
diff --git a/src/xercesc/idom/IDNodeListImpl.cpp b/src/xercesc/idom/IDNodeListImpl.cpp
index 79bff69abea1a0f9ca424a963809329182a9fe46..493bfd2f185cb4a1d2719e2d6380b040b72c7be1 100644
--- a/src/xercesc/idom/IDNodeListImpl.cpp
+++ b/src/xercesc/idom/IDNodeListImpl.cpp
@@ -1,7 +1,7 @@
 /*
  * The Apache Software License, Version 1.1
  *
- * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  * reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -56,8 +56,17 @@
 
 /*
  * $Log$
- * Revision 1.1  2002/02/01 22:21:55  peiyongz
- * Initial revision
+ * Revision 1.2  2002/02/04 21:50:17  tng
+ * Add DOM 2 Level missing functions:
+ *   1. NodeIterator::getRoot
+ *   2. TreeWalker::getRoot
+ *   3. Element::hasAttribute
+ *   4. Element::hasAttributeNS
+ *   5. Node::hasAttributes
+ *   6. Node::isSupported
+ *
+ * Revision 1.1.1.1  2002/02/01 22:21:55  peiyongz
+ * sane_include
  *
  * Revision 1.3  2001/06/04 14:55:34  tng
  * IDOM: Add IRange and IDeepNodeList Support.
@@ -93,22 +102,27 @@ IDNodeListImpl:: ~IDNodeListImpl()
 
 unsigned int IDNodeListImpl::getLength(){
     unsigned int count = 0;
-    IDOM_Node *node = castToParentImpl(fNode)->fFirstChild;
-    while(node != 0)
-    {
-        ++count;
-        node = castToChildImpl(node)->nextSibling;
+    if (fNode) {
+        IDOM_Node *node = castToParentImpl(fNode)->fFirstChild;
+        while(node != 0){
+            ++count;
+            node = castToChildImpl(node)->nextSibling;
+        }
     }
+
     return count;
 };
 
 
 
 IDOM_Node *IDNodeListImpl::item(unsigned int index){
-    IDOM_Node *node = castToParentImpl(fNode)->fFirstChild;
-    for(unsigned int i=0; i<index && node!=0; ++i)
-        node = castToChildImpl(node)->nextSibling;
-    return node;
+    if (fNode) {
+        IDOM_Node *node = castToParentImpl(fNode)->fFirstChild;
+        for(unsigned int i=0; i<index && node!=0; ++i)
+            node = castToChildImpl(node)->nextSibling;
+        return node;
+    }
+    return 0;
 };