private void TraverseParticle(XmlSchemaParticle particle, XmlSchemaComplexType baseType,
                                      ClrContentTypeInfo typeInfo, XmlSchemaDerivationMethod derivationMethod)
        {
            if (particleStack == null)
            {
                particleStack = new Stack <ParticleData>();
            }
            else
            {
                particleStack.Clear();
            }

            if (propertyNameTypeTable == null)
            {
                propertyNameTypeTable = new Dictionary <string, ClrPropertyInfo>();
            }
            else
            {
                propertyNameTypeTable.Clear();
            }

            XmlSchemaParticle baseParticle = baseType.ContentTypeParticle;
            ParticleData      particleData;
            GroupingInfo      parentGroupInfo = null;
            StringBuilder     regEx           = new StringBuilder();

            XmlSchemaGroupBase currentGroupBase    = null;
            GroupingInfo       currentGroupingInfo = null;

            int currentIndex = 0;

            while (true)
            {
                // dont interrogate a particle if we are past the end of the list
                if (currentGroupBase == null || currentIndex <= currentGroupBase.Items.Count)
                {
                    ParticleType particleType = particle.GetParticleType();
                    switch (particleType)
                    {
                    case ParticleType.Element:
                    {
                        XmlSchemaElement elem         = particle as XmlSchemaElement;
                        ClrPropertyInfo  propertyInfo = null;
                        bool             fromBaseType = false;
                        if (derivationMethod == XmlSchemaDerivationMethod.Extension && typeInfo.IsDerived)
                        {
                            if (baseParticle.ContainsElement(elem))
                            {
                                fromBaseType = true;
                            }
                            else if (!typeInfo.InlineBaseType && baseType.ContainsName(elem.QualifiedName))
                            {
                                typeInfo.InlineBaseType = true;
                            }
                        }

                        propertyInfo = BuildProperty(elem, fromBaseType);
                        regEx.Append(propertyInfo.PropertyName);
                        AppendOccurenceToRegex(propertyInfo, regEx);
                        //Add to parent
                        if (currentGroupingInfo == null)
                        {
                            //Not adding property to propertyNameTypeTable as this case will occur only for pointless groups, so they have just one property
                            BuildAnnotationInformation(propertyInfo, elem, false, false);
                            typeInfo.AddMember(propertyInfo);
                        }
                        else
                        {
                            BuildAnnotationInformation(propertyInfo, elem,
                                                       currentGroupingInfo.ContentModelType == ContentModelType.Choice,
                                                       currentGroupingInfo.IsNested);
                            currentGroupingInfo.AddChild(propertyInfo);
                            SetPropertyFlags(propertyInfo, currentGroupingInfo, elem.ElementSchemaType);
                        }

                        break;
                    }

                    case ParticleType.Any:
                    {
                        regEx.Append("any");
                        XmlSchemaAny any = particle as XmlSchemaAny;

                        if (derivationMethod == XmlSchemaDerivationMethod.Extension && typeInfo.IsDerived)
                        {
                            if (baseParticle.ContainsWildCard(any))
                            {
                                typeInfo.HasElementWildCard = true;     //ANY property in the base type will be reused
                            }
                        }

                        //Note we always create a property info object to keep the original nesting structure in the schema
                        //so it can be used to create a correct FSM; on the other hand, typeInfo.HasElementWildCard will indicate whether
                        //we need to create a property in the resulting object type.
                        ClrWildCardPropertyInfo wcPropertyInfo =
                            BuildAnyProperty(any, !typeInfo.HasElementWildCard);


                        //Add to parent
                        if (currentGroupingInfo == null)
                        {
                            typeInfo.AddMember(wcPropertyInfo);
                        }
                        else
                        {
                            currentGroupingInfo.AddChild(wcPropertyInfo);
                        }

                        if (!typeInfo.HasElementWildCard)
                        {
                            typeInfo.HasElementWildCard = true;
                        }
                        break;
                    }

                    case ParticleType.Sequence:
                    case ParticleType.Choice:
                    case ParticleType.All:
                        regEx.Append("(");
                        if (currentGroupBase != null)
                        {
                            //already there is a group that we are processing, push it on stack to process sub-group
                            particleStack.Push(
                                new ParticleData(currentGroupBase, currentGroupingInfo, currentIndex));
                            currentIndex = 0;     //Re-start index for new group base
                        }

                        parentGroupInfo  = currentGroupingInfo;    //Assign parent before creating child groupInfo
                        currentGroupBase = particle as XmlSchemaGroupBase;
                        Debug.Assert(currentGroupBase != null);
                        currentGroupingInfo = new GroupingInfo((ContentModelType)((int)particleType),
                                                               GetOccurence(currentGroupBase));

                        //Add to parent
                        if (parentGroupInfo == null)
                        {
                            typeInfo.AddMember(currentGroupingInfo);
                            parentGroupInfo = currentGroupingInfo;     //Assign first time
                        }
                        else
                        {
                            parentGroupInfo.AddChild(currentGroupingInfo);
                            parentGroupInfo.HasChildGroups = true;
                            currentGroupingInfo.IsNested   = true;
                            if (parentGroupInfo.IsRepeating)
                            {
                                currentGroupingInfo.IsRepeating = true;
                            }

                            if (currentGroupingInfo.IsRepeating)
                            {
                                parentGroupInfo.HasRepeatingGroups = true;
                            }
                        }

                        break;
                    }
                }

                //Drill down into items
                if (currentGroupBase != null && currentIndex < currentGroupBase.Items.Count)
                {
                    // if this isnt the first, then we need a seperator
                    if (currentIndex > 0)
                    {
                        regEx.Append(currentGroupingInfo.ContentModelType == ContentModelType.Choice ? " | " : ", ");
                    }

                    particle = (XmlSchemaParticle)currentGroupBase.Items[currentIndex++];
                }
                else
                {
                    if (currentGroupBase != null)
                    {
                        regEx.Append(")");
                        AppendOccurenceToRegex(currentGroupingInfo, regEx);
                    }

                    if (particleStack.Count > 0)
                    {
                        bool childGroupHasRecurringElements = currentGroupingInfo.HasRecurrentElements;
                        bool childGroupHasRepeatingGroups   = currentGroupingInfo.HasRepeatingGroups;

                        particleData        = particleStack.Pop();
                        currentGroupBase    = particleData.currentGroupBase;
                        currentGroupingInfo = particleData.currentGroupingInfo;

                        currentGroupingInfo.HasRecurrentElements = childGroupHasRecurringElements;
                        currentGroupingInfo.HasRepeatingGroups   = childGroupHasRepeatingGroups;

                        currentIndex = particleData.currentIndex;
                        if (currentIndex < currentGroupBase.Items.Count)
                        {
                            particle = (XmlSchemaParticle)currentGroupBase.Items[currentIndex++];
                            regEx.Append(currentGroupingInfo.ContentModelType == ContentModelType.Choice ? "|" : ", ");
                        }
                        else
                        {
                            // we were already at the end of the parent group, so just continue
                            currentIndex++; //we are off the end of this list
                        }
                    }
                    else
                    {
                        //No more particles to process
                        break;
                    }
                }
            }

            if (regEx.Length != 0)
            {
                typeInfo.ContentModelRegEx = regEx.ToString();
            }
        }
        private void TraverseParticle(XmlSchemaParticle particle, XmlSchemaComplexType baseType, ClrContentTypeInfo typeInfo, XmlSchemaDerivationMethod derivationMethod)
        {
            if (this.particleStack != null)
            {
                this.particleStack.Clear();
            }
            else
            {
                this.particleStack = new Stack <XsdToTypesConverter.ParticleData>();
            }
            if (this.propertyNameTypeTable != null)
            {
                this.propertyNameTypeTable.Clear();
            }
            else
            {
                this.propertyNameTypeTable = new Dictionary <string, ClrPropertyInfo>();
            }
            XmlSchemaParticle  baseParticle        = baseType.ContentTypeParticle;
            GroupingInfo       parentGroupInfo     = null;
            StringBuilder      regEx               = new StringBuilder();
            XmlSchemaGroupBase currentGroupBase    = null;
            GroupingInfo       currentGroupingInfo = null;
            int currentIndex = 0;

            while (true)
            {
                if ((currentGroupBase == null ? true : currentIndex <= currentGroupBase.Items.Count))
                {
                    ParticleType particleType = particle.GetParticleType();
                    switch (particleType)
                    {
                    case ParticleType.Sequence:
                    case ParticleType.Choice:
                    case ParticleType.All:
                    {
                        regEx.Append("(");
                        if (currentGroupBase != null)
                        {
                            this.particleStack.Push(new XsdToTypesConverter.ParticleData(currentGroupBase, currentGroupingInfo, currentIndex));
                            currentIndex = 0;
                        }
                        parentGroupInfo  = currentGroupingInfo;
                        currentGroupBase = particle as XmlSchemaGroupBase;
                        Debug.Assert(currentGroupBase != null);
                        currentGroupingInfo = new GroupingInfo((ContentModelType)particleType, this.GetOccurence(currentGroupBase));
                        if (parentGroupInfo != null)
                        {
                            parentGroupInfo.AddChild(currentGroupingInfo);
                            parentGroupInfo.HasChildGroups = true;
                            currentGroupingInfo.IsNested   = true;
                            if (parentGroupInfo.IsRepeating)
                            {
                                currentGroupingInfo.IsRepeating = true;
                            }
                            if (currentGroupingInfo.IsRepeating)
                            {
                                parentGroupInfo.HasRepeatingGroups = true;
                            }
                        }
                        else
                        {
                            typeInfo.AddMember(currentGroupingInfo);
                            parentGroupInfo = currentGroupingInfo;
                        }
                        break;
                    }

                    case ParticleType.Element:
                    {
                        XmlSchemaElement elem         = particle as XmlSchemaElement;
                        ClrPropertyInfo  propertyInfo = null;
                        bool             fromBaseType = false;
                        if ((derivationMethod != XmlSchemaDerivationMethod.Extension ? false : typeInfo.IsDerived))
                        {
                            if (baseParticle.ContainsElement(elem))
                            {
                                fromBaseType = true;
                            }
                            else if ((typeInfo.InlineBaseType ? false : baseType.ContainsName(elem.QualifiedName)))
                            {
                                typeInfo.InlineBaseType = true;
                            }
                        }
                        propertyInfo = this.BuildProperty(elem, fromBaseType);
                        regEx.Append(propertyInfo.PropertyName);
                        this.AppendOccurenceToRegex(propertyInfo, regEx);
                        if (currentGroupingInfo != null)
                        {
                            this.BuildAnnotationInformation(propertyInfo, elem, currentGroupingInfo.ContentModelType == ContentModelType.Choice, currentGroupingInfo.IsNested);
                            currentGroupingInfo.AddChild(propertyInfo);
                            this.SetPropertyFlags(propertyInfo, currentGroupingInfo, elem.ElementSchemaType);
                        }
                        else
                        {
                            this.BuildAnnotationInformation(propertyInfo, elem, false, false);
                            typeInfo.AddMember(propertyInfo);
                        }
                        break;
                    }

                    case ParticleType.Any:
                    {
                        regEx.Append("any");
                        XmlSchemaAny any = particle as XmlSchemaAny;
                        if ((derivationMethod != XmlSchemaDerivationMethod.Extension ? false : typeInfo.IsDerived))
                        {
                            if (baseParticle.ContainsWildCard(any))
                            {
                                typeInfo.HasElementWildCard = true;
                            }
                        }
                        ClrWildCardPropertyInfo wcPropertyInfo = this.BuildAnyProperty(any, !typeInfo.HasElementWildCard);
                        if (currentGroupingInfo != null)
                        {
                            currentGroupingInfo.AddChild(wcPropertyInfo);
                        }
                        else
                        {
                            typeInfo.AddMember(wcPropertyInfo);
                        }
                        if (!typeInfo.HasElementWildCard)
                        {
                            typeInfo.HasElementWildCard = true;
                        }
                        break;
                    }
                    }
                }
                if ((currentGroupBase == null ? true : currentIndex >= currentGroupBase.Items.Count))
                {
                    if (currentGroupBase != null)
                    {
                        regEx.Append(")");
                        this.AppendOccurenceToRegex(currentGroupingInfo, regEx);
                    }
                    if (this.particleStack.Count <= 0)
                    {
                        break;
                    }
                    bool childGroupHasRecurringElements           = currentGroupingInfo.HasRecurrentElements;
                    bool childGroupHasRepeatingGroups             = currentGroupingInfo.HasRepeatingGroups;
                    XsdToTypesConverter.ParticleData particleData = this.particleStack.Pop();
                    currentGroupBase    = particleData.currentGroupBase;
                    currentGroupingInfo = particleData.currentGroupingInfo;
                    currentGroupingInfo.HasRecurrentElements = childGroupHasRecurringElements;
                    currentGroupingInfo.HasRepeatingGroups   = childGroupHasRepeatingGroups;
                    currentIndex = particleData.currentIndex;
                    if (currentIndex >= currentGroupBase.Items.Count)
                    {
                        currentIndex++;
                    }
                    else
                    {
                        int num = currentIndex;
                        currentIndex = num + 1;
                        particle     = (XmlSchemaParticle)currentGroupBase.Items[num];
                        regEx.Append((currentGroupingInfo.ContentModelType == ContentModelType.Choice ? "|" : ", "));
                    }
                }
                else
                {
                    if (currentIndex > 0)
                    {
                        regEx.Append((currentGroupingInfo.ContentModelType == ContentModelType.Choice ? " | " : ", "));
                    }
                    int num1 = currentIndex;
                    currentIndex = num1 + 1;
                    particle     = (XmlSchemaParticle)currentGroupBase.Items[num1];
                }
            }
            if (regEx.Length != 0)
            {
                typeInfo.ContentModelRegEx = regEx.ToString();
            }
        }