diff --git a/doc/releases.xml b/doc/releases.xml
index 192ccb88c59e8e6fb0dc9b4d4b99aea20eb5e4cd..09221812396d575bb2206579b1c97abf51af3845 100644
--- a/doc/releases.xml
+++ b/doc/releases.xml
@@ -25,6 +25,13 @@
         <td>Description</td>
     </tr>
 
+    <tr>
+        <td>2002-07-19</td>
+        <td>Tinny Ng</td>
+        <td>[Bug 10968] Default attributes from Schema not restored by removeAttribute.
+        </td>
+    </tr>
+
     <tr>
         <td>2002-07-18</td>
         <td>Khaled Noaman</td>
diff --git a/src/xercesc/dom/impl/DOMElementImpl.cpp b/src/xercesc/dom/impl/DOMElementImpl.cpp
index 8aa96b4d99a6e6c505bb7c16d535a33b823c3255..cb19f8c8f41d5e4df5848d5675c2ee85cba7c232 100644
--- a/src/xercesc/dom/impl/DOMElementImpl.cpp
+++ b/src/xercesc/dom/impl/DOMElementImpl.cpp
@@ -80,20 +80,26 @@
 class DOMAttr;
 
 DOMElementImpl::DOMElementImpl(DOMDocument *ownerDoc, const XMLCh *eName)
-    : fNode(ownerDoc), fParent(ownerDoc), fAttributes(0)
+    : fNode(ownerDoc), fParent(ownerDoc), fAttributes(0), fDefaultAttributes(0)
 {
     DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
     fName = docImpl->fNamePool->getPooledString(eName);
     setupDefaultAttributes();
-    if (!fAttributes)
+    if (!fDefaultAttributes) {
+        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
         fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
+    }
+    else {
+        fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, fDefaultAttributes);
+    }
 };
 
 
 DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep)
     : fNode(other.getOwnerDocument()),
       fParent(other.getOwnerDocument()),
-      fAttributes(0)
+      fAttributes(0),
+      fDefaultAttributes(0)
 {
     fName = other.fName;
     if (deep)
@@ -104,10 +110,24 @@ DOMElementImpl::DOMElementImpl(const DOMElementImpl &other, bool deep)
         fAttributes = ((DOMAttrMapImpl *)other.getAttributes())->cloneAttrMap(this);
     }
 
-    if (!fAttributes) {
+    if (other.getDefaultAttributes())
+    {
+        fDefaultAttributes = ((DOMAttrMapImpl *)other.getDefaultAttributes())->cloneAttrMap(this);
+    }
+
+    if (!fDefaultAttributes)
         setupDefaultAttributes();
-        if (!fAttributes)
+
+    if (!fDefaultAttributes)
+        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
+
+    if (!fAttributes) {
+        if (!fDefaultAttributes) {
             fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
+        }
+        else {
+            fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, fDefaultAttributes);
+        }
     }
 };
 
@@ -375,29 +395,57 @@ bool DOMElementImpl::hasAttributeNS(const XMLCh *namespaceURI,
 
 // util functions for default attributes
 // returns the default attribute map for this node from the owner document
-DOMAttrMapImpl *DOMElementImpl::getDefaultAttributes()
+DOMAttrMapImpl *DOMElementImpl::getDefaultAttributes() const
 {
-    if ((fNode.fOwnerNode == 0) || (getOwnerDocument() == 0))
-        return 0;
+    return fDefaultAttributes;
+}
 
+// initially set up the default attribute information based on doctype information
+void DOMElementImpl::setupDefaultAttributes()
+{
     DOMDocument *tmpdoc = getOwnerDocument();
-    if (tmpdoc->getDoctype() == 0)
-        return 0;
+    if ((fNode.fOwnerNode == 0) || (tmpdoc == 0) || (tmpdoc->getDoctype() == 0))
+        return;
 
     DOMNode *eldef = ((DOMDocumentTypeImpl*)tmpdoc->getDoctype())->getElements()->getNamedItem(getNodeName());
-    return (eldef == 0) ? 0 : (DOMAttrMapImpl *)(eldef->getAttributes());
+    DOMAttrMapImpl* defAttrs = (eldef == 0) ? 0 : (DOMAttrMapImpl *)(eldef->getAttributes());
+
+    if (defAttrs)
+        fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, defAttrs);
 }
 
-// resets all attributes for this node to their default values
-void DOMElementImpl::setupDefaultAttributes()
+DOMAttr * DOMElementImpl::setDefaultAttributeNode(DOMAttr *newAttr)
 {
-    if ((fNode.fOwnerNode == 0) || (getOwnerDocument() == 0) || (getOwnerDocument()->getDoctype() == 0))
-        return;
+    if (fNode.isReadOnly())
+        throw DOMException(
+        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
 
-    DOMAttrMapImpl* defAttrs = getDefaultAttributes();
+    if (newAttr->getNodeType() != DOMNode::ATTRIBUTE_NODE)
+        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0);
+        // revisit.  Exception doesn't match test.
 
-    if (defAttrs)
-        fAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this, defAttrs);
+    // This will throw INUSE if necessary
+    DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItem(newAttr);
+    fAttributes->hasDefaults(true);
+
+    return oldAttr;
+};
+
+
+DOMAttr *DOMElementImpl::setDefaultAttributeNodeNS(DOMAttr *newAttr)
+{
+    if (fNode.isReadOnly())
+        throw DOMException(
+            DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
+
+    if (newAttr -> getOwnerDocument() != this -> getOwnerDocument())
+        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0);
+
+    // This will throw INUSE if necessary
+    DOMAttr *oldAttr = (DOMAttr *) fDefaultAttributes->setNamedItemNS(newAttr);
+    fAttributes->hasDefaults(true);
+
+    return oldAttr;
 }
 
 void DOMElementImpl::release()
diff --git a/src/xercesc/dom/impl/DOMElementImpl.hpp b/src/xercesc/dom/impl/DOMElementImpl.hpp
index a427bb2b191fe9ea3685b2e633de7af953d8be9e..0545840c06f46212a020a26991b6346649f1530b 100644
--- a/src/xercesc/dom/impl/DOMElementImpl.hpp
+++ b/src/xercesc/dom/impl/DOMElementImpl.hpp
@@ -95,6 +95,7 @@ public:
     DOMParentNode     fParent;
     DOMChildNode      fChild;
     DOMAttrMapImpl    *fAttributes;
+    DOMAttrMapImpl    *fDefaultAttributes;
     const XMLCh      *fName;
 
 public:
@@ -107,39 +108,45 @@ public:
     DOMNODE_FUNCTIONS;
 
     // Functions introduced on Element...
-    virtual const XMLCh     * getAttribute(const XMLCh *name) const;
-    virtual DOMAttr       * getAttributeNode(const XMLCh *name) const;
-    virtual DOMNodeList   * getElementsByTagName(const XMLCh *tagname) const;
-    virtual const XMLCh     * getTagName() const;
+    virtual const XMLCh*      getAttribute(const XMLCh *name) const;
+    virtual DOMAttr*          getAttributeNode(const XMLCh *name) const;
+    virtual DOMNodeList*      getElementsByTagName(const XMLCh *tagname) const;
+    virtual const XMLCh*      getTagName() const;
     virtual void              removeAttribute(const XMLCh *name);
-    virtual DOMAttr       * removeAttributeNode(DOMAttr * oldAttr);
+    virtual DOMAttr*          removeAttributeNode(DOMAttr * oldAttr);
     virtual void              setAttribute(const XMLCh *name, const XMLCh *value);
-    virtual DOMAttr       * setAttributeNode(DOMAttr *newAttr);
+    virtual DOMAttr*          setAttributeNode(DOMAttr *newAttr);
     virtual void              setReadOnly(bool readOnly, bool deep);
 
     //Introduced in DOM Level 2
-    virtual const XMLCh *     getAttributeNS(const XMLCh *namespaceURI,
-                                         const XMLCh *localName) const;
+    virtual const XMLCh*      getAttributeNS(const XMLCh *namespaceURI,
+                                             const XMLCh *localName) const;
     virtual void              setAttributeNS(const XMLCh *namespaceURI,
-                                   const XMLCh *qualifiedName,
-                                   const XMLCh *value);
+                                             const XMLCh *qualifiedName,
+                                             const XMLCh *value);
     virtual void              removeAttributeNS(const XMLCh *namespaceURI,
-                                   const XMLCh *localName);
-    virtual DOMAttr        *getAttributeNodeNS(const XMLCh *namespaceURI,
-                                         const XMLCh *localName) const;
-    virtual DOMAttr        *setAttributeNodeNS(DOMAttr *newAttr);
-    virtual DOMNodeList    *getElementsByTagNameNS(const XMLCh *namespaceURI,
-                                                  const XMLCh *localName) const;
+                                                const XMLCh *localName);
+    virtual DOMAttr*          getAttributeNodeNS(const XMLCh *namespaceURI,
+                                                 const XMLCh *localName) const;
+    virtual DOMAttr*          setAttributeNodeNS(DOMAttr *newAttr);
+    virtual DOMNodeList*      getElementsByTagNameNS(const XMLCh *namespaceURI,
+                                                     const XMLCh *localName) const;
     virtual bool              hasAttribute(const XMLCh *name) const;
     virtual bool              hasAttributeNS(const XMLCh *namespaceURI,
                                              const XMLCh *localName) const;
 
-	// default attribute helper functions
-	virtual DOMAttrMapImpl *getDefaultAttributes();
-	virtual void setupDefaultAttributes();
+    // for handling of default attribute
+    virtual DOMAttr*          setDefaultAttributeNode(DOMAttr *newAttr);
+    virtual DOMAttr*          setDefaultAttributeNodeNS(DOMAttr *newAttr);
+    virtual DOMAttrMapImpl*   getDefaultAttributes() const;
+
+    // helper function for DOM Level 3 renameNode
+    virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
+
+protected:
+    // default attribute helper functions
+    virtual void setupDefaultAttributes();
 
-   // helper function for DOM Level 3 renameNode
-   virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
 };
 
 #endif
diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp
index ff2fe7629abeeb2c88b79a2169e7d1e17950e190..c9f42e64b69f4beb60f71825d3044d040a1009ea 100644
--- a/src/xercesc/parsers/AbstractDOMParser.cpp
+++ b/src/xercesc/parsers/AbstractDOMParser.cpp
@@ -611,6 +611,7 @@ void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
                              , const bool                    isRoot)
 {
     DOMElement     *elem;
+    DOMElementImpl *elemImpl;
 
     if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on
 
@@ -632,7 +633,7 @@ void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
         elemQName.append(elemDecl.getBaseName());
 
         elem = createElementNSNode(namespaceURI, elemQName.getRawBuffer());
-        DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
+        elemImpl = (DOMElementImpl *) elem;
         for (unsigned int index = 0; index < attrCount; ++index) {
             static const XMLCh XMLNS[] = {
             chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull
@@ -674,7 +675,7 @@ void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
     }
     else {    //DOM Level 1
         elem = fDocument->createElement(elemDecl.getFullName());
-        DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
+        elemImpl = (DOMElementImpl *) elem;
 			for (unsigned int index = 0; index < attrCount; ++index) {
 				const XMLAttr* oneAttrib = attrList.elementAt(index);
             //AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
@@ -699,6 +700,90 @@ void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
         }
     }
 
+    // set up the default attributes
+	if (elemDecl.hasAttDefs())
+	{		
+        XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
+        XMLAttDef* attr = 0;
+
+        DOMAttrImpl * insertAttr = 0;
+
+        while (defAttrs->hasMoreElements())
+        {
+            attr = &defAttrs->nextElement();
+            const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
+
+            if ((defType == XMLAttDef::Default)
+            ||  (defType == XMLAttDef::Fixed))
+            {
+                if (attr->getValue() != 0)
+                {
+                    if (fScanner->getDoNamespaces())
+                    {
+                        // DOM Level 2 wants all namespace declaration attributes
+                        // to be bound to "http://www.w3.org/2000/xmlns/"
+                        // So as long as the XML parser doesn't do it, it needs to
+                        // done here.
+                        const XMLCh* qualifiedName = attr->getFullName();
+                        int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
+
+                        XMLBufBid bbQName(&fBufMgr);
+                        XMLBuffer& buf = bbQName.getBuffer();
+                        static const XMLCh XMLNS[] = {
+                            chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
+
+                        if (index > 0) {
+                            // there is prefix
+                            // map to XML URI for all cases except when prefix == "xmlns"
+                            XMLCh* prefix;
+                            XMLCh temp[1000];
+
+                            if (index > 999)
+                                prefix = new XMLCh[index+1];
+                            else
+                                prefix = temp;
+
+                            XMLString::subString(prefix ,qualifiedName, 0, index);
+
+                            if (!XMLString::compareString(prefix,XMLNS))
+                                buf.append(XMLUni::fgXMLNSURIName);
+                            else
+                                buf.append(XMLUni::fgXMLURIName);
+
+                            if (index > 999)
+                                delete prefix;
+                        }
+                        else {
+                            //   No prefix
+                            if (!XMLString::compareString(qualifiedName,XMLNS))
+                                buf.append(XMLUni::fgXMLNSURIName);
+                        }
+
+                        insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
+                           buf.getRawBuffer(),     // NameSpaceURI
+                           qualifiedName);   // qualified name
+
+                        DOMNode* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
+                        if (remAttr)
+                            remAttr->release();
+                    }
+                    else
+                    {
+                        // Namespaces is turned off...
+                        insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
+                        DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
+                        if (remAttr)
+                            remAttr->release();
+                    }
+
+                    insertAttr->setValue(attr->getValue());
+                    insertAttr->setSpecified(false);
+                }
+            }
+        }
+    }
+
+
     fCurrentParent->appendChild(elem);
 
     fNodeStack->push(fCurrentParent);