diff --git a/src/xercesc/validators/schema/TraverseSchema.cpp b/src/xercesc/validators/schema/TraverseSchema.cpp
index 82939a24bf63120c732789527685c8c08bd9862a..4aa253d1c38195d1177065662a8eb85384ed8943 100644
--- a/src/xercesc/validators/schema/TraverseSchema.cpp
+++ b/src/xercesc/validators/schema/TraverseSchema.cpp
@@ -215,6 +215,7 @@ TraverseSchema::TraverseSchema( DOMElement* const    schemaRoot
     , fCurrentGroupStack(0)
     , fIC_NamespaceDepth(0)
     , fIC_Elements(0)
+    , fDeclStack(0)
     , fGlobalDeclarations(0)
     , fNotationRegistry(0)
     , fRedefineComponents(0)
@@ -1489,7 +1490,7 @@ TraverseSchema::traverseAttributeGroupDecl(const DOMElement* const elem,
     XercesAttGroupInfo* saveAttGroupInfo = fCurrentAttGroupInfo;
     XercesAttGroupInfo* attGroupInfo = new XercesAttGroupInfo();
 
-    fAttGroupRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), attGroupInfo);
+    fDeclStack->addElement(elem);
     fCurrentAttGroupInfo = attGroupInfo;
 
     for (; content !=0; content = XUtil::getNextSiblingElement(content)) {
@@ -1524,9 +1525,15 @@ TraverseSchema::traverseAttributeGroupDecl(const DOMElement* const elem,
         }
     }
 
+    // ------------------------------------------------------------------
+    // Pop declaration
+    // ------------------------------------------------------------------
+    fDeclStack->removeElementAt(fDeclStack->size() - 1);
+
     // ------------------------------------------------------------------
     // Restore old attGroupInfo
     // ------------------------------------------------------------------
+    fAttGroupRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), attGroupInfo);
     fCurrentAttGroupInfo = saveAttGroupInfo;
 
     // ------------------------------------------------------------------
@@ -6482,17 +6489,6 @@ TraverseSchema::processAttributeGroupRef(const DOMElement* const elem,
     }
     else {
 
-        // circular check
-        DOMNode* parentElem = elem->getParentNode();
-
-        if (XMLString::equals(parentElem->getLocalName(), SchemaSymbols::fgELT_ATTRIBUTEGROUP)
-            && XMLString::equals(((DOMElement*) parentElem)->getAttribute(SchemaSymbols::fgATT_NAME), localPart)
-            && !XMLString::equals(parentElem->getParentNode()->getLocalName(), SchemaSymbols::fgELT_REDEFINE)) {
-
-            reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularAttGroup);
-            return 0;
-        }
-
         attGroupInfo = fAttGroupRegistry->get(localPart);
     }
 
@@ -6504,6 +6500,13 @@ TraverseSchema::processAttributeGroupRef(const DOMElement* const elem,
 
         if (attGroupElem != 0) {
 
+            // circular attribute check
+            if (fDeclStack->containsElement(attGroupElem)) {
+
+                reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, refName);
+                return 0;
+            }
+
             attGroupInfo = traverseAttributeGroupDecl(attGroupElem, typeInfo, true);
 
             if (attGroupInfo && fCurrentAttGroupInfo) {
@@ -7718,6 +7721,7 @@ void TraverseSchema::init() {
     fSchemaInfoList = new RefHash2KeysTableOf<SchemaInfo>(29);
     fPreprocessedNodes = new RefHashTableOf<SchemaInfo>(29, false, new HashPtr());
     fLocator = new XSDLocator();
+    fDeclStack = new ValueVectorOf<const DOMElement*>(16);
 }
 
 void TraverseSchema::cleanUp() {
@@ -7730,6 +7734,7 @@ void TraverseSchema::cleanUp() {
     delete fRedefineComponents;
     delete fIdentityConstraintNames;
     delete fSubstitutionGroups;
+    delete fDeclStack;
     delete fIC_ElementsNS;
     delete fIC_NamespaceDepthNS;
     delete fIC_NodeListNS;
diff --git a/src/xercesc/validators/schema/TraverseSchema.hpp b/src/xercesc/validators/schema/TraverseSchema.hpp
index 0a0ff2ffeee3c652570afb0e533f7d919dae2e36..d1f5658fc0c39a9b3a7f6a10324c37eb4f6a6a1d 100644
--- a/src/xercesc/validators/schema/TraverseSchema.hpp
+++ b/src/xercesc/validators/schema/TraverseSchema.hpp
@@ -755,6 +755,7 @@ private:
     ValueVectorOf<unsigned int>*                   fCurrentGroupStack;
     ValueVectorOf<unsigned int>*                   fIC_NamespaceDepth;
     ValueVectorOf<SchemaElementDecl*>*             fIC_Elements;
+    ValueVectorOf<const DOMElement*>*              fDeclStack;
     GeneralAttributeCheck                          fAttributeCheck;
     RefHash2KeysTableOf<XMLCh>*                    fGlobalDeclarations;
     RefHash2KeysTableOf<XMLCh>*                    fNotationRegistry;
@@ -762,7 +763,7 @@ private:
     RefHash2KeysTableOf<IdentityConstraint>*       fIdentityConstraintNames;
     RefHash2KeysTableOf<SchemaElementDecl>*        fSubstitutionGroups;
     RefHash2KeysTableOf<ElemVector>*               fValidSubstitutionGroups;
-    RefHashTableOf<ValueVectorOf<DOMElement*> >* fIC_NodeListNS;
+    RefHashTableOf<ValueVectorOf<DOMElement*> >*   fIC_NodeListNS;
     RefHashTableOf<ElemVector>*                    fIC_ElementsNS;
     RefHashTableOf<ValueVectorOf<unsigned int> >*  fIC_NamespaceDepthNS;
     XSDDOMParser*                                  fParser;