diff --git a/src/validators/schema/ComplexTypeInfo.cpp b/src/validators/schema/ComplexTypeInfo.cpp
index 86066d0b29d05b0c93136f91a12c5d4ab97418eb..38e9f7c74e5a3a179b6477e72fff54583a8ad7fa 100644
--- a/src/validators/schema/ComplexTypeInfo.cpp
+++ b/src/validators/schema/ComplexTypeInfo.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.27  2002/01/15 19:09:16  knoaman
+ * Fix for bug 5807.
+ *
  * Revision 1.26  2002/01/02 15:20:22  tng
  * Schema Fix: should not store a temp value as the key in the element pool and the attribute pool.
  *
@@ -156,12 +159,14 @@ ComplexTypeInfo::ComplexTypeInfo()
     : fAbstract(false)
     , fAdoptContentSpec(true)
     , fAttWithTypeId(false)
+    , fPreprocessed(false)
     , fDerivedBy(0)
     , fBlockSet(0)
     , fFinalSet(0)
     , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
     , fElementId(XMLElementDecl::fgInvalidElemId)
     , fContentType(SchemaElementDecl::Empty)
+    , fRecursingTypeIndex(-1)
     , fTypeName(0)
     , fBaseDatatypeValidator(0)
     , fDatatypeValidator(0)
diff --git a/src/validators/schema/ComplexTypeInfo.hpp b/src/validators/schema/ComplexTypeInfo.hpp
index acfee522289942d9e4255baea4e5dbd2f9202c77..f1bb4ea215f3283c85e52dd796cc7d61ddc28414 100644
--- a/src/validators/schema/ComplexTypeInfo.hpp
+++ b/src/validators/schema/ComplexTypeInfo.hpp
@@ -104,6 +104,7 @@ public:
     bool                     getAbstract() const;
     bool                     getAdoptContentSpec() const;
     bool                     containsAttWithTypeId() const;
+    bool                     getPreprocessed() const;
     int                      getDerivedBy() const;
     int                      getBlockSet() const;
     int                      getFinalSet() const;
@@ -127,7 +128,7 @@ public:
     SchemaElementDecl*       elementAt(const unsigned int index);
     XMLContentModel*         getContentModel(const bool checkUPA = false);
     const XMLCh*             getFormattedContentModel ()   const;
-
+    int                      getRecursingTypeIndex() const;
 
     // -----------------------------------------------------------------------
     //  Setter methods
@@ -135,6 +136,7 @@ public:
     void setAbstract(const bool isAbstract);
     void setAdoptContentSpec(const bool toAdopt);
     void setAttWithTypeId(const bool value);
+    void setPreprocessed(const bool aValue = true);
     void setDerivedBy(const int derivedBy);
     void setBlockSet(const int blockSet);
     void setFinalSet(const int finalSet);
@@ -150,6 +152,7 @@ public:
     void addAttDef(SchemaAttDef* const toAdd);
     void addElement(SchemaElementDecl* const toAdd);
     void setContentModel(XMLContentModel* const newModelToAdopt);
+    void setRecursingTypeIndex(const int anIndex);
 
     // -----------------------------------------------------------------------
     //  Helper methods
@@ -198,12 +201,14 @@ private:
     bool                               fAbstract;
     bool                               fAdoptContentSpec;
     bool                               fAttWithTypeId;
+    bool                               fPreprocessed;
     int                                fDerivedBy;
     int                                fBlockSet;
     int                                fFinalSet;
     int                                fScopeDefined;
     unsigned int                       fElementId;
     int                                fContentType;
+    int                                fRecursingTypeIndex;
     XMLCh*                             fTypeName;
     DatatypeValidator*                 fBaseDatatypeValidator;
     DatatypeValidator*                 fDatatypeValidator;
@@ -239,6 +244,11 @@ inline bool ComplexTypeInfo::containsAttWithTypeId() const {
     return fAttWithTypeId;
 }
 
+inline bool ComplexTypeInfo::getPreprocessed() const {
+
+    return fPreprocessed;
+}
+
 inline int ComplexTypeInfo::getDerivedBy() const {
 
     return fDerivedBy;
@@ -361,6 +371,11 @@ inline XMLContentModel* ComplexTypeInfo::getContentModel(const bool checkUPA)
     return fContentModel;
 }
 
+inline int ComplexTypeInfo::getRecursingTypeIndex() const {
+
+    return fRecursingTypeIndex;
+}
+
 // ---------------------------------------------------------------------------
 //  ComplexTypeInfo: Setter methods
 // ---------------------------------------------------------------------------
@@ -379,6 +394,11 @@ inline void ComplexTypeInfo::setAttWithTypeId(const bool value) {
     fAttWithTypeId = value;
 }
 
+inline void ComplexTypeInfo::setPreprocessed(const bool aValue) {
+
+    fPreprocessed = aValue;
+}
+
 inline void ComplexTypeInfo::setDerivedBy(const int derivedBy) {
 
     fDerivedBy = derivedBy;
@@ -462,6 +482,11 @@ ComplexTypeInfo::setContentModel(XMLContentModel* const newModelToAdopt)
     fContentModel = newModelToAdopt;
 }
 
+inline void ComplexTypeInfo::setRecursingTypeIndex(const int anIndex) {
+
+    fRecursingTypeIndex = anIndex;
+}
+
 // ---------------------------------------------------------------------------
 //  ComplexTypeInfo: Helper methods
 // ---------------------------------------------------------------------------
diff --git a/src/validators/schema/TraverseSchema.cpp b/src/validators/schema/TraverseSchema.cpp
index 63320060600b15f7f47a37445ecfe919eb65b03a..003a0ce45cbe835fc29b9b5334a3a36b2f1cc792 100644
--- a/src/validators/schema/TraverseSchema.cpp
+++ b/src/validators/schema/TraverseSchema.cpp
@@ -189,11 +189,12 @@ TraverseSchema::TraverseSchema( const DOM_Element&                 schemaRoot
     , fTargetNSURI(-1)
     , fEmptyNamespaceURI(-1)
     , fCurrentScope(Grammar::TOP_LEVEL_SCOPE)
-    , fAnonXSTypeCount(0)
-    , fCircularCheckIndex(0)
     , fFinalDefault(0)
     , fBlockDefault(0)
     , fScopeCount(0)
+    , fRecursingElemIndex(0)
+    , fAnonXSTypeCount(0)
+    , fCircularCheckIndex(0)
     , fTargetNSURIString(0)
     , fDatatypeRegistry(0)
     , fGrammarResolver(grammarResolver)
@@ -229,6 +230,8 @@ TraverseSchema::TraverseSchema( const DOM_Element&                 schemaRoot
     , fIC_NodeListNS(0)
     , fIC_ElementsNS(0)
     , fIC_NamespaceDepthNS(0)
+    , fRecursingAnonTypes(0)
+    , fRecursingTypeNames(0)
 {
 
     try {
@@ -1060,7 +1063,8 @@ int TraverseSchema::traverseSimpleTypeDecl(const DOM_Element& childElem,
   *                   ( (attribute | attributeGroup)* , anyAttribute?))))
   *     </complexType>
   */
-int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
+int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem,
+                                            const XMLCh* const recursingTypeName) {
 
     // Get the attributes of the complexType
     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
@@ -1074,7 +1078,10 @@ int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
             return -1;
         }
 
-        name = genAnonTypeName(fgAnonCNamePrefix);
+        if (recursingTypeName)
+            name = recursingTypeName;
+        else
+            name = genAnonTypeName(fgAnonCNamePrefix);
     }
 
     if (!XMLString::isValidNCName(name)) {
@@ -1094,11 +1101,13 @@ int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
 
     int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
     const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex);
-    if (topLevel) {
+    ComplexTypeInfo* typeInfo = 0;
+
+    if (topLevel || recursingTypeName) {
 
-        ComplexTypeInfo* temp = fComplexTypeRegistry->get(fullName);
+        typeInfo = fComplexTypeRegistry->get(fullName);
 
-        if (temp != 0 ) {
+        if (typeInfo && !typeInfo->getPreprocessed()) {
             return typeNameIndex;
         }
     }
@@ -1113,10 +1122,30 @@ int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
     // -----------------------------------------------------------------------
     // Create a new instance
     // -----------------------------------------------------------------------
-    ComplexTypeInfo* typeInfo = new ComplexTypeInfo();
+    bool preProcessFlag = (typeInfo) ? typeInfo->getPreprocessed() : false;
     unsigned int previousCircularCheckIndex = fCircularCheckIndex;
     int previousScope = fCurrentScope;
-    fCurrentScope = fScopeCount++;
+
+    if (preProcessFlag) {
+
+        fCurrentScope = typeInfo->getScopeDefined();
+        typeInfo->setPreprocessed(false);
+    }
+    else {
+
+        // ------------------------------------------------------------------
+        // Register the type
+        // ------------------------------------------------------------------
+        typeInfo = new ComplexTypeInfo();
+        fCurrentScope = fScopeCount++;
+        fComplexTypeRegistry->put((void*) fullName, typeInfo);
+        typeInfo->setTypeName(fullName);
+        typeInfo->setScopeDefined(fCurrentScope);
+    }
+
+    fCurrentTypeNameStack->addElement(typeNameIndex);
+    ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;
+    fCurrentComplexType = typeInfo;
 
     // ------------------------------------------------------------------
     // First, handle any ANNOTATION declaration and get next child
@@ -1124,18 +1153,6 @@ int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
     DOM_Element child = checkContent(elem, XUtil::getFirstChildElement(elem),
                                      true);
 
-    // ------------------------------------------------------------------
-    // Register the type
-    // ------------------------------------------------------------------
-    // Register the type first, so that in case of a recursive element type
-    // declaration, we can retrieve the complexType info (though the rest of
-    fComplexTypeRegistry->put((void*) fullName, typeInfo);
-    typeInfo->setTypeName(fullName);
-    typeInfo->setScopeDefined(fCurrentScope);
-    fCurrentTypeNameStack->addElement(typeNameIndex);
-    ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;
-    fCurrentComplexType = typeInfo;
-
     // ------------------------------------------------------------------
     // Process the content of the complex type declaration
     // ------------------------------------------------------------------
@@ -1182,39 +1199,62 @@ int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
             }
         }
     }
-    catch(TraverseSchema::ExceptionCodes) {
-        defaultComplexTypeInfo(typeInfo);
+    catch(const TraverseSchema::ExceptionCodes aCode) {
+        if (aCode == TraverseSchema::InvalidComplexTypeInfo)
+            defaultComplexTypeInfo(typeInfo);
+        else if (aCode == TraverseSchema::RecursingElement)
+            typeInfo->setPreprocessed();
     }
 
     // ------------------------------------------------------------------
     // Finish the setup of the typeInfo
     // ------------------------------------------------------------------
-    const XMLCh* blockAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK);
-    const XMLCh* finalAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_FINAL);
-    const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
-    int blockSet = parseBlockSet(blockAttVal, C_Block);
-    int finalSet = parseFinalSet(finalAttVal, EC_Final);
+    if (!preProcessFlag) {
 
-    typeInfo->setBlockSet(blockSet);
-    typeInfo->setFinalSet(finalSet);
+        const XMLCh* blockAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK);
+        const XMLCh* finalAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_FINAL);
+        const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
+        int blockSet = parseBlockSet(blockAttVal, C_Block);
+        int finalSet = parseFinalSet(finalAttVal, EC_Final);
 
-    if (XMLString::stringLen(abstractAttVal)
-        && (!XMLString::compareString(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)
-            || !XMLString::compareString(abstractAttVal, fgValueOne))) {
-        typeInfo->setAbstract(true);
-    }
-    else {
-        typeInfo->setAbstract(false);
+        typeInfo->setBlockSet(blockSet);
+        typeInfo->setFinalSet(finalSet);
+
+        if (XMLString::stringLen(abstractAttVal)
+            && (!XMLString::compareString(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)
+                || !XMLString::compareString(abstractAttVal, fgValueOne))) {
+            typeInfo->setAbstract(true);
+        }
+        else {
+            typeInfo->setAbstract(false);
+        }
     }
 
+    // ------------------------------------------------------------------
+    // Traverse anonymous complex types for recursing elements
+    // ------------------------------------------------------------------
+    resetCurrentTypeNameStack(0);
+    fCircularCheckIndex = previousCircularCheckIndex;
+
+    int i = fRecursingElemIndex - 1;
+    int recursingTypeIndex = typeInfo->getRecursingTypeIndex();
+
+    for (; i >= recursingTypeIndex && recursingTypeIndex != -1; i--) {
+
+        DOM_Element elem = fRecursingAnonTypes->elementAt(i);
+        const XMLCh* typeName = fRecursingTypeNames->elementAt(i);
+
+        fRecursingAnonTypes->removeElementAt(i);
+        fRecursingTypeNames->removeElementAt(i);
+        fRecursingElemIndex--;
+        traverseComplexTypeDecl(elem, typeName);
+    }    
+
     // ------------------------------------------------------------------
     // Before exiting, restore the scope, mainly for nested anonymous types
     // ------------------------------------------------------------------
     fCurrentScope = previousScope;
     fCurrentComplexType = saveTypeInfo;
-    fCircularCheckIndex = previousCircularCheckIndex;
-    resetCurrentTypeNameStack(0);
-
 
     return typeNameIndex;
 }
@@ -2280,7 +2320,24 @@ QName* TraverseSchema::traverseElementDecl(const DOM_Element& elem, bool& toDele
                 noErrorFound = false;
             }
             else if (!isDuplicate) {
+
                 typeInfo->setElementId(elemDecl->getId());
+
+                //Recursing element
+                if (typeInfo->getPreprocessed()) {
+
+                    const XMLCh* typeInfoName = typeInfo->getTypeName();
+                    
+                    if (!fRecursingAnonTypes) {
+                        fRecursingAnonTypes = new ValueVectorOf<DOM_Element>(8);
+                        fRecursingTypeNames = new ValueVectorOf<const XMLCh*>(8);
+                    }
+
+                    fRecursingAnonTypes->addElement(content);
+                    fRecursingTypeNames->addElement(typeInfoName + XMLString::indexOf(typeInfoName, chComma) + 1);
+                    typeInfo->getBaseComplexTypeInfo()->setRecursingTypeIndex(fRecursingElemIndex);
+                    fRecursingElemIndex++;
+                }
             }
 
             anonymousType = true;
@@ -5621,11 +5678,21 @@ void TraverseSchema::processBaseTypeInfo(const XMLCh* const baseName,
         baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName);
 
         // Circular check
-        if (baseComplexTypeInfo &&
-            fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName), fCircularCheckIndex)) {
+        if (baseComplexTypeInfo) {
 
-            reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
-            throw TraverseSchema::InvalidComplexTypeInfo;
+            if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName), fCircularCheckIndex)) {
+
+                reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
+                throw TraverseSchema::InvalidComplexTypeInfo;
+            }
+            else if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName))) {
+
+                typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo);
+                throw TraverseSchema::RecursingElement;
+            }
+            else if (baseComplexTypeInfo->getPreprocessed()) {
+                baseComplexTypeInfo = 0;
+            }
         }
     }
 
@@ -8502,6 +8569,8 @@ void TraverseSchema::cleanUp() {
     delete fIC_ElementsNS;
     delete fIC_NamespaceDepthNS;
     delete fIC_NodeListNS;
+    delete fRecursingAnonTypes;
+    delete fRecursingTypeNames;
 }
 
 /**
diff --git a/src/validators/schema/TraverseSchema.hpp b/src/validators/schema/TraverseSchema.hpp
index 4a9f4c92953d7ccc7876769e3f99edb241c4a39e..2222edd5f687c633a090f732d3b7ff123e215293 100644
--- a/src/validators/schema/TraverseSchema.hpp
+++ b/src/validators/schema/TraverseSchema.hpp
@@ -181,7 +181,7 @@ private:
                                                   const bool isMixed);
     int                 traverseSimpleTypeDecl(const DOM_Element& childElem,
                                                int baseRefContext = SchemaSymbols::EMPTY_SET);
-    int                 traverseComplexTypeDecl(const DOM_Element& childElem);
+    int                 traverseComplexTypeDecl(const DOM_Element& childElem, const XMLCh* const recursingTypeName = 0);
     int                 traverseByList(const DOM_Element& rootElem,
                                        const DOM_Element& contentElem,
                                        const int typeNameIndex,
@@ -757,8 +757,7 @@ private:
     {
         NoException = 0,
         InvalidComplexTypeInfo = 1,
-        ParticleDerivationNotOK = 2,
-        InvalidContentSpecType = 3
+        RecursingElement = 2
     };
 
     enum
@@ -777,7 +776,8 @@ private:
     int                                           fCurrentScope;
     int                                           fFinalDefault;
     int                                           fBlockDefault;
-    int                                           fScopeCount;    
+    int                                           fScopeCount;
+    int                                           fRecursingElemIndex;
     unsigned int                                  fAnonXSTypeCount;
     unsigned int                                  fCircularCheckIndex;
     const XMLCh*                                  fTargetNSURIString;
@@ -817,6 +817,8 @@ private:
     RefHashTableOf<ValueVectorOf<DOM_Element> >*  fIC_NodeListNS;
     RefHashTableOf<ElemVector>*                   fIC_ElementsNS;
     RefHashTableOf<ValueVectorOf<unsigned int> >* fIC_NamespaceDepthNS;
+    ValueVectorOf<DOM_Element>*                   fRecursingAnonTypes;
+    ValueVectorOf<const XMLCh*>*                  fRecursingTypeNames;
 
     friend class GeneralAttributeCheck;
 };