diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.cpp b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
index 6ee1ba0d32577334f79d0ad9411b0b8e078a6ae2..695d8a0462ae7eec04cc288be51ec534f8198fe5 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.cpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
@@ -576,6 +576,11 @@ int DOMDocumentImpl::indexofQualifiedName(const XMLCh * qName)
 }
 
 
+const XMLCh*     DOMDocumentImpl::getBaseURI() const
+{
+	  return fDocumentURI;
+};
+
 
 DOMRange* DOMDocumentImpl::createRange()
 {
@@ -692,7 +697,6 @@ int             DOMDocumentImpl::changes() const{
            void*            DOMDocumentImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                      {return fNode.setUserData(key, data, handler); };
            void*            DOMDocumentImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMDocumentImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
            short            DOMDocumentImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
            const XMLCh*     DOMDocumentImpl::getTextContent() const                  {return fNode.getTextContent(); };
            void             DOMDocumentImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
@@ -727,7 +731,8 @@ XMLCh * DOMDocumentImpl::cloneString(const XMLCh *src)
 
 const XMLCh *  DOMDocumentImpl::getPooledString(const XMLCh *src)
 {
-    return this->fNamePool->getPooledString(src);
+    if (!src) return 0;
+    else return this->fNamePool->getPooledString(src);
 }
 
 static const int kHeapAllocSize = 0x10000;    // The chunk size to allocate from the
@@ -892,7 +897,8 @@ void DOMDocumentImpl::setVersion(const XMLCh* version){
     fVersion = cloneString(version);
 }
 
-const XMLCh* DOMDocumentImpl::getDocumentURI() const {
+const XMLCh* DOMDocumentImpl::getDocumentURI() const
+{
     return fDocumentURI;
 }
 
diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.hpp b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
index d970d7519a2afca653deb5dbef4e7c4b567d959e..b78a00951a605bb863a49b633ed3ab8d4bddbba0 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.hpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.hpp
@@ -321,11 +321,11 @@ private:
     //  data
     // -----------------------------------------------------------------------
     // New data introduced in DOM Level 3
-    XMLCh*                fActualEncoding;
-    XMLCh*                fEncoding;
+    const XMLCh*          fActualEncoding;
+    const XMLCh*          fEncoding;
     bool                  fStandalone;
-    XMLCh*                fVersion;
-    XMLCh*                fDocumentURI;
+    const XMLCh*          fVersion;
+    const XMLCh*          fDocumentURI;
 
     RefHashTableOf<DOMNodeUserDataTable>* fUserDataTable;
 
diff --git a/src/xercesc/dom/impl/DOMElementImpl.cpp b/src/xercesc/dom/impl/DOMElementImpl.cpp
index 3b7554b1260991631f2d27a91c21aa5f50dcc186..24684a1d0b6d4441367633bc4be96162eb0dd42b 100644
--- a/src/xercesc/dom/impl/DOMElementImpl.cpp
+++ b/src/xercesc/dom/impl/DOMElementImpl.cpp
@@ -63,6 +63,8 @@
 #include <xercesc/dom/DOMAttr.hpp>
 #include <xercesc/dom/DOMDocument.hpp>
 #include <xercesc/dom/DOMException.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xercesc/util/XMLUri.hpp>
 
 #include "DOMAttrMapImpl.hpp"
 #include "DOMDocumentImpl.hpp"
@@ -71,12 +73,10 @@
 #include "DOMCasts.hpp"
 #include "DOMElementNSImpl.hpp"
 
-
 #include "DOMDeepNodeListImpl.hpp"
 #include "DOMDocumentTypeImpl.hpp"
 #include "DOMNamedNodeMapImpl.hpp"
 
-
 class DOMAttr;
 
 DOMElementImpl::DOMElementImpl(DOMDocument *ownerDoc, const XMLCh *eName)
@@ -102,6 +102,7 @@ DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep)
       fDefaultAttributes(0)
 {
     fName = other.fName;
+
     if (deep)
         fParent.cloneChildren(&other);
 
@@ -129,6 +130,7 @@ DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep)
             fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, fDefaultAttributes);
         }
     }
+
 };
 
 
@@ -465,6 +467,35 @@ void DOMElementImpl::release()
     }
 }
 
+const XMLCh* DOMElementImpl::getBaseURI() const
+{
+    const XMLCh* baseURI = fNode.fOwnerNode->getBaseURI();
+    if (fAttributes) {
+        const XMLCh xmlBaseString[] =
+        {
+            chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
+        };
+        DOMNode* attrNode = fAttributes->getNamedItem(xmlBaseString);
+        if (attrNode) {
+            const XMLCh* uri =  attrNode->getNodeValue();
+            if (XMLString::stringLen(uri) != 0 ) {// attribute value is always empty string
+                try {
+                    XMLUri temp(baseURI);
+                    XMLUri temp2(&temp, uri);
+                    uri = ((DOMDocumentImpl *)this->getOwnerDocument())->cloneString(temp2.getUriText());
+                }
+                catch (...){
+                    // REVISIT: what should happen in this case?
+                    return 0;
+                }
+                return uri;
+            }
+        }
+    }
+    return baseURI;
+}
+
+
 
 //
 //   Functions inherited from Node
@@ -477,7 +508,7 @@ void DOMElementImpl::release()
      const XMLCh*           DOMElementImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); };
            DOMNode*         DOMElementImpl::getNextSibling() const                  {return fChild.getNextSibling (); };
      const XMLCh*           DOMElementImpl::getNodeValue() const                    {return fNode.getNodeValue (); };
-           DOMDocument*     DOMElementImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); };
+           DOMDocument*     DOMElementImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; };
      const XMLCh*           DOMElementImpl::getPrefix() const                       {return fNode.getPrefix (); };
            DOMNode*         DOMElementImpl::getParentNode() const                   {return fChild.getParentNode (this); };
            DOMNode*         DOMElementImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); };
@@ -495,7 +526,6 @@ void DOMElementImpl::release()
            void*            DOMElementImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                     {return fNode.setUserData(key, data, handler); };
            void*            DOMElementImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMElementImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
            short            DOMElementImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
            const XMLCh*     DOMElementImpl::getTextContent() const                  {return fNode.getTextContent(); };
            void             DOMElementImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
@@ -508,6 +538,10 @@ void DOMElementImpl::release()
 
 bool DOMElementImpl::isEqualNode(const DOMNode* arg)
 {
+    if (isSameNode(arg)) {
+        return true;
+    }
+
     if (!fNode.isEqualNode(arg)) {
         return false;
     }
diff --git a/src/xercesc/dom/impl/DOMElementNSImpl.cpp b/src/xercesc/dom/impl/DOMElementNSImpl.cpp
index 7aeade4a612103dc8f55ecb5dad3a584d15d531b..2156010ef788be796ccd09f16926c42b780e13ec 100644
--- a/src/xercesc/dom/impl/DOMElementNSImpl.cpp
+++ b/src/xercesc/dom/impl/DOMElementNSImpl.cpp
@@ -62,6 +62,7 @@
 #include "DOMElementNSImpl.hpp"
 #include "DOMDocumentImpl.hpp"
 #include <xercesc/dom/DOMException.hpp>
+#include <xercesc/util/XMLUri.hpp>
 
 DOMElementNSImpl::DOMElementNSImpl(DOMDocument *ownerDoc, const XMLCh *nam) :
     DOMElementImpl(ownerDoc, nam)
@@ -110,6 +111,35 @@ const XMLCh * DOMElementNSImpl::getLocalName() const
     return fLocalName;
 }
 
+const XMLCh* DOMElementNSImpl::getBaseURI() const
+{
+    const XMLCh* baseURI = (fNode.fOwnerNode)->getBaseURI();
+    if (fAttributes) {
+        const XMLCh baseString[] =
+        {
+            chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
+        };
+        DOMNode* attrNode = fAttributes->getNamedItemNS(DOMNodeImpl::getXmlURIString(), baseString);
+        if (attrNode) {
+            const XMLCh* uri =  attrNode->getNodeValue();
+            if (XMLString::stringLen(uri) != 0 ) {// attribute value is always empty string
+                try {
+                    XMLUri temp(baseURI);
+                    XMLUri temp2(&temp, uri);
+                    uri = ((DOMDocumentImpl *)this->getOwnerDocument())->cloneString(temp2.getUriText());
+                }
+                catch (...){
+                    // REVISIT: what should happen in this case?
+                    return 0;
+                }
+                return uri;
+            }
+        }
+    }
+    return baseURI;
+}
+
+
 void DOMElementNSImpl::setPrefix(const XMLCh *prefix)
 {
     const XMLCh * xml      = DOMNodeImpl::getXmlString();
diff --git a/src/xercesc/dom/impl/DOMElementNSImpl.hpp b/src/xercesc/dom/impl/DOMElementNSImpl.hpp
index 27b9f5630b84638b42e78af1a9220a9d3711ef07..576b09d2069c17c9c914a96e8ad8b904e3024a7e 100644
--- a/src/xercesc/dom/impl/DOMElementNSImpl.hpp
+++ b/src/xercesc/dom/impl/DOMElementNSImpl.hpp
@@ -96,6 +96,9 @@ public:
     virtual void         setPrefix(const XMLCh *prefix);
     virtual void         release();
 
+    //Introduced in DOM Level 3
+    virtual const XMLCh *getBaseURI() const;
+
    // helper function for DOM Level 3 renameNode
    virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
    void setName(const XMLCh* namespaceURI, const XMLCh* name);
diff --git a/src/xercesc/dom/impl/DOMEntityImpl.cpp b/src/xercesc/dom/impl/DOMEntityImpl.cpp
index b8356b0b05aa542b9e7654579decc3f5fc513efa..a4ded9ece4cb4448ceadbd0432862c9b7a45f308 100644
--- a/src/xercesc/dom/impl/DOMEntityImpl.cpp
+++ b/src/xercesc/dom/impl/DOMEntityImpl.cpp
@@ -73,7 +73,8 @@ DOMEntityImpl::DOMEntityImpl(DOMDocument *ownerDoc, const XMLCh *eName)
      fActualEncoding(0),
      fEncoding(0),
      fVersion(0),
-     fEntityRefNodeCloned(false)
+     fEntityRefNodeCloned(false),
+     fBaseURI(0)
 {
     fRefEntity  = 0;
     fName        = ((DOMDocumentImpl *)ownerDoc)->getPooledString(eName);
@@ -95,6 +96,7 @@ DOMEntityImpl::DOMEntityImpl(const DOMEntityImpl &other, bool deep)
     fPublicId        = other.fPublicId;
     fSystemId        = other.fSystemId;
     fNotationName    = other.fNotationName;
+    fBaseURI         = other.fBaseURI;
 
     fRefEntity       = other.fRefEntity;
     fNode.setReadOnly(true, true);
@@ -140,6 +142,12 @@ const XMLCh * DOMEntityImpl::getSystemId() const
 };
 
 
+const XMLCh* DOMEntityImpl::getBaseURI() const
+{
+    return fBaseURI;
+}
+
+
 void DOMEntityImpl::setNodeValue(const XMLCh *arg)
 {
     fNode.setNodeValue(arg);
@@ -167,6 +175,11 @@ void DOMEntityImpl::setSystemId(const XMLCh *arg)
 }
 
 
+void DOMEntityImpl::setBaseURI(const XMLCh* baseURI) {
+    fBaseURI = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(baseURI);
+}
+
+
 void   DOMEntityImpl::setEntityRef(DOMEntityReference* other)
 {
     fRefEntity = other;
@@ -248,38 +261,37 @@ void DOMEntityImpl::release()
 //  Functions inherited from Node
 //
 
-           DOMNode*         DOMEntityImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); };
+           DOMNode*         DOMEntityImpl::appendChild(DOMNode *newChild)          {cloneEntityRefTree(); return fParent.appendChild (newChild); };
            DOMNamedNodeMap* DOMEntityImpl::getAttributes() const                   {return fNode.getAttributes (); };
      const XMLCh*           DOMEntityImpl::getLocalName() const                    {return fNode.getLocalName (); };
      const XMLCh*           DOMEntityImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); };
-           DOMNode*         DOMEntityImpl::getNextSibling() const                  {return fNode.getNextSibling (); };
-     const XMLCh*           DOMEntityImpl::getNodeValue() const                    {return fNode.getNodeValue (); };
-           DOMDocument*     DOMEntityImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); };
+           DOMNode*         DOMEntityImpl::getNextSibling() const                  {cloneEntityRefTree(); return fNode.getNextSibling (); };
+     const XMLCh*           DOMEntityImpl::getNodeValue() const                    {cloneEntityRefTree(); return fNode.getNodeValue (); };
+           DOMDocument*     DOMEntityImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; };
      const XMLCh*           DOMEntityImpl::getPrefix() const                       {return fNode.getPrefix (); };
            DOMNode*         DOMEntityImpl::getParentNode() const                   {return fNode.getParentNode (); };
            DOMNode*         DOMEntityImpl::getPreviousSibling() const              {return fNode.getPreviousSibling (); };
            DOMNode*         DOMEntityImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
-                                                                                   {return fParent.insertBefore (newChild, refChild); };
-           void             DOMEntityImpl::normalize()                             {fParent.normalize (); };
-           DOMNode*         DOMEntityImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); };
+                                                                                   {cloneEntityRefTree(); return fParent.insertBefore (newChild, refChild); };
+           void             DOMEntityImpl::normalize()                             {cloneEntityRefTree(); fParent.normalize (); };
+           DOMNode*         DOMEntityImpl::removeChild(DOMNode *oldChild)          {cloneEntityRefTree(); return fParent.removeChild (oldChild); };
            DOMNode*         DOMEntityImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
-                                                                                   {return fParent.replaceChild (newChild, oldChild); };
+                                                                                   {cloneEntityRefTree(); return fParent.replaceChild (newChild, oldChild); };
            bool             DOMEntityImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
                                                                                    {return fNode.isSupported (feature, version); };
            void             DOMEntityImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); };
            bool             DOMEntityImpl::hasAttributes() const                   {return fNode.hasAttributes(); };
            bool             DOMEntityImpl::isSameNode(const DOMNode* other)        {return fNode.isSameNode(other); };
-           bool             DOMEntityImpl::isEqualNode(const DOMNode* arg)         {return fParent.isEqualNode(arg); };
+           bool             DOMEntityImpl::isEqualNode(const DOMNode* arg)         {cloneEntityRefTree(); return fParent.isEqualNode(arg); };
            void*            DOMEntityImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                    {return fNode.setUserData(key, data, handler); };
            void*            DOMEntityImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMEntityImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
-           short            DOMEntityImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
-           const XMLCh*     DOMEntityImpl::getTextContent() const                  {return fNode.getTextContent(); };
-           void             DOMEntityImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
-           const XMLCh*     DOMEntityImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); };
-           bool             DOMEntityImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); };
-           const XMLCh*     DOMEntityImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); };
+           short            DOMEntityImpl::compareTreePosition(DOMNode* other)     {cloneEntityRefTree(); return fNode.compareTreePosition(other); };
+           const XMLCh*     DOMEntityImpl::getTextContent() const                  {cloneEntityRefTree(); return fNode.getTextContent(); };
+           void             DOMEntityImpl::setTextContent(const XMLCh* textContent){cloneEntityRefTree(); fNode.setTextContent(textContent); };
+           const XMLCh*     DOMEntityImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {cloneEntityRefTree(); return fNode.lookupNamespacePrefix(namespaceURI, useDefault); };
+           bool             DOMEntityImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {cloneEntityRefTree(); return fNode.isDefaultNamespace(namespaceURI); };
+           const XMLCh*     DOMEntityImpl::lookupNamespaceURI(const XMLCh* prefix) const  {cloneEntityRefTree(); return fNode.lookupNamespaceURI(prefix); };
            DOMNode*         DOMEntityImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); };
 
 
diff --git a/src/xercesc/dom/impl/DOMEntityImpl.hpp b/src/xercesc/dom/impl/DOMEntityImpl.hpp
index 7f67972534d60ba921df5c561b7b44e95ea7b8fe..a101b5e00493125a4d3ecc274be28748dae31a53 100644
--- a/src/xercesc/dom/impl/DOMEntityImpl.hpp
+++ b/src/xercesc/dom/impl/DOMEntityImpl.hpp
@@ -89,9 +89,10 @@ private:
     DOMEntityReference*	fRefEntity;
 
     // New data introduced in DOM Level 3
-    XMLCh*                fActualEncoding;
-    XMLCh*                fEncoding;
-    XMLCh*                fVersion;
+    const XMLCh*          fActualEncoding;
+    const XMLCh*          fEncoding;
+    const XMLCh*          fVersion;
+    const XMLCh*          fBaseURI;
     bool                  fEntityRefNodeCloned;
     // private helper function
     void	cloneEntityRefTree() const;
@@ -125,6 +126,7 @@ public:
     virtual void                   setEncoding(const XMLCh* encoding);
     virtual const XMLCh*           getVersion() const;
     virtual void                   setVersion(const XMLCh* version);
+    virtual void                   setBaseURI(const XMLCh *arg);
 };
 
 #endif
diff --git a/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp b/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
index 381000c215e2703b5e3a3b5fc2d145e58bb0d3e3..65748414c4e0a1276885cb7662c8826dcc72c43b 100644
--- a/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
+++ b/src/xercesc/dom/impl/DOMEntityReferenceImpl.cpp
@@ -69,7 +69,7 @@
 
 DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
                                          const XMLCh *entityName)
-    : fNode(ownerDoc), fParent(ownerDoc)
+    : fNode(ownerDoc), fParent(ownerDoc), fBaseURI(0)
 {
     fName = ((DOMDocumentImpl *)getOwnerDocument())->getPooledString(entityName);
     // EntityReference behaves as a read-only node, since its contents
@@ -81,9 +81,11 @@ DOMEntityReferenceImpl::DOMEntityReferenceImpl(DOMDocument *ownerDoc,
             if (ownerDoc->getDoctype()->getEntities()) {
                 DOMEntityImpl* entity = (DOMEntityImpl*)ownerDoc->getDoctype()->getEntities()->getNamedItem(entityName);
                 if (entity) {
+                    fBaseURI = entity->getBaseURI();
                     DOMEntityReference* refEntity = entity->getEntityRef();
-                    if (refEntity)
+                    if (refEntity) {
                         fParent.cloneChildren(refEntity);
+                    }
                 }
             }
         }
@@ -99,6 +101,7 @@ DOMEntityReferenceImpl::DOMEntityReferenceImpl(const DOMEntityReferenceImpl &oth
     : fNode(other.fNode), fParent(other.fParent), fChild(other.fChild)
 {
     fName = other.fName;
+    fBaseURI = other.fBaseURI;
     if (deep)
         fParent.cloneChildren(&other);
     fNode.setReadOnly(true, true);
@@ -173,6 +176,12 @@ void DOMEntityReferenceImpl::release()
     }
 }
 
+const XMLCh* DOMEntityReferenceImpl::getBaseURI() const
+{
+    return fBaseURI;
+}
+
+
 
 //
 //   Delegate functions from Node to the appropriate implementation.
@@ -188,7 +197,7 @@ void DOMEntityReferenceImpl::release()
      const XMLCh*           DOMEntityReferenceImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); };
            DOMNode*         DOMEntityReferenceImpl::getNextSibling() const                  {return fChild.getNextSibling (); };
      const XMLCh*           DOMEntityReferenceImpl::getNodeValue() const                    {return fNode.getNodeValue (); };
-           DOMDocument*     DOMEntityReferenceImpl::getOwnerDocument() const                {return fNode.getOwnerDocument (); };
+           DOMDocument*     DOMEntityReferenceImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; };
      const XMLCh*           DOMEntityReferenceImpl::getPrefix() const                       {return fNode.getPrefix (); };
            DOMNode*         DOMEntityReferenceImpl::getParentNode() const                   {return fChild.getParentNode (this); };
            DOMNode*         DOMEntityReferenceImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); };
@@ -208,7 +217,6 @@ void DOMEntityReferenceImpl::release()
            void*            DOMEntityReferenceImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                             {return fNode.setUserData(key, data, handler); };
            void*            DOMEntityReferenceImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMEntityReferenceImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
            short            DOMEntityReferenceImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
            const XMLCh*     DOMEntityReferenceImpl::getTextContent() const                  {return fNode.getTextContent(); };
            void             DOMEntityReferenceImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
diff --git a/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp b/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
index 5328129ddcedd019ad96dee9a7e9e3a0b9875c27..2fbcd0a4a1bfb1072c2440ac4a06bfc17f0ec0af 100644
--- a/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
+++ b/src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp
@@ -85,6 +85,7 @@ private:
     DOMChildNode     fChild;
 
     const XMLCh    *fName;
+    const XMLCh    *fBaseURI;
 
     friend class XercesDOMParser;
 
diff --git a/src/xercesc/dom/impl/DOMNodeImpl.cpp b/src/xercesc/dom/impl/DOMNodeImpl.cpp
index c9154b2d322512253004df140a669a0833d19a4b..cb48090ff7ac822ea84c7cfedda7d14725761cd2 100644
--- a/src/xercesc/dom/impl/DOMNodeImpl.cpp
+++ b/src/xercesc/dom/impl/DOMNodeImpl.cpp
@@ -482,11 +482,9 @@ bool DOMNodeImpl::isEqualNode(const DOMNode* arg)
         return false;
     }
 
-// baseURI not suppported yet
-/*
     if (XMLString::compareString(thisNode->getBaseURI(), arg->getBaseURI())) {
         return false;
-    }*/
+    }
 
     return true;
 }
diff --git a/src/xercesc/dom/impl/DOMNotationImpl.cpp b/src/xercesc/dom/impl/DOMNotationImpl.cpp
index fd4d5fa3d86597ed0d74858258531b5fc4036e18..1a65428dee2b831543687a37a76bf72225ff65c7 100644
--- a/src/xercesc/dom/impl/DOMNotationImpl.cpp
+++ b/src/xercesc/dom/impl/DOMNotationImpl.cpp
@@ -66,10 +66,10 @@
 
 
 DOMNotationImpl::DOMNotationImpl(DOMDocument *ownerDoc, const XMLCh *nName)
-    : fNode(ownerDoc), fPublicId(0), fSystemId(0)
+    : fNode(ownerDoc), fName(0), fPublicId(0), fSystemId(0), fBaseURI(0)
 {
     fNode.setIsLeafNode(true);
-    fName = ((DOMDocumentImpl *)ownerDoc)->cloneString(nName);
+    fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(nName);
 };
 
 DOMNotationImpl::DOMNotationImpl(const DOMNotationImpl &other, bool deep)
@@ -79,6 +79,7 @@ DOMNotationImpl::DOMNotationImpl(const DOMNotationImpl &other, bool deep)
     fName = other.fName;
     fPublicId = other.fPublicId;
     fSystemId = other.fSystemId;
+    fBaseURI = other.fBaseURI;
 };
 
 
@@ -159,6 +160,15 @@ void DOMNotationImpl::release()
     }
 }
 
+void DOMNotationImpl::setBaseURI(const XMLCh* baseURI) {
+    this->fBaseURI = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(baseURI);
+}
+
+const XMLCh* DOMNotationImpl::getBaseURI() const
+{
+    return fBaseURI;
+}
+
 
            DOMNode*         DOMNotationImpl::appendChild(DOMNode *newChild)          {return fNode.appendChild (newChild); };
            DOMNamedNodeMap* DOMNotationImpl::getAttributes() const                   {return fNode.getAttributes (); };
@@ -189,7 +199,6 @@ void DOMNotationImpl::release()
            void*            DOMNotationImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                      {return fNode.setUserData(key, data, handler); };
            void*            DOMNotationImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMNotationImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
            short            DOMNotationImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
            const XMLCh*     DOMNotationImpl::getTextContent() const                  {return fNode.getTextContent(); };
            void             DOMNotationImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
diff --git a/src/xercesc/dom/impl/DOMNotationImpl.hpp b/src/xercesc/dom/impl/DOMNotationImpl.hpp
index a5b2ad27ad81f2828d9ca2605810b9274e56a0a7..dab80a5ef8d40d532418f41b7563c310878ddc33 100644
--- a/src/xercesc/dom/impl/DOMNotationImpl.hpp
+++ b/src/xercesc/dom/impl/DOMNotationImpl.hpp
@@ -83,6 +83,7 @@ public:
     const XMLCh * fName;
     const XMLCh * fPublicId;
     const XMLCh * fSystemId;
+    const XMLCh * fBaseURI;
 
 public:
     DOMNotationImpl(DOMDocument *ownerDoc, const XMLCh *);
@@ -102,16 +103,18 @@ public:
     // was specified, this will be null.
     virtual const XMLCh * getSystemId() const;
 
-
     // NON-DOM: The Public Identifier for this Notation. If no public
-    // identifier was specified, this will be null.  */
+    // identifier was specified, this will be null.
     virtual void setPublicId(const XMLCh *arg);
 
 
     // NON-DOM: The System Identifier for this Notation. If no system
-    // identifier was specified, this will be null.  */
+    // identifier was specified, this will be null.
     virtual void setSystemId(const XMLCh *arg);
 
+    // NON-DOM: set base uri
+    virtual void setBaseURI(const XMLCh *arg);
+
 };
 
 #endif
diff --git a/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp b/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp
index 813bfa659ee30a7878df87525e2092ea5a1bfde4..b879868eadc89581b0007fc504c99b3b54979508 100644
--- a/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp
+++ b/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp
@@ -68,7 +68,7 @@
 DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(DOMDocument *ownerDoc,
                                                      const XMLCh *targt,
                                                      const XMLCh *dat)
-    : fNode(ownerDoc)
+    : fNode(ownerDoc), fBaseURI(0)
 {
     fNode.setIsLeafNode(true);
     this->fTarget = ((DOMDocumentImpl *)ownerDoc)->cloneString(targt);
@@ -84,6 +84,7 @@ DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(
     fNode.setIsLeafNode(true);
     fTarget = other.fTarget;
     fData = other.fData;
+    fBaseURI = other.fBaseURI;
 };
 
 
@@ -177,6 +178,15 @@ void DOMProcessingInstructionImpl::release()
     }
 }
 
+void DOMProcessingInstructionImpl::setBaseURI(const XMLCh* baseURI) {
+    this->fBaseURI = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(baseURI);
+}
+
+const XMLCh* DOMProcessingInstructionImpl::getBaseURI() const
+{
+    return fBaseURI? fBaseURI : fNode.fOwnerNode->getBaseURI();
+}
+
 //
 //    Delegation stubs for inherited functions
 //
@@ -208,7 +218,6 @@ void DOMProcessingInstructionImpl::release()
            void*            DOMProcessingInstructionImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
                                                                                                   {return fNode.setUserData(key, data, handler); };
            void*            DOMProcessingInstructionImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
-           const XMLCh*     DOMProcessingInstructionImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
            short            DOMProcessingInstructionImpl::compareTreePosition(DOMNode* other)     {return fNode.compareTreePosition(other); };
            const XMLCh*     DOMProcessingInstructionImpl::getTextContent() const                  {return fNode.getTextContent(); };
            void             DOMProcessingInstructionImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
diff --git a/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp b/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp
index 5cc46cac32a1072ff95219d5ef668d04e45b7fa3..004c2c6b4786de43431192b939cd878e3bfad3df 100644
--- a/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp
+++ b/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp
@@ -85,6 +85,7 @@ private:
 
     XMLCh       *fTarget;
     XMLCh       *fData;
+    const XMLCh *fBaseURI;
 
 public:
     DOMProcessingInstructionImpl(DOMDocument *ownerDoc,
@@ -100,6 +101,9 @@ public:
     virtual const XMLCh *getData() const;
     virtual const XMLCh *getTarget() const;
     virtual void setData(const XMLCh *arg);
+
+    // NON-DOM: set base uri
+    virtual void setBaseURI(const XMLCh* baseURI);
 };
 
 #endif
diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp
index 058409309cba06cff42910fee7ccb424102cd6cb..0ccf85d11225bb4d92d4e8030becd0642ab5179a 100644
--- a/src/xercesc/parsers/AbstractDOMParser.cpp
+++ b/src/xercesc/parsers/AbstractDOMParser.cpp
@@ -90,9 +90,9 @@
 #include <xercesc/dom/impl/DOMNotationImpl.hpp>
 #include <xercesc/dom/DOMNamedNodeMap.hpp>
 #include <xercesc/dom/DOMProcessingInstruction.hpp>
+#include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
 #include <xercesc/dom/impl/DOMNodeIDMap.hpp>
 
-
 #include <xercesc/validators/common/ContentSpecNode.hpp>
 #include <xercesc/validators/DTD/DTDAttDefList.hpp>
 
@@ -542,6 +542,44 @@ void AbstractDOMParser::endEntityReference(const XMLEntityDecl& entDecl)
                 // append the child of erImpl to currentParent
                 fCurrentNode = kid->cloneNode(true);
                 fCurrentParent->appendChild(fCurrentNode);
+
+                if (erImpl->getBaseURI()) {
+                    /**
+                     * Record baseURI information for the Element (by adding xml:base attribute)
+                     * or for the ProcessingInstruction (by setting a baseURI field)
+                     */
+                    if (fCurrentNode->getNodeType() == DOMNode::ELEMENT_NODE) {
+                        // if an element already has xml:base attribute
+                        // do nothing
+                        const XMLCh baseString[] =
+                        {
+                            chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
+                        };
+                        const XMLCh xmlBaseString[] =
+                        {
+                            chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
+                        };
+
+                        if (fScanner -> getDoNamespaces() && (((DOMElement*)fCurrentNode)->getAttributeNodeNS(DOMNodeImpl::getXmlURIString(), baseString) != 0)) {
+                            return;
+                        } else if (((DOMElement*)fCurrentNode)->getAttributeNode(xmlBaseString) != 0) {
+                            return;
+                        }
+
+                        // retrive the baseURI from the entity decl
+                        const XMLCh* baseURI = erImpl->getBaseURI();
+                        if (baseURI != 0 && XMLString::compareString(baseURI,fDocument->getDocumentURI())) {
+                            if (fScanner -> getDoNamespaces()) {
+                                ((DOMElement*)fCurrentNode)->setAttributeNS(DOMNodeImpl::getXmlURIString(), baseString, baseURI);
+                            } else {
+                                ((DOMElement*)fCurrentNode)->setAttribute(xmlBaseString, baseURI);
+                            }
+                        }
+                    }
+                    else if (fCurrentNode->getNodeType() == DOMNode::PROCESSING_INSTRUCTION_NODE) {
+                        ((DOMProcessingInstructionImpl*)fCurrentNode)->setBaseURI(erImpl->getBaseURI());
+                    }
+                }
             }
 
             next = kid->getNextSibling();
@@ -619,7 +657,14 @@ void AbstractDOMParser::startDocument()
     // set DOM error checking off
     fDocument->setErrorChecking(false);
 
-    fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
+    const XMLCh* systemId = fScanner->getLocator()->getSystemId();
+    if (systemId) {
+        XMLBufBid bbURI(&fBufMgr);
+        XMLBuffer& bufURI = bbURI.getBuffer();
+        XMLString::fixURI(systemId, bufURI);
+
+        fDocument->setDocumentURI(bufURI.getRawBuffer());
+    }
     fDocument->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
 }
 
@@ -1179,8 +1224,9 @@ void AbstractDOMParser::endAttList
 void AbstractDOMParser::endIntSubset()
 {
     fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
-    fBufMgr.releaseBuffer(fInternalSubset);
-    fDocumentType->intSubsetReading = false;
+    // the buffer shouldn't be released as it is reused in the next parse
+    // fBufMgr.releaseBuffer(fInternalSubset);
+    fDocumentType->fIntSubsetReading = false;
 }
 
 void AbstractDOMParser::endExtSubset()
@@ -1199,6 +1245,14 @@ void AbstractDOMParser::entityDecl
     entity->setPublicId(entityDecl.getPublicId());
     entity->setSystemId(entityDecl.getSystemId());
     entity->setNotationName(entityDecl.getNotationName());
+    if (entityDecl.getBaseURI())
+    {
+        XMLBufBid bbURI(&fBufMgr);
+        XMLBuffer& bufURI = bbURI.getBuffer();
+        XMLString::fixURI(entityDecl.getBaseURI(), bufURI);
+
+        entity->setBaseURI(bufURI.getRawBuffer());
+    }
 
     DOMEntityImpl *previousDef = (DOMEntityImpl *)
 	    fDocumentType->getEntities()->setNamedItem( entity );
@@ -1269,6 +1323,14 @@ void AbstractDOMParser::notationDecl
     DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
     notation->setPublicId(notDecl.getPublicId());
     notation->setSystemId(notDecl.getSystemId());
+    if (notDecl.getBaseURI())
+    {
+        XMLBufBid bbURI(&fBufMgr);
+        XMLBuffer& bufURI = bbURI.getBuffer();
+        XMLString::fixURI(notDecl.getBaseURI(), bufURI);
+
+        notation->setBaseURI(bufURI.getRawBuffer());
+    }
 
     DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
     if (rem)
@@ -1324,7 +1386,7 @@ void AbstractDOMParser::startAttList
 
 void AbstractDOMParser::startIntSubset()
 {
-	fDocumentType->intSubsetReading = true;
+	fDocumentType->fIntSubsetReading = true;
 }
 
 void AbstractDOMParser::startExtSubset()
@@ -1342,3 +1404,4 @@ void AbstractDOMParser::TextDecl
         fCurrentEntity->setEncoding(encodingStr);
     }
 }
+