/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject;
import org.eclipse.persistence.internal.oxm.schema.model.All;
import org.eclipse.persistence.internal.oxm.schema.model.Annotation;
import org.eclipse.persistence.internal.oxm.schema.model.Any;
import org.eclipse.persistence.internal.oxm.schema.model.Attribute;
import org.eclipse.persistence.internal.oxm.schema.model.AttributeGroup;
import org.eclipse.persistence.internal.oxm.schema.model.Choice;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexContent;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexType;
import org.eclipse.persistence.internal.oxm.schema.model.Element;
import org.eclipse.persistence.internal.oxm.schema.model.Extension;
import org.eclipse.persistence.internal.oxm.schema.model.Group;
import org.eclipse.persistence.internal.oxm.schema.model.Import;
import org.eclipse.persistence.internal.oxm.schema.model.Include;
import org.eclipse.persistence.internal.oxm.schema.model.List;
import org.eclipse.persistence.internal.oxm.schema.model.NestedParticle;
import org.eclipse.persistence.internal.oxm.schema.model.Occurs;
import org.eclipse.persistence.internal.oxm.schema.model.Restriction;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.oxm.schema.model.Sequence;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleComponent;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleContent;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleType;
import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticle;
import org.eclipse.persistence.internal.oxm.schema.model.Union;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.sdo.helper.extension.SDOUtil;
import org.eclipse.persistence.sdo.types.SDODataType;
import org.eclipse.persistence.sdo.types.SDOWrapperType;
import org.eclipse.persistence.sessions.Project;

import commonj.sdo.Property;
import commonj.sdo.Type;
import commonj.sdo.helper.HelperContext;

/**
 * <p><b>Purpose</b>: Called from XSDHelper define methods to generate SDO Types from a Schema
 *
 * @see commonj.sdo.helper.XSDHelper
 */
public class SDOTypesGenerator {
    private Project schemaProject;
    private Schema rootSchema;
    private HashMap processedComplexTypes;
    private HashMap processedSimpleTypes;
    private HashMap processedElements;
    private HashMap processedAttributes;
    private Map itemNameToSDOName;
    private boolean processImports;
    private boolean returnAllTypes;
    private java.util.List<NamespaceResolver> namespaceResolvers;
    private boolean inRestriction;
    // hold the context containing all helpers so that we can preserve inter-helper relationships
    private HelperContext aHelperContext;

    private java.util.List<SDOType> anonymousTypes;
    private java.util.Map<QName, Type> generatedTypes;
    private java.util.Map<QName, SDOType> generatedTypesByXsdQName;
    private java.util.Map<QName, Property> generatedGlobalElements;
    private java.util.Map<QName, Property> generatedGlobalAttributes;
    private String packageName;
    private java.util.List<NonContainmentReference> nonContainmentReferences;
    private Map<Type, java.util.List<GlobalRef>> globalRefs;
    private boolean isImportProcessor;

    public SDOTypesGenerator(HelperContext aContext) {
        anonymousTypes = new ArrayList<SDOType>();
        generatedTypesByXsdQName = new HashMap<QName, SDOType>();
        processedComplexTypes = new HashMap();
        processedSimpleTypes = new HashMap();
        processedElements = new HashMap();
        processedAttributes = new HashMap();
        itemNameToSDOName = new HashMap();
        namespaceResolvers = new ArrayList();
        this.aHelperContext = aContext;
    }

    public java.util.List<Type> define(Source xsdSource, SchemaResolver schemaResolver) {
        return define(xsdSource, schemaResolver, false, true);
    }

    public java.util.List<Type> define(Source xsdSource, SchemaResolver schemaResolver, boolean includeAllTypes, boolean processImports) {
        Schema schema = getSchema(xsdSource, schemaResolver, false);
        return define(schema, includeAllTypes, processImports);
    }

    public java.util.List<Type> define(Schema schema, boolean includeAllTypes, boolean processImports) {
        // Initialize the List of Types before we process the schema
        java.util.List<Type> returnList = new ArrayList<Type>();

        setReturnAllTypes(includeAllTypes);
        setProcessImports(processImports);
        processSchema(schema);

        returnList.addAll(getGeneratedTypes().values());
        returnList.addAll(anonymousTypes);

        if (!this.isImportProcessor()) {
            java.util.List descriptorsToAdd = new ArrayList(returnList);
            Iterator<Type> iter = descriptorsToAdd.iterator();
            while (iter.hasNext()) {
                SDOType nextSDOType = (SDOType) iter.next();
                if (!nextSDOType.isFinalized()) {
                    //Only throw this error if we're not processing an import.
                    throw SDOException.typeReferencedButNotDefined(nextSDOType.getURI(), nextSDOType.getName());
                }

                Iterator<Property> propertiesIter = nextSDOType.getProperties().iterator();
                while (propertiesIter.hasNext()) {
                    SDOProperty prop = (SDOProperty) propertiesIter.next();
                    if (prop.getType().isDataType() && prop.isContainment()) {
                        // If isDataType is true, then isContainment has to be false.
                        // This property was likely created as a stub, and isContainment never got reset
                        // when the property was fully defined.
                        // This problem was uncovered in bug 6809767
                        prop.setContainment(false);
                    }
                }

            }
            Iterator<Property> propertiesIter = getGeneratedGlobalElements().values().iterator();
            while (propertiesIter.hasNext()) {
                SDOProperty nextSDOProperty = (SDOProperty) propertiesIter.next();
                if (!nextSDOProperty.isFinalized()) {
                    //Only throw this error if we're not processing an import.
                    throw SDOException.referencedPropertyNotFound(nextSDOProperty.getUri(), nextSDOProperty.getName());
                }
            }

            propertiesIter = getGeneratedGlobalAttributes().values().iterator();
            while (propertiesIter.hasNext()) {
                SDOProperty nextSDOProperty = (SDOProperty) propertiesIter.next();
                if (!nextSDOProperty.isFinalized()) {
                    //Only throw this error if we're not processing an import.
                    throw SDOException.referencedPropertyNotFound(nextSDOProperty.getUri(), nextSDOProperty.getName());
                }
            }

            iter = getGeneratedTypes().values().iterator();
            //If we get here all types were finalized correctly
            while (iter.hasNext()) {
                SDOType nextSDOType = (SDOType) iter.next();
                ((SDOTypeHelper) aHelperContext.getTypeHelper()).addType(nextSDOType);
            }

            Iterator<SDOType> anonymousIterator = getAnonymousTypes().iterator();

            while (anonymousIterator.hasNext()) {
                SDOType nextSDOType = anonymousIterator.next();
                ((SDOTypeHelper) aHelperContext.getTypeHelper()).getAnonymousTypes().add(nextSDOType);
            }

            // add any base types to the list
            for (int i=0; i<descriptorsToAdd.size(); i++) {
                SDOType nextSDOType = (SDOType) descriptorsToAdd.get(i);
                if (!nextSDOType.isDataType() && !nextSDOType.isSubType() && nextSDOType.isBaseType()) {
                    nextSDOType.setupInheritance(null);
                } else if (!nextSDOType.isDataType() && nextSDOType.isSubType() && !getGeneratedTypes().values().contains(nextSDOType.getBaseTypes().get(0))) {
                    SDOType baseType = (SDOType) nextSDOType.getBaseTypes().get(0);
                    while (baseType != null) {
                        descriptorsToAdd.add(baseType);
                        if (baseType.getBaseTypes().size() == 0) {
                            // baseType should now be root of inheritance
                            baseType.setupInheritance(null);
                            baseType = null;
                        } else {
                            baseType = (SDOType) baseType.getBaseTypes().get(0);
                        }
                    }
                }
            }

            ((SDOXMLHelper) aHelperContext.getXMLHelper()).addDescriptors(descriptorsToAdd);

            //go through generatedGlobalProperties and add to xsdhelper
            Iterator<QName> qNameIter = getGeneratedGlobalElements().keySet().iterator();
            while (qNameIter.hasNext()) {
                QName nextQName = qNameIter.next();
                SDOProperty nextSDOProperty = (SDOProperty) getGeneratedGlobalElements().get(nextQName);
                ((SDOXSDHelper) aHelperContext.getXSDHelper()).addGlobalProperty(nextQName, nextSDOProperty, true);
            }

            qNameIter = getGeneratedGlobalAttributes().keySet().iterator();
            while (qNameIter.hasNext()) {
                QName nextQName = qNameIter.next();
                SDOProperty nextSDOProperty = (SDOProperty) getGeneratedGlobalAttributes().get(nextQName);
                ((SDOXSDHelper) aHelperContext.getXSDHelper()).addGlobalProperty(nextQName, nextSDOProperty, false);
            }

            Iterator<java.util.List<GlobalRef>> globalRefsIter = getGlobalRefs().values().iterator();
            while (globalRefsIter.hasNext()) {
                java.util.List<GlobalRef> nextList = globalRefsIter.next();
                if (nextList.size() > 0) {
                    GlobalRef ref = nextList.get(0);
                    throw SDOException.referencedPropertyNotFound(((SDOProperty) ref.getProperty()).getUri(), ref.getProperty().getName());
                }
            }
        }

        return returnList;
    }

    private void processSchema(Schema parsedSchema) {
        rootSchema = parsedSchema;
        initialize();
        namespaceResolvers.add(rootSchema.getNamespaceResolver());
        processIncludes(rootSchema.getIncludes());
        processImports(rootSchema.getImports());
        preprocessGlobalTypes(rootSchema);
        processGlobalAttributes(rootSchema);
        processGlobalElements(rootSchema);
        processGlobalSimpleTypes(rootSchema);
        processGlobalComplexTypes(rootSchema);

        postProcessing();
    }

    private void processImports(java.util.List imports) {
        if ((imports == null) || (imports.size() == 0) || !isProcessImports()) {
            return;
        }
        Iterator iter = imports.iterator();
        while (iter.hasNext()) {
            Import nextImport = (Import) iter.next();
            try {
                processImportIncludeInternal(nextImport);
            } catch (Exception e) {
                throw SDOException.errorProcessingImport(nextImport.getSchemaLocation(), nextImport.getNamespace(), e);
            }
        }
    }

    private void processIncludes(java.util.List includes) {
        if ((includes == null) || (includes.size() == 0) || !isProcessImports()) {
            return;
        }
        Iterator iter = includes.iterator();
        while (iter.hasNext()) {
            Include nextInclude = (Include) iter.next();
            try {
                processImportIncludeInternal(nextInclude);
            } catch (Exception e) {
                throw SDOException.errorProcessingInclude(nextInclude.getSchemaLocation(), e);
            }
        }
    }

    /**
     * INTERNAL:
     * This function is referenced by processImport or processInclude possibly recursively
     * @param theImportOrInclude theImportOrInclude
     * @throws Exception
     */
    private void processImportIncludeInternal(Include theImportOrInclude) throws Exception {
        if (theImportOrInclude.getSchema() != null) {
            SDOTypesGenerator generator = new SDOTypesGenerator(aHelperContext);
            generator.setAnonymousTypes(getAnonymousTypes());
            generator.setGeneratedTypes(getGeneratedTypes());
            generator.setGeneratedTypesByXsdQName(getGeneratedTypesByXsdQName());
            generator.setGeneratedGlobalElements(getGeneratedGlobalElements());
            generator.setGeneratedGlobalAttributes(getGeneratedGlobalAttributes());
            // Both imports and includes are treated the same when checking for a mid-schema tree walk state
            generator.setIsImportProcessor(true);
            // May throw an IAE if a global type: local part cannot be null when creating a QName
            java.util.List<Type> importedTypes = generator.define(theImportOrInclude.getSchema(), isReturnAllTypes(), isProcessImports());
            processedComplexTypes.putAll(generator.processedComplexTypes);
            processedSimpleTypes.putAll(generator.processedSimpleTypes);
            processedElements.putAll(generator.processedElements);
            processedAttributes.putAll(generator.processedAttributes);
            for (int i = 0, size = importedTypes.size(); i < size; i++) {
                SDOType nextType = (SDOType) importedTypes.get(i);
                getGeneratedTypes().put(nextType.getQName(), nextType);
            }

            //copy over any global properties
            Iterator<QName> globalPropsIter = generator.getGeneratedGlobalElements().keySet().iterator();
            while (globalPropsIter.hasNext()) {
                QName nextKey = globalPropsIter.next();
                getGeneratedGlobalElements().put(nextKey, generator.getGeneratedGlobalElements().get(nextKey));
            }

            globalPropsIter = generator.getGeneratedGlobalAttributes().keySet().iterator();
            while (globalPropsIter.hasNext()) {
                QName nextKey = globalPropsIter.next();
                getGeneratedGlobalAttributes().put(nextKey, generator.getGeneratedGlobalAttributes().get(nextKey));
            }

            //copy over any unfinished globalRefs
            Iterator<Type> globalRefsIter = generator.getGlobalRefs().keySet().iterator();
            while (globalRefsIter.hasNext()) {
                Type nextKey = globalRefsIter.next();
                getGlobalRefs().put(nextKey, generator.getGlobalRefs().get(nextKey));
            }
        }
    }

    private boolean typesExists(String targetNamespace, String sdoTypeName) {
        boolean alreadyProcessed = false;

        if ((targetNamespace != null) && (targetNamespace.equals(SDOConstants.SDOJAVA_URL) || targetNamespace.equals(SDOConstants.SDO_URL) || targetNamespace.equals(SDOConstants.SDOXML_URL))) {
            alreadyProcessed = true;
        } else {
            QName qname = new QName(targetNamespace, sdoTypeName);
            Object processed = processedComplexTypes.get(qname);
            if (processed != null) {
                alreadyProcessed = true;
            }
        }

        if (!alreadyProcessed) {
            SDOType lookup = (SDOType) aHelperContext.getTypeHelper().getType(targetNamespace, sdoTypeName);
            if ((lookup != null) && lookup.isFinalized()) {
                if (isReturnAllTypes()) {
                    QName qname = new QName(targetNamespace, sdoTypeName);
                    getGeneratedTypes().put(qname, lookup);
                }
                return true;
            } else if (lookup == null) {
                QName qname = new QName(targetNamespace, sdoTypeName);
                SDOType processed = (SDOType) getGeneratedTypes().get(qname);
                if (processed != null && processed.isFinalized()) {
                    alreadyProcessed = true;
                }
            }
        }

        return alreadyProcessed;
    }

    private void processGlobalComplexTypes(Schema schema) {
        Collection complexTypes = schema.getTopLevelComplexTypes().values();
        if (complexTypes == null) {
            return;
        }

        Iterator complexTypesIter = complexTypes.iterator();
        while (complexTypesIter.hasNext()) {
            ComplexType complexType = (ComplexType) complexTypesIter.next();
            String targetNamespace = schema.getTargetNamespace();
            if(null == targetNamespace) {
                targetNamespace = "";
            }
            processGlobalComplexType(targetNamespace, schema.getDefaultNamespace(), complexType);
        }
    }

    private void processGlobalComplexType(String targetNamespace, String defaultNamespace, ComplexType complexType) {
        QName qname = new QName(targetNamespace, complexType.getName());
        Object processed = processedComplexTypes.get(qname);

        if (processed == null) {
            processComplexType(targetNamespace, defaultNamespace, complexType.getName(), complexType);
            processedComplexTypes.put(qname, complexType);
        }
    }

    private SDOType processComplexType(String targetNamespace, String defaultNamespace, String name, ComplexType complexType) {
        if (complexType == null) {
            return null;
        }
        boolean addedNR = addNextNamespaceResolver(complexType.getAttributesMap());
        SDOType newType = startComplexType(targetNamespace, defaultNamespace, name, complexType);
        if (newType != null) {
            if (complexType.getComplexContent() != null) {
                processComplexContent(targetNamespace, defaultNamespace, complexType.getComplexContent(), newType);
                finishComplexType(newType);
            } else if (complexType.getSimpleContent() != null) {
                processSimpleContent(targetNamespace, defaultNamespace, complexType.getSimpleContent(), newType);
                finishComplexType(newType);
            } else {
                if (complexType.getChoice() != null) {
                    processChoice(targetNamespace, defaultNamespace, newType, complexType.getChoice(), false);
                } else if (complexType.getSequence() != null) {
                    processSequence(targetNamespace, defaultNamespace, newType, complexType.getSequence(), false);
                } else if (complexType.getAll() != null) {
                    processAll(targetNamespace, defaultNamespace, newType, complexType.getAll(), false);
                }

                processOrderedAttributes(targetNamespace, defaultNamespace, newType, complexType.getOrderedAttributes());
                finishComplexType(newType);
            }
        }
        if (addedNR) {
            namespaceResolvers.remove(namespaceResolvers.size() - 1);
        }

        return newType;
    }

    //return true if a new type was created
    private SDOType startComplexType(String targetNamespace, String defaultNamespace, String name, ComplexType complexType) {
        String nameValue = (String) complexType.getAttributesMap().get(SDOConstants.SDOXML_NAME_QNAME);
        String originalName = name;
        if (nameValue != null) {
            itemNameToSDOName.put(name, nameValue);
            originalName = name;
            name = nameValue;
        }

        //check if already processed, if yes return false because a new type was not started else start new type and return true
        boolean alreadyExists = false;
        if(null != complexType.getName()) {
            alreadyExists = typesExists(targetNamespace, name);
        }

        if (!alreadyExists) {
            return startNewComplexType(targetNamespace, name, originalName, complexType);
        }

        return null;
    }

    private SDOType startNewComplexType(String targetNamespace, String sdoTypeName, String xsdLocalName, ComplexType complexType) {
        SDOType currentType;
        if(null == complexType.getName()) {
            currentType = createSDOTypeForName(targetNamespace, sdoTypeName, xsdLocalName);
        } else {
            currentType = getGeneratedTypesByXsdQName().get(new QName(targetNamespace, complexType.getName()));
        }

        if (complexType.isMixed()) {
            currentType.setMixed(true);
            currentType.setSequenced(true);
            // currentType.setOpen(true); Remove as part of SDO JIRA-106
        }

        if (complexType.getAnyAttribute() != null) {
            currentType.setOpen(true);
        }
        currentType.setAbstract(complexType.isAbstractValue());
        currentType.setDataType(false);

        String value = (String) complexType.getAttributesMap().get(SDOConstants.SDOXML_ALIASNAME_QNAME);
        if (value != null) {
            XMLConversionManager xmlConversionManager = ((SDOXMLHelper) aHelperContext.getXMLHelper()).getXmlConversionManager();
            java.util.List names = xmlConversionManager.convertObject(value, java.util.List.class);
            currentType.setAliasNames(names);
        }

        String sequencedValue = (String) complexType.getAttributesMap().get(SDOConstants.SDOXML_SEQUENCE_QNAME);
        if (sequencedValue != null) {
            currentType.setSequenced(Boolean.parseBoolean(sequencedValue));
        }
        Annotation annotation = complexType.getAnnotation();
        if (annotation != null) {
            java.util.List documentation = annotation.getDocumentation();
            if ((documentation != null) && (documentation.size() > 0)) {
                currentType.setInstanceProperty(SDOConstants.DOCUMENTATION_PROPERTY, documentation);
            }
        }
        currentType.preInitialize(packageName, namespaceResolvers);
        if (complexType.getAnnotation() != null) {
            currentType.setAppInfoElements(complexType.getAnnotation().getAppInfo());
        }

        return currentType;
    }

    private void finishComplexType(SDOType currentType) {
        currentType.postInitialize();
    }

    private void processOrderedAttributes(String targetNamespace, String defaultNamespace, SDOType owningType, java.util.List orderedAttributes) {
        for (int i = 0; i < orderedAttributes.size(); i++) {
            Object next = orderedAttributes.get(i);
            if (next instanceof Attribute) {
                processAttribute(targetNamespace, defaultNamespace, owningType, (Attribute) next, false);
            } else if (next instanceof AttributeGroup) {
                processAttributeGroup(targetNamespace, defaultNamespace, owningType, (AttributeGroup) next);
            }
        }
    }

    private void processGlobalAttributes(Schema schema) {
        Collection attributes = schema.getTopLevelAttributes().values();
        if (attributes == null) {
            return;
        }
        Iterator attributesIter = attributes.iterator();
        while (attributesIter.hasNext()) {
            Attribute nextAttribute = (Attribute) attributesIter.next();
            String targetNamespace = schema.getTargetNamespace();
            if(null == targetNamespace) {
                targetNamespace = "";
            }
            processGlobalAttribute(targetNamespace, schema.getDefaultNamespace(), nextAttribute);
        }
    }

    private void processGlobalAttribute(String targetNamespace, String defaultNamespace, Attribute attribute) {
        if (attribute.getName() != null) {
            QName qname = new QName(targetNamespace, attribute.getName());
            Object processed = processedAttributes.get(qname);

            if (processed == null) {
                SDOType attributeType = processAttribute(targetNamespace, defaultNamespace, null, attribute, true);
                processedAttributes.put(qname, attribute);
                if(null != attributeType && !getGeneratedTypes().containsKey(attributeType.getQName())) {
                    getGeneratedTypes().put(attributeType.getQName(), attributeType);
                    anonymousTypes.remove(attributeType);
                }
            }
        } else {
            processAttribute(targetNamespace, defaultNamespace, null, attribute, true);
        }
    }

    private void processGroup(String targetNamespace, String defaultNamespace, SDOType owningType, TypeDefParticle typeDefParticle, Group group, boolean isMany) {
        if (!isMany && maxOccursGreaterThanOne(group.getMaxOccurs())) {
            isMany = true;
        }

        String groupName = group.getRef();
        if (groupName != null) {
            int idx = groupName.indexOf(':');
            String prefix = null;
            String localName = null;
            String uri = null;
            if (idx > -1) {
                localName = groupName.substring(idx + 1, groupName.length());
                prefix = groupName.substring(0, idx);
                uri = getURIForPrefix(prefix);
            } else {
                localName = groupName;
                uri = targetNamespace;
            }
            Group globalGroup = rootSchema.getGroup(uri, localName);
            if (globalGroup != null) {
                if (globalGroup.getChoice() != null) {
                    globalGroup.getChoice().setMaxOccurs(group.getMaxOccurs());
                    processChoice(targetNamespace, defaultNamespace, owningType, globalGroup.getChoice(), isMany);
                } else if (globalGroup.getSequence() != null) {
                    globalGroup.getSequence().setMaxOccurs(group.getMaxOccurs());
                    processSequence(targetNamespace, defaultNamespace, owningType, globalGroup.getSequence(), isMany);
                } else if (globalGroup.getAll() != null) {
                    globalGroup.getAll().setMaxOccurs(group.getMaxOccurs());
                    processAll(targetNamespace, defaultNamespace, owningType, globalGroup.getAll(), isMany);
                }
            }
        }
    }

    private SDOType processAttribute(String targetNamespace, String defaultNamespace, SDOType owningType, Attribute attribute, boolean isGlobal) {
        SimpleType simpleType = attribute.getSimpleType();
        if (simpleType != null) {
            SDOType propertyType = processSimpleType(targetNamespace, defaultNamespace, attribute.getName(), simpleType);
            processSimpleAttribute(targetNamespace, defaultNamespace, owningType, attribute, isGlobal, rootSchema.isAttributeFormDefault(), propertyType);
            propertyType.setXsdLocalName(attribute.getName());
            propertyType.setXsd(true);
            return propertyType;
        } else {
            processSimpleAttribute(targetNamespace, defaultNamespace, owningType, attribute, isGlobal, rootSchema.isAttributeFormDefault() || isGlobal, null);
            return null;
        }
    }

    private void processAttributeGroup(String targetNamespace, String defaultNamespace, SDOType owningType, AttributeGroup attributeGroup) {
        String attributeGroupName = attributeGroup.getRef();
        if (attributeGroupName != null) {
            int idx = attributeGroupName.indexOf(':');
            String prefix = null;
            String localName = null;
            String uri = null;
            if (idx > -1) {
                localName = attributeGroupName.substring(idx + 1, attributeGroupName.length());
                prefix = attributeGroupName.substring(0, idx);
                uri = getURIForPrefix(prefix);
            } else {
                localName = attributeGroupName;
                uri = targetNamespace;
            }
            AttributeGroup globalAttributeGroup = rootSchema.getAttributeGroup(uri, localName);
            if (globalAttributeGroup != null) {
                int size = globalAttributeGroup.getAttributes().size();
                if (globalAttributeGroup.getAnyAttribute() != null) {
                    processAnyAttribute(targetNamespace, defaultNamespace, owningType);
                }
                for (int j = 0; j < size; j++) {
                    processAttribute(targetNamespace, defaultNamespace, owningType, (Attribute) globalAttributeGroup.getAttributes().get(j), false);
                }
            }
        }
    }

    private void processAttributes(String targetNamespace, String defaultNamespace, SDOType owningType, java.util.List attributes) {
        if (attributes == null) {
            return;
        }
        for (int i = 0; i < attributes.size(); i++) {
            Attribute nextAttribute = (Attribute) attributes.get(i);
            processAttribute(targetNamespace, defaultNamespace, owningType, nextAttribute, false);
        }
    }

    private void processGlobalSimpleTypes(Schema schema) {
        Collection simpleTypes = schema.getTopLevelSimpleTypes().values();
        if (simpleTypes == null) {
            return;
        }

        Iterator simpleTypesIter = simpleTypes.iterator();
        while (simpleTypesIter.hasNext()) {
            SimpleType simpleType = (SimpleType) simpleTypesIter.next();
            String targetNamespace = schema.getTargetNamespace();
            if(null == targetNamespace) {
                targetNamespace = "";
            }
            processGlobalSimpleType(targetNamespace, schema.getDefaultNamespace(), simpleType);
        }
    }

    private void processGlobalSimpleType(String targetNamespace, String defaultNamespace, SimpleType simpleType) {
        QName qname = new QName(targetNamespace, simpleType.getName());
        if (!processedSimpleTypes.containsKey(qname)) {
            processSimpleType(targetNamespace, defaultNamespace, simpleType.getName(), simpleType);
            processedSimpleTypes.put(qname, simpleType);
        }
    }

    private SDOType startSimpleType(String targetNamespace, String defaultNamespace, String name, String xsdLocalName, SimpleType simpleType) {
        boolean alreadyExists = typesExists(targetNamespace, name);
        if (!alreadyExists) {
            return startNewSimpleType(targetNamespace, defaultNamespace, name, xsdLocalName, simpleType);
        }
        if(this.returnAllTypes) {
            return this.getExisitingType(targetNamespace, name);
        } else {
            return null;
        }
    }

    private SDOType startNewSimpleType(String targetNamespace, String defaultNamespace, String sdoTypeName, String xsdLocalName, SimpleType simpleType) {
        SDOType currentType;
         if(null == simpleType.getName()) {
            currentType = createSDOTypeForName(targetNamespace, sdoTypeName, xsdLocalName);
            currentType.setDataType(true);
        } else {
            currentType = getGeneratedTypesByXsdQName().get(new QName(targetNamespace, simpleType.getName()));
        }

        // Defining a new simple type from XSD.
        // See also: SDOTypeHelperDelegate:define for "types from DataObjects" equivalent

        SDOTypeHelper typeHelper = ((SDOTypeHelper) aHelperContext.getTypeHelper());

        // If this simple type is a restriction, get the QName for the base type and
        // include it when creating the WrapperType.  The QName will be used during
        // conversions (eg. "myBinaryElement" could be a restriction of base64Binary
        // or hexBinary.

        QName baseTypeQName = null;
        if (simpleType.getRestriction() != null) {
            String baseType = simpleType.getRestriction().getBaseType();
            baseTypeQName = this.getQNameForString(defaultNamespace, baseType);
            SDOType baseSDOType = getTypeForXSDQName(baseTypeQName);
            currentType.addBaseType(baseSDOType);

            currentType.setInstanceClass(baseSDOType.getInstanceClass());
        }

        // Create the new WrapperType
        SDOWrapperType wrapperType = new SDOWrapperType(currentType, sdoTypeName, typeHelper, baseTypeQName);

        // Register WrapperType with maps on TypeHelper
        typeHelper.getWrappersHashMap().put(currentType.getQName(), wrapperType);
        typeHelper.getTypesHashMap().put(wrapperType.getQName(), wrapperType);
        typeHelper.getImplClassesToSDOType().put(wrapperType.getXmlDescriptor().getJavaClass(), wrapperType);

        // Add descriptor to XMLHelper
        ArrayList list = new ArrayList(1);
        list.add(wrapperType);
        ((SDOXMLHelper) aHelperContext.getXMLHelper()).addDescriptors(list);

        if (simpleType.getAnnotation() != null) {
            currentType.setAppInfoElements(simpleType.getAnnotation().getAppInfo());
        }

        return currentType;
    }

    private SDOType processSimpleType(String targetNamespace, String defaultNamespace, String sdoTypeName, SimpleType simpleType) {
        if (simpleType == null) {
            return null;
        }
        boolean addedNR = addNextNamespaceResolver(simpleType.getAttributesMap());
        String name = sdoTypeName;
        String originalName = name;
        String nameValue = (String) simpleType.getAttributesMap().get(SDOConstants.SDOXML_NAME_QNAME);
        if (nameValue != null) {
            itemNameToSDOName.put(sdoTypeName, nameValue);
            name = nameValue;
        }

        SDOType newType = startSimpleType(targetNamespace, defaultNamespace, name, originalName, simpleType);
        if (newType != null) {
            Restriction restriction = simpleType.getRestriction();

            if (restriction != null) {
                processRestriction(targetNamespace, defaultNamespace, newType, restriction);
            }
            List list = simpleType.getList();
            if (list != null) {
                processList(targetNamespace, defaultNamespace, sdoTypeName, list, newType);
            }

            Union union = simpleType.getUnion();
            if (union != null) {
                processUnion(targetNamespace, defaultNamespace, sdoTypeName, union, newType);
            }

            finishSimpleType(targetNamespace, defaultNamespace, sdoTypeName, simpleType, newType);
        }
        if (addedNR) {
            namespaceResolvers.remove(namespaceResolvers.size() - 1);
        }

        return newType;
    }

    private void finishSimpleType(String targetNamespace, String defaultNamespace, String sdoTypeName, SimpleType simpleType, SDOType currentType) {
        String value = (String) simpleType.getAttributesMap().get(SDOConstants.SDOXML_ALIASNAME_QNAME);
        if (value != null) {
            XMLConversionManager xmlConversionManager = ((SDOXMLHelper) aHelperContext.getXMLHelper()).getXmlConversionManager();
            java.util.List names = xmlConversionManager.convertObject(value, java.util.List.class);
            currentType.setAliasNames(names);
        }

        String instanceClassValue = (String) simpleType.getAttributesMap().get(SDOConstants.SDOJAVA_INSTANCECLASS_QNAME);
        if (instanceClassValue != null) {
            currentType.setInstanceProperty(SDOConstants.JAVA_CLASS_PROPERTY, instanceClassValue);
            currentType.setBaseTypes(null);
        }

        String extendedInstanceClassValue = (String) simpleType.getAttributesMap().get(SDOConstants.SDOJAVA_EXTENDEDINSTANCECLASS_QNAME);
        if (extendedInstanceClassValue != null) {
            currentType.setInstanceClassName(extendedInstanceClassValue);
        }
        currentType.postInitialize();
    }

    private void processChoice(String targetNamespace, String defaultNamespace, SDOType owningType, Choice choice, boolean isMany) {
        if (choice != null) {
            processTypeDef(targetNamespace, defaultNamespace, owningType, choice);

            java.util.List orderedItems = choice.getOrderedElements();
            for (int i = 0; i < orderedItems.size(); i++) {
                Object next = orderedItems.get(i);
                if (!isMany && maxOccursGreaterThanOne(choice.getMaxOccurs())) {
                    isMany = true;
                }

                if (next instanceof Choice) {
                    processChoice(targetNamespace, defaultNamespace, owningType, (Choice) next, isMany);
                } else if (next instanceof Sequence) {
                    processSequence(targetNamespace, defaultNamespace, owningType, (Sequence) next, isMany);
                } else if (next instanceof Any) {
                    processAny(targetNamespace, defaultNamespace, (Any) next, owningType, choice);//isMany??
                } else if (next instanceof Element) {
                    processElement(targetNamespace, defaultNamespace, owningType, choice, (Element) next, false, isMany);
                } else if (next instanceof Group) {
                    processGroup(targetNamespace, defaultNamespace, owningType, choice, (Group) next, isMany);
                }
            }
        }
    }

    private void processSequence(String targetNamespace, String defaultNamespace, SDOType owningType, Sequence sequence, boolean isMany) {
        if (sequence != null) {
            processTypeDef(targetNamespace, defaultNamespace, owningType, sequence);

            java.util.List orderedItems = sequence.getOrderedElements();
            for (int i = 0; i < orderedItems.size(); i++) {
                Object next = orderedItems.get(i);
                if (!isMany && maxOccursGreaterThanOne(sequence.getMaxOccurs())) {
                    isMany = true;
                }
                if (next instanceof Choice) {
                    processChoice(targetNamespace, defaultNamespace, owningType, (Choice) next, isMany);
                } else if (next instanceof Sequence) {
                    processSequence(targetNamespace, defaultNamespace, owningType, (Sequence) next, isMany);
                } else if (next instanceof Any) {
                    processAny(targetNamespace, defaultNamespace, (Any) next, owningType, sequence);//isMany?
                } else if (next instanceof Element) {
                    processElement(targetNamespace, defaultNamespace, owningType, sequence, (Element) next, false, isMany);
                } else if (next instanceof Group) {
                    processGroup(targetNamespace, defaultNamespace, owningType, sequence, (Group) next, isMany);
                }
            }
        }
    }

    private void processAll(String targetNamespace, String defaultNamespace, SDOType owningType, All all, boolean isMany) {
        if (all != null) {
            owningType.setSequenced(true);

            processTypeDef(targetNamespace, defaultNamespace, owningType, all);
            if (!isMany && maxOccursGreaterThanOne(all.getMaxOccurs())) {
                isMany = true;
            }
            java.util.List elements = all.getElements();
            for (int i = 0; i < elements.size(); i++) {
                Object next = elements.get(i);
                if (next instanceof Element) {
                    processElement(targetNamespace, defaultNamespace, owningType, all, (Element) next, false, isMany);
                }
            }
        }
    }

    private void processComplexContent(String targetNamespace, String defaultNamespace, ComplexContent complexContent, SDOType owningType) {
        if (complexContent != null) {
            if (complexContent.getExtension() != null) {
                processExtension(targetNamespace, defaultNamespace, owningType, complexContent.getExtension(), false);
            } else if (complexContent.getRestriction() != null) {
                processRestriction(targetNamespace, defaultNamespace, owningType, complexContent.getRestriction());
            }
        }
    }

    private void processSimpleContent(String targetNamespace, String defaultNamespace, SimpleContent simpleContent, SDOType owningType) {
        if (simpleContent != null) {
            if (simpleContent.getExtension() != null) {
                processExtension(targetNamespace, defaultNamespace, owningType, simpleContent.getExtension(), true);
            } else {
                if (simpleContent.getRestriction() != null) {
                    processRestriction(targetNamespace, defaultNamespace, owningType, simpleContent.getRestriction());
                }
            }
        }
    }

    private void processExtension(String targetNamespace, String defaultNamespace, SDOType owningType, Extension extension, boolean simpleContent) {
        if (extension != null) {
            String qualifiedType = extension.getBaseType();
            SDOType baseType = getSDOTypeForName(targetNamespace, defaultNamespace, qualifiedType);
            QName baseQName = getQNameForString(defaultNamespace, qualifiedType);

            if(baseType != null) {
                if(!baseType.isFinalized() && baseQName.getNamespaceURI().equals(targetNamespace)) {
                    if(baseType.isDataType()) {
                        SimpleType baseSimpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(baseQName.getLocalPart());
                        if(baseSimpleType != null){
                            processGlobalSimpleType(targetNamespace, defaultNamespace, baseSimpleType);
                        }
                    } else {
                        ComplexType baseComplexType = (ComplexType) rootSchema.getTopLevelComplexTypes().get(baseQName.getLocalPart());
                        if(baseComplexType != null){
                            processGlobalComplexType(targetNamespace, defaultNamespace, baseComplexType);
                        }
                    }
                }
                owningType.setOpen(owningType.isOpen() || baseType.isOpen());
            }
            if (qualifiedType != null) {
                processBaseType(baseType, targetNamespace, defaultNamespace, owningType, qualifiedType, simpleContent);
            }
            if (extension.getChoice() != null) {
                processChoice(targetNamespace, defaultNamespace, owningType, extension.getChoice(), false);
            } else if (extension.getSequence() != null) {
                processSequence(targetNamespace, defaultNamespace, owningType, extension.getSequence(), false);
            } else if (extension.getAll() != null) {
            }

            processOrderedAttributes(targetNamespace, defaultNamespace, owningType, extension.getOrderedAttributes());
        }
    }

    private void processRestriction(String targetNamespace, String defaultNamespace, SDOType owningType, Restriction restriction) {
        if (restriction != null) {
            String qualifiedType = restriction.getBaseType();
            Type baseType = processBaseType(targetNamespace, defaultNamespace, owningType, qualifiedType, false, restriction);
            boolean alreadyIn = inRestriction;
            if (!alreadyIn) {
                inRestriction = true;
            }

            if (restriction.getChoice() != null) {
                processChoice(targetNamespace, defaultNamespace, owningType, restriction.getChoice(), false);
            } else if (restriction.getSequence() != null) {
                processSequence(targetNamespace, defaultNamespace, owningType, restriction.getSequence(), false);
            } else if (restriction.getAll() != null) {
                processAll(targetNamespace, defaultNamespace, owningType, restriction.getAll(), false);
            }

            processAttributes(targetNamespace, defaultNamespace, owningType, restriction.getAttributes());
            if (!alreadyIn) {
                inRestriction = false;
            }
            owningType.setOpen(owningType.isOpen() || baseType.isOpen());
        }
    }

    private void processUnion(String targetNamespace, String defaultNamespace, String sdoTypeName, Union union, SDOType type) {
        if (union != null) {
            java.util.List allMemberTypes = union.getAllMemberTypes();
            String firstInstanceClassName = null;
            for (int i = 0; i < allMemberTypes.size(); i++) {
                String nextMemberType = (String) allMemberTypes.get(i);
                SDOType typeForMemberType = getTypeForName(targetNamespace, defaultNamespace, nextMemberType);
                QName baseQName = this.getQNameForString(defaultNamespace, nextMemberType);
                if(!typeForMemberType.isFinalized() && baseQName.getNamespaceURI().equals(targetNamespace)) {
                    SimpleType baseSimpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(baseQName.getLocalPart());
                    processSimpleType(targetNamespace, defaultNamespace, baseQName.getLocalPart(), baseSimpleType);
                }
                if (i == 0) {
                    firstInstanceClassName = typeForMemberType.getInstanceClassName();
                    if (firstInstanceClassName == null) {
                        break;
                    }
                } else {
                    String nextClassName = typeForMemberType.getInstanceClassName();
                    if (!firstInstanceClassName.equals(nextClassName)) {
                        type.setInstanceClass(java.lang.Object.class);
                        return;
                    }
                }

            }
            if (firstInstanceClassName != null) {
                type.setInstanceClassName(firstInstanceClassName);
            } else {
                type.setInstanceClass(java.lang.Object.class);
            }
        }
    }

    private boolean addNextNamespaceResolver(Map attributesMap) {
        NamespaceResolver nr = new NamespaceResolver();
        Iterator iter = attributesMap.keySet().iterator();
        while (iter.hasNext()) {
            QName key = (QName) iter.next();
            if (key.getNamespaceURI().equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
                String value = (String) attributesMap.get(key);
                String prefix = key.getLocalPart();
                int index = prefix.indexOf(':');
                if (index > -1) {
                    prefix = prefix.substring(index + 1, prefix.length());
                }
                nr.put(prefix, value);
            }
        }
        if (nr.getPrefixes().hasMoreElements()) {
            namespaceResolvers.add(nr);
            return true;
        }
        return false;
    }

    private void processList(String targetNamespace, String defaultNamespace, String sdoTypeName, List list, SDOType type) {
        if (list != null) {
            type.setXsdList(true);
            type.setInstanceClass(ClassConstants.List_Class);
        }
    }

    private Type processBaseType(String targetNamespace, String defaultNamespace, SDOType owningType, String qualifiedName, boolean simpleContentExtension, Restriction restriction) {
        if (qualifiedName == null) {
            return null;
        }

        SDOType baseType = getSDOTypeForName(targetNamespace, defaultNamespace, qualifiedName);
        QName baseQName = getQNameForString(defaultNamespace, qualifiedName);

        if(!baseType.isFinalized() && baseQName.getNamespaceURI().equals(targetNamespace)) {
            if(baseType.isDataType()) {
                SimpleType baseSimpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(baseQName.getLocalPart());
                processGlobalSimpleType(targetNamespace, defaultNamespace, baseSimpleType);
            } else {
                ComplexType baseComplexType = (ComplexType) rootSchema.getTopLevelComplexTypes().get(baseQName.getLocalPart());
                processGlobalComplexType(targetNamespace, defaultNamespace, baseComplexType);
            }
        }

        // When the XSD type is one of the following, and there are facets (maxInclusive,
        // maxExclusive) constraining the range to be within the range of int then the
        // Java instance class is int
        if (baseQName.equals(XMLConstants.INTEGER_QNAME) ||
                baseQName.equals(SDOConstants.POSITIVEINTEGER_QNAME) ||
                baseQName.equals(SDOConstants.NEGATIVEINTEGER_QNAME) ||
                baseQName.equals(SDOConstants.NONPOSITIVEINTEGER_QNAME) ||
                baseQName.equals(SDOConstants.NONNEGATIVEINTEGER_QNAME) ||
                baseQName.equals(XMLConstants.LONG_QNAME) ||
                baseQName.equals(SDOConstants.UNSIGNEDLONG_QNAME)) {

            boolean alreadySet = false;
            String value = restriction.getMaxInclusive();
            if (value != null) {
                if (Integer.parseInt(value) <= Integer.MAX_VALUE) {
                    baseType = getTypeForXSDQName(XMLConstants.INT_QNAME);
                    alreadySet = true;
                }
            }
            // if maxInclusive was processed, no need to handle maxExclusive
            if (!alreadySet) {
                value = restriction.getMaxExclusive();
                if (value != null) {
                    if (Integer.parseInt(value) < Integer.MAX_VALUE) {
                        baseType = getTypeForXSDQName(XMLConstants.INT_QNAME);
                    }
                }
            }
        }

        processBaseType(baseType, targetNamespace, defaultNamespace, owningType, qualifiedName, simpleContentExtension);
        return baseType;
    }

    private void processBaseType(SDOType baseType, String targetNamespace, String defaultNamespace, SDOType owningType, String qualifiedName, boolean simpleContentExtension) {
        if (simpleContentExtension && baseType.isDataType()) {
            if (owningType != null) {
                SDOProperty prop = new SDOProperty(aHelperContext);
                prop.setName("value");
                prop.setType(baseType);
                prop.setValueProperty(true);
                prop.setInstanceProperty(SDOConstants.XMLELEMENT_PROPERTY, Boolean.TRUE);
                owningType.addDeclaredProperty(prop);
                prop.buildMapping(null, -1);
                prop.setFinalized(true);

            }
            return;
        }

        java.util.List<Type> baseTypes = new ArrayList<Type>();
        baseTypes.add(baseType);

        if (owningType != null) {
            if (owningType.isDataType()) {
                owningType.setInstanceClassName(baseType.getInstanceClassName());
                if (baseType.getInstanceClass() != null) {
                    owningType.setInstanceClass(baseType.getInstanceClass());
                }

                QName baseQName = getQNameForString(defaultNamespace, qualifiedName);
                if ((baseQName.equals(XMLConstants.BASE_64_BINARY_QNAME)) || (baseQName.equals(XMLConstants.HEX_BINARY_QNAME)) || (baseQName.equals(XMLConstants.DATE_QNAME)) || (baseQName.equals(XMLConstants.TIME_QNAME))
                        || (baseQName.equals(XMLConstants.DATE_TIME_QNAME))) {
                    owningType.setXsdType(baseQName);
                }
            }

            if (!owningType.getBaseTypes().contains(baseType)) {
                owningType.addBaseType(baseType);
            }
        }
    }

    private void processTypeDef(String targetNamespace, String defaultNamespace, SDOType owningType, TypeDefParticle typeDefParticle) {
        if (maxOccursGreaterThanOne(typeDefParticle.getMaxOccurs())) {
            if (!owningType.isSequenced() && shouldBeSequenced(typeDefParticle)) {
                owningType.setSequenced(true);
            }
        }
    }

    private boolean shouldBeSequenced(TypeDefParticle typeDefParticle) {
        java.util.List elements = typeDefParticle.getElements();
        if ((elements != null) && (elements.size() > 1)) {
            return true;
        }
        if (typeDefParticle instanceof Sequence) {
            java.util.List allItems = ((Sequence) typeDefParticle).getOrderedElements();
            for (int i = 0; i < allItems.size(); i++) {
                Object nextItem = allItems.get(i);
                if (nextItem instanceof TypeDefParticle) {
                    boolean sequenced = shouldBeSequenced((TypeDefParticle) nextItem);
                    if (sequenced) {
                        return true;
                    }
                }
            }
        } else if (typeDefParticle instanceof Choice) {
            java.util.List allItems = ((Choice) typeDefParticle).getOrderedElements();
            for (int i = 0; i < allItems.size(); i++) {
                Object nextItem = allItems.get(i);
                if (nextItem instanceof TypeDefParticle) {
                    boolean sequenced = shouldBeSequenced((TypeDefParticle) nextItem);
                    if (sequenced) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void processAny(String targetNamespace, String defaultNamespace, Any any, SDOType owningType, TypeDefParticle typeDefParticle) {
        if (any == null) {
            return;
        }

        if (((NestedParticle) typeDefParticle).hasAny()) {
            owningType.setOpen(true);
            owningType.setSequenced(true);
        }

    }

    private void processGlobalElements(Schema schema) {
        Collection elements = schema.getTopLevelElements().values();
        if (elements == null) {
            return;
        }
        Iterator elementsIter = elements.iterator();
        while (elementsIter.hasNext()) {
            Element nextElement = (Element) elementsIter.next();
            String targetNamespace = schema.getTargetNamespace();
            if(null == targetNamespace) {
                targetNamespace = "";
            }
            processGlobalElement(targetNamespace, schema.getDefaultNamespace(), nextElement);
        }
        //process substitution groups after properties have been created for all elements
        processSubstitutionGroups(elements, schema.getTargetNamespace(), schema.getDefaultNamespace());
    }

    private void processGlobalElement(String targetNamespace, String defaultNamespace, Element element) {
        if (element.getName() != null) {
            if(!returnAllTypes && null != aHelperContext.getXSDHelper().getGlobalProperty(targetNamespace, element.getName(), true)) {
                return;
            }
            QName qname = new QName(targetNamespace, element.getName());
            Object processed = processedElements.get(qname);

            if (processed == null) {
                SDOType elementType = processElement(targetNamespace, defaultNamespace, null, null, element, true, true);
                processedElements.put(qname, element);
                if(null != elementType && !getGeneratedTypes().containsKey(elementType.getQName())) {
                    getGeneratedTypes().put(elementType.getQName(), elementType);
                    anonymousTypes.remove(elementType);
                }
            }
        } else {
            processElement(targetNamespace, defaultNamespace, null, null, element, true, true);
        }
    }

    private SDOType processElement(String targetNamespace, String defaultNamespace, SDOType owningType, TypeDefParticle typeDefParticle, Element element, boolean isGlobal, boolean isMany) {
        SDOType type = null;
        boolean addedNR = addNextNamespaceResolver(element.getAttributesMap());

        ComplexType complexType = element.getComplexType();
        boolean qualified = true;
        if (!isGlobal) {
            qualified = rootSchema.isElementFormDefault();
        }
        if (!isMany && maxOccursGreaterThanOne(element.getMaxOccurs())) {
            isMany = true;
        }

        if (complexType != null) {
            type = processComplexType(targetNamespace, defaultNamespace, element.getName(), complexType);
            type.setXsdLocalName(element.getName());
            type.setXsd(true);
            processSimpleElement(targetNamespace, defaultNamespace, owningType, type, typeDefParticle, element, qualified, isGlobal, isMany);
        } else if (element.getSimpleType() != null) {
            type = processSimpleType(targetNamespace, defaultNamespace, element.getName(), element.getSimpleType());
            type.setXsdLocalName(element.getName());
            type.setXsd(true);
            processSimpleElement(targetNamespace, defaultNamespace, owningType, type, typeDefParticle, element, qualified, isGlobal, isMany);
        } else {
            processSimpleElement(targetNamespace, defaultNamespace, owningType, null, typeDefParticle, element, qualified, isGlobal, isMany);
        }
        if (addedNR) {
            namespaceResolvers.remove(namespaceResolvers.size() - 1);
        }
        return type;
    }

    private void processSimpleElement( //
            String targetNamespace,//
            String defaultNamespace,//
            SDOType owningType,//
            SDOType sdoPropertyType,//
            TypeDefParticle typeDefParticle,//
            Element element,//
            boolean isQualified,//
            boolean isGlobal,//
            boolean isMany) {
        if (element == null) {
            return;
        }

        String manyValue = (String) element.getAttributesMap().get(SDOConstants.SDOXML_MANY_QNAME);
        if (manyValue != null) {
            isMany = Boolean.parseBoolean(manyValue);
        }

        SDOProperty p = null;
        String typeName = null;
        String mappingUri = null;
        if (typeDefParticle != null) {
            mappingUri = owningType.getURI();
        }

        if (element.getRef() != null) {
            String ref = element.getRef();
            String localName = null;
            String uri = null;

            int index = ref.indexOf(':');
            if (index != -1) {
                String prefix = ref.substring(0, index);
                localName = ref.substring(index + 1, ref.length());
                uri = getURIForPrefix(prefix);
            } else {
                localName = ref;
                uri = defaultNamespace;
            }

            Property lookedUp = owningType.getProperty(localName);
            if (lookedUp != null) {
                if (inRestriction) {
                    return;
                }
                updateCollisionProperty(owningType, (SDOProperty) lookedUp);
            } else {
                SDOProperty theProp = new SDOProperty(aHelperContext);
                theProp.setName(localName);

                theProp.setGlobal(false);
                theProp.setContainment(true);
                theProp.setXsd(true);
                theProp.setMany(isMany);
                theProp.setInstanceProperty(SDOConstants.XMLELEMENT_PROPERTY, Boolean.TRUE);
                if (element.getAnnotation() != null) {
                    java.util.List doc = element.getAnnotation().getDocumentation();
                    if (doc != null) {
                        theProp.setInstanceProperty(SDOConstants.DOCUMENTATION_PROPERTY, doc);
                    }
                }

                owningType.addDeclaredProperty(theProp);

                GlobalRef globalRef = new GlobalRef();
                globalRef.setProperty(theProp);

                globalRef.setIsElement(true);
                globalRef.setOwningType(owningType);
                globalRef.setUri(uri);
                globalRef.setLocalName(localName);
                addGlobalRef(globalRef);
            }
            return;
        } else {
            if (isGlobal) {
                SDOProperty lookedUpProp = getExistingGlobalProperty(targetNamespace, element.getName(), true);
                if (lookedUpProp != null && lookedUpProp.isFinalized()) {
                    return;
                }
            }
            p = createNewProperty(targetNamespace, element.getName(), isQualified, isGlobal, true, element.isNillable(), element.getAnnotation());
            if (element.getAnnotation() != null) {
                p.setAppInfoElements(element.getAnnotation().getAppInfo());
            }

            if (element.getType() != null) {
                typeName = element.getType();
                p.setName(element.getName());
                QName qname = getQNameForString(defaultNamespace, typeName);
                if (isGlobal) {
                    // only process the root schema's global items if qname uri == target namespace
                    if (qname.getNamespaceURI().equals(targetNamespace)) {
                        //if type is found set it other wise process new type
                        processGlobalItem(targetNamespace, defaultNamespace, qname.getLocalPart());
                    }
                }

                if ((qname.equals(XMLConstants.QNAME_QNAME)) || (qname.equals(XMLConstants.BASE_64_BINARY_QNAME)) || (qname.equals(XMLConstants.HEX_BINARY_QNAME)) || (qname.equals(XMLConstants.DATE_QNAME)) || (qname.equals(XMLConstants.TIME_QNAME)) || (qname.equals(XMLConstants.DATE_TIME_QNAME))) {
                    p.setXsdType(qname);
                }

                String mimeType = (String) element.getAttributesMap().get(SDOConstants.XML_MIME_TYPE_QNAME);
                if (mimeType != null) {
                    p.setInstanceProperty(SDOConstants.MIME_TYPE_PROPERTY, mimeType);
                }
                String mimeTypePropName = (String) element.getAttributesMap().get(SDOConstants.XML_MIME_TYPE_PROPERTY_QNAME);
                if (mimeTypePropName != null) {
                    p.setInstanceProperty(SDOConstants.MIME_TYPE_PROPERTY_PROPERTY, mimeTypePropName);
                }

                sdoPropertyType = getSDOTypeForName(targetNamespace, defaultNamespace, typeName);
                if(!sdoPropertyType.isFinalized() && qname.getNamespaceURI().equals(targetNamespace)) {
                    if(sdoPropertyType.isDataType()) {
                        SimpleType baseSimpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(qname.getLocalPart());
                        processGlobalSimpleType(targetNamespace, defaultNamespace, baseSimpleType);
                    }
                }

                if ((p.getXsdType() == null) && (sdoPropertyType.getXsdType() != null)) {
                    p.setXsdType(sdoPropertyType.getXsdType());
                }

                if (sdoPropertyType.isDataType()) {
                    p.setContainment(false);
                }
            } else if (element.getComplexType() != null) {
                typeName = element.getName();
                p.setName(element.getComplexType().getNameOrOwnerName());
            } else if (element.getSimpleType() != null) {
                typeName = element.getName();
                p.setName(element.getName());
                if (sdoPropertyType.isDataType()) {
                    p.setContainment(false);
                }
            } else {
                //we assume the xsd type to be any simple type
                p.setName(element.getName());
                sdoPropertyType = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getSDOTypeFromXSDType(SDOConstants.ANY_TYPE_QNAME);
            }
        }
        sdoPropertyType = processSimpleComponentAnnotations(owningType, element, p, targetNamespace, defaultNamespace, sdoPropertyType);

        p.setType(sdoPropertyType);
        setDefaultValue(p, element);

        p.setMany(isMany);

        if (p.getType().isChangeSummaryType()) {
            p.setReadOnly(true);
        }

        if (typeDefParticle != null) {
            updateOwnerAndBuildMapping(owningType, p, defaultNamespace, targetNamespace, element, typeName, mappingUri);
        }
        if (isGlobal) {
            //we have a global element
            addRootElementToDescriptor(p, targetNamespace, element.getName());
        }
        p.setFinalized(true);
    }

    private SDOProperty processRef(GlobalRef globalRef) {
        boolean isElement = globalRef.isElement();
        SDOProperty p = null;

        SDOProperty refProp = getExistingGlobalProperty(globalRef.getUri(), globalRef.getLocalName(), isElement);

        if (refProp != null && refProp.isFinalized()) {
            p = (SDOProperty) globalRef.getProperty();
            p.setValueProperty(refProp.isValueProperty());
            p.setNullable(refProp.isNullable());
            p.setName(refProp.getName());
            p.setXsdLocalName(refProp.getXsdLocalName());
            p.setNamespaceQualified(refProp.isNamespaceQualified());
            if (refProp.hasAliasNames()) {
                p.setAliasNames(refProp.getAliasNames());
            }
            p.setDefault(refProp.getDefault());
            p.setSubstitutable(refProp.isSubstitutable());
            p.setSubstitutableElements(refProp.getSubstitutableElements());

            if (p.getType() == null) {
                p.setType(refProp.getType());
                if (refProp.getType().isDataType()) {
                    p.setContainment(false);
                }
            }
            p.setOpposite(refProp.getOpposite());
            p.setReadOnly(refProp.isReadOnly());
            p.setXsd(refProp.isXsd());
            p.setAppInfoElements(refProp.getAppInfoElements());

            int index = ((SDOProperty) globalRef.getProperty()).getIndexInDeclaredProperties();
            p.buildMapping(globalRef.getUri(), index);
            p.setFinalized(true);
        } else {
            if (isImportProcessor) {
                p = new SDOProperty(aHelperContext);
                p.setGlobal(true);
                p.setUri(globalRef.getUri());
                p.setName(globalRef.getLocalName());
                QName qname = new QName(globalRef.getUri(), globalRef.getLocalName());
                if (isElement) {
                    p.setInstanceProperty(SDOConstants.XMLELEMENT_PROPERTY, Boolean.TRUE);
                    getGeneratedGlobalElements().put(qname, p);
                } else {
                    getGeneratedGlobalAttributes().put(qname, p);
                }
            } else {
                throw SDOException.referencedPropertyNotFound(globalRef.getUri(), globalRef.getLocalName());
            }
        }
        return p;
    }

    private void updateCollisionProperty(SDOType owningType, SDOProperty p) {
        owningType.setSequenced(true);
        SDOType baseType = owningType;
        while (baseType.isSubType()) {
            baseType = (SDOType) baseType.getBaseTypes().get(0);
            baseType.setSequenced(true);
        }
        p.setNameCollision(true);
        p.setType(SDOConstants.SDO_OBJECT);
        p.setContainment(true);
        p.setMany(true);
        p.setInstanceProperty(SDOConstants.XMLELEMENT_PROPERTY, Boolean.TRUE);
    }

    private SDOProperty createNewProperty(String targetNamespace, String xsdLocalName, boolean isQualified, boolean isGlobal, boolean isElement, boolean isNillable, Annotation annotation) {
        SDOProperty p = null;
        if (isGlobal) {
            p = getExistingGlobalProperty(targetNamespace, xsdLocalName, isElement);
        }
        if (p == null) {
            p = new SDOProperty(aHelperContext);
        }
        p.setGlobal(isGlobal);
        p.setXsd(true);
        p.setNullable(isNillable);
        if (isElement) {
            p.setInstanceProperty(SDOConstants.XMLELEMENT_PROPERTY, Boolean.TRUE);
        }
        p.setXsdLocalName(xsdLocalName);
        p.setNamespaceQualified(isQualified);
        p.setContainment(true);
        if (isGlobal) {
            QName qname = new QName(targetNamespace, xsdLocalName);
            if (isElement) {
                getGeneratedGlobalElements().put(qname, p);
            } else {
                getGeneratedGlobalAttributes().put(qname, p);
            }
        }

        if (annotation != null) {
            java.util.List documentation = annotation.getDocumentation();
            if ((documentation != null) && (documentation.size() > 0)) {
                p.setInstanceProperty(SDOConstants.DOCUMENTATION_PROPERTY, documentation);
            }
        }

        return p;
    }

    private void addRootElementToDescriptor(SDOProperty p, String targetNamespace, String xsdName) {
        if (!p.getType().isDataType()) {
            String prefix = null;
            if(targetNamespace != null && !XMLConstants.EMPTY_STRING.equals(targetNamespace)) {
                NamespaceResolver nr = p.getType().getXmlDescriptor().getNamespaceResolver();
                if (nr != null) {
                    prefix = nr.resolveNamespaceURI(targetNamespace);
                    if(null == prefix) {
                        prefix = nr.generatePrefix();
                        nr.put(prefix, targetNamespace);
                    }
                }
            }
            if ((prefix == null) || prefix.equals(SDOConstants.EMPTY_STRING)) {
                p.getType().getXmlDescriptor().addRootElement(xsdName);
            } else {
                p.getType().getXmlDescriptor().addRootElement(prefix + //
                        SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + xsdName);
            }
        } else {
            // Types from Schema: isDataType() == true so:
            //   - find the SDOWrapperType from TypeHelper's WrappersHashMap
            //   - set the root element name on it
            //   - add the descriptor to XMLContext's DescriptorsByQName map

            // See also: SDOTypeHelperDelegate:defineOpenContentProperty

            SDOTypeHelper typeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();

            SDOWrapperType wrapperType = (SDOWrapperType) typeHelper.getWrappersHashMap().get(p.getType().getQName());

            XMLDescriptor d = wrapperType.getXmlDescriptor(p.getXsdType());
            if (wrapperType != null) {
                d.addRootElement(xsdName);

                QName descriptorQname = new QName(targetNamespace, xsdName);
                ((SDOXMLHelper) aHelperContext.getXMLHelper()).getXmlContext().addDescriptorByQName(descriptorQname, d);
            }
        }
    }

    private void updateOwnerAndBuildMapping(SDOType owningType, SDOProperty p, String defaultNamespace, String targetNamespace, SimpleComponent simpleComponent, String typeName, String mappingUri) {
        boolean buildMapping = true;
        Property lookedUp = owningType.getProperty(p.getName());

        if (lookedUp != null) {
            p = (SDOProperty) lookedUp;
            if (inRestriction) {
                return;
            }
            updateCollisionProperty(owningType, p);
        } else {
            owningType.addDeclaredProperty(p);
        }

        QName xsdType = getQNameForString(defaultNamespace, typeName);

        if ((xsdType != null) && xsdType.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
            if (xsdType.getLocalPart().equals(SDOConstants.ID)) {
                owningType.setInstanceProperty(SDOConstants.ID_PROPERTY, p.getName());
            } else if (xsdType.getLocalPart().equals(SDOConstants.IDREF)) {
                p.setContainment(false);
                String propertyTypeValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_PROPERTYTYPE_QNAME);
                if (propertyTypeValue != null) {
                    buildMapping = false;
                }
            } else if (xsdType.getLocalPart().equals(SDOConstants.IDREFS)) {
                p.setContainment(false);
                String propertyTypeValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_PROPERTYTYPE_QNAME);
                if (propertyTypeValue != null) {
                    buildMapping = false;
                    p.setMany(true);
                } else {
                    p.setMany(false);
                }
            }
        }

        if (buildMapping) {
            p.buildMapping(mappingUri);
        }
    }

    private void setDefaultValue(SDOProperty p, SimpleComponent sc) {
        if (sc.getFixed() != null) {
            Object convertedValue = convertDefaultValue(p.getType(), sc.getFixed());
            p.setDefault(convertedValue);
        } else if (sc.getDefaultValue() != null) {
            Object convertedValue = convertDefaultValue(p.getType(), sc.getDefaultValue());
            p.setDefault(convertedValue);
        } else {
            if (p.getType().getQName().equals(SDOConstants.SDO_STRING.getQName()) && sc.isSetDefaultValue()) {
                p.setDefault("");
            }
        }
    }

    private Object convertDefaultValue(Type type, String stringValue) {
        if (type != null) {
            Class javaClass = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getJavaWrapperTypeForSDOType(type);
            if (javaClass != null) {
                Object objectValue = ((SDODataHelper) aHelperContext.getDataHelper()).convertFromStringValue(stringValue, javaClass);
                return objectValue;
            }
        }
        return stringValue;
    }

    private void processSimpleAttribute(String targetNamespace, String defaultNamespace, SDOType owningType, Attribute attribute, boolean isGlobal, boolean isQualified, SDOType sdoPropertyType) {
        if (attribute == null) {
            return;
        }

        SDOProperty p = null;

        String typeName = null;
        String mappingUri = null;
        if (owningType != null) {
            mappingUri = owningType.getURI();
        }
        if (attribute.getRef() != null) {
            String ref = attribute.getRef();

            String localName = null;
            String uri = null;

            int index = ref.indexOf(':');
            if (index != -1) {
                String prefix = ref.substring(0, index);
                localName = ref.substring(index + 1, ref.length());
                uri = getURIForPrefix(prefix);
            } else {
                localName = ref;
                uri = defaultNamespace;
            }

            Property lookedUp = owningType.getProperty(localName);
            if (lookedUp != null) {
                if (inRestriction) {
                    return;
                }
                updateCollisionProperty(owningType, (SDOProperty) lookedUp);
            } else {
                SDOProperty theProp = new SDOProperty(aHelperContext);
                SDOProperty lookedUpProp = getExistingGlobalProperty(uri, localName, false);
                if (lookedUpProp != null) {
                    theProp.setNamespaceQualified(lookedUpProp.isNamespaceQualified());
                    theProp.setUri(uri);
                    theProp.setType(lookedUpProp.getType());
                }
                theProp.setName(localName);
                theProp.setGlobal(false);
                theProp.setContainment(false);
                theProp.setXsd(true);
                theProp.setMany(false);
                if (attribute.getAnnotation() != null) {
                    java.util.List doc = attribute.getAnnotation().getDocumentation();
                    if (doc != null) {
                        theProp.setInstanceProperty(SDOConstants.DOCUMENTATION_PROPERTY, doc);
                    }
                }
                theProp.setFinalized(true);
                GlobalRef globalRef = new GlobalRef();
                globalRef.setProperty(theProp);
                owningType.addDeclaredProperty(theProp);

                globalRef.setIsElement(false);
                globalRef.setOwningType(owningType);
                globalRef.setUri(uri);
                globalRef.setLocalName(localName);
                addGlobalRef(globalRef);
            }
            return;

        } else {
            if (isGlobal) {
                SDOProperty lookedUpProp = getExistingGlobalProperty(targetNamespace, attribute.getName(), false);
                if (lookedUpProp != null && lookedUpProp.isFinalized()) {
                    return;
                }
            }

            p = createNewProperty(targetNamespace, attribute.getName(), isQualified, isGlobal, false, false, attribute.getAnnotation());
            if (attribute.getAnnotation() != null) {
                p.setAppInfoElements(attribute.getAnnotation().getAppInfo());
            }

            typeName = attribute.getType();
            if (typeName != null) {
                p.setName(attribute.getName());
                QName qname = getQNameForString(defaultNamespace, typeName);
                if (isGlobal) {
                    //if type is found set it other wise process new type
                    processGlobalItem(targetNamespace, defaultNamespace, typeName);
                }
                if ((qname.equals(XMLConstants.QNAME_QNAME)) || (qname.equals(XMLConstants.BASE_64_BINARY_QNAME)) || (qname.equals(XMLConstants.HEX_BINARY_QNAME)) || (qname.equals(XMLConstants.DATE_QNAME)) || (qname.equals(XMLConstants.TIME_QNAME)) || (qname.equals(XMLConstants.DATE_TIME_QNAME))) {
                    p.setXsdType(qname);
                }
                sdoPropertyType = getSDOTypeForName(targetNamespace, defaultNamespace, typeName);
                if(!sdoPropertyType.isFinalized() && qname.getNamespaceURI().equals(targetNamespace)) {
                    if(sdoPropertyType.isDataType()) {
                        SimpleType baseSimpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(qname.getLocalPart());
                        processGlobalSimpleType(targetNamespace, defaultNamespace, baseSimpleType);
                    }
                }
                if ((p.getXsdType() == null) && (sdoPropertyType.getXsdType() != null)) {
                    p.setXsdType(sdoPropertyType.getXsdType());
                }
            } else if (attribute.getSimpleType() != null) {
                p.setName(attribute.getName());
                typeName = attribute.getName();
            } else {
                p.setName(attribute.getName());
                sdoPropertyType = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getSDOTypeFromXSDType(SDOConstants.ANY_TYPE_QNAME);
            }
        }
        sdoPropertyType = processSimpleComponentAnnotations(owningType, attribute, p, targetNamespace, defaultNamespace, sdoPropertyType);
        p.setType(sdoPropertyType);
        p.setContainment(false);
        setDefaultValue(p, attribute);

        if (p.getType().isChangeSummaryType()) {
            p.setReadOnly(true);
        }

        if (owningType != null) {
            updateOwnerAndBuildMapping(owningType, p, defaultNamespace, targetNamespace, attribute, typeName, mappingUri);
        }
        p.setFinalized(true);
    }

    private SDOType processSimpleComponentAnnotations(SDOType owningType, SimpleComponent simpleComponent, SDOProperty p, String targetNamespace, String defaultNamespace, SDOType sdoPropertyType) {
        //aliasName annotation
        String aliasNamesValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_ALIASNAME_QNAME);
        if (aliasNamesValue != null) {
            XMLConversionManager xmlConversionManager = ((SDOXMLHelper) aHelperContext.getXMLHelper()).getXmlConversionManager();
            java.util.List names = xmlConversionManager.convertObject(aliasNamesValue, java.util.List.class);
            p.setAliasNames(names);
        }

        //readOnly annotation
        String readOnlyValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_READONLY_QNAME);
        if (readOnlyValue != null) {
            p.setReadOnly(Boolean.parseBoolean(readOnlyValue));
        }

        //dataType annotation
        String dataTypeValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_DATATYPE_QNAME);
        if (dataTypeValue != null) {
            QName xsdQName = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(sdoPropertyType);
            if ((xsdQName == null) && !sdoPropertyType.isDataType()) {
                xsdQName = new QName(sdoPropertyType.getURI(), sdoPropertyType.getName());
            }
            p.setXsdType(xsdQName);
            SDOType sdoType = getSDOTypeForName(targetNamespace, defaultNamespace, dataTypeValue);
            sdoPropertyType = sdoType;
            Property xmlDataTypeProperty = aHelperContext.getTypeHelper().getOpenContentProperty(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_DATATYPE);
            p.setInstanceProperty(xmlDataTypeProperty, sdoType);
        }

        //string annotation
        String stringValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_STRING_QNAME);
        if (stringValue != null) {
            QName xsdTypeQName = getQNameForString(defaultNamespace, simpleComponent.getType());
            p.setXsdType(xsdTypeQName);
            sdoPropertyType = SDOConstants.SDO_STRING;
        }

        //name annotation
        String nameValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_NAME_QNAME);
        if (nameValue != null) {
            //itemNameToSDOName.put(sdoTypeName, nameValue);
            p.setName(nameValue);
            if (p.isGlobal() && targetNamespace != null) {
                QName propertyName = new QName(targetNamespace, nameValue);
                ((SDOTypeHelper) aHelperContext.getTypeHelper()).getOpenContentProperties().put(propertyName, p);
            }
        } else {
            if (p.isGlobal() && targetNamespace != null) {
                QName propertyName = new QName(targetNamespace, p.getName());
                ((SDOTypeHelper) aHelperContext.getTypeHelper()).getOpenContentProperties().put(propertyName, p);
            }
        }

        // propertyType annotation
        String propertyTypeValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_PROPERTYTYPE_QNAME);
        if (propertyTypeValue != null) {
            String uri = targetNamespace;
            int colonIndex = propertyTypeValue.indexOf(':');
            if (colonIndex > -1) {
                String prefix = propertyTypeValue.substring(0, colonIndex);
                uri = getURIForPrefix(prefix);
            }
            NonContainmentReference nonContainmentReference = new NonContainmentReference();
            nonContainmentReference.setPropertyTypeName(propertyTypeValue);
            nonContainmentReference.setPropertyTypeURI(uri);
            nonContainmentReference.setOwningType(owningType);
            nonContainmentReference.setOwningProp(p);
            String oppositePropValue = (String) simpleComponent.getAttributesMap().get(SDOConstants.SDOXML_OPPOSITEPROPERTY_QNAME);

            nonContainmentReference.setOppositePropName(oppositePropValue);
            getNonContainmentReferences().add(nonContainmentReference);
        }

        return sdoPropertyType;
    }

    private void postProcessing() {
        int size = getNonContainmentReferences().size();
        for (int i = 0; i < size; i++) {
            NonContainmentReference nonContainmentReference = getNonContainmentReferences().get(i);
            SDOType owningType = nonContainmentReference.getOwningType();

            if (owningType != null) {
                String propertyTypeName = nonContainmentReference.getPropertyTypeName();
                String propertyTypeUri = nonContainmentReference.getPropertyTypeURI();

                SDOType oppositeType = getSDOTypeForName(propertyTypeUri, propertyTypeUri, propertyTypeName);
                if (oppositeType != null) {
                    SDOProperty owningProp = nonContainmentReference.getOwningProp();
                    if (owningProp != null) {
                        // Spec sect 9.2 (1) oppositeType.dataType must be false
                        if (oppositeType.isDataType()) {
                            throw SDOException.propertyTypeAnnotationTargetCannotBeDataTypeTrue(//
                                    oppositeType.getName(), owningProp.getName());
                        }
                        owningProp.setType(oppositeType);
                        owningProp.setContainment(false);
                        owningProp.buildMapping(owningProp.getType().getURI());
                        // Bidirectional property name
                        String oppositePropName = nonContainmentReference.getOppositePropName();
                        if (oppositePropName != null) {
                            SDOProperty prop = oppositeType.getProperty(oppositePropName);
                            owningProp.setOpposite(prop);
                            prop.setOpposite(owningProp);
                        }
                    }
                }
            }
        }

        Iterator<Type> iter = getGlobalRefs().keySet().iterator();
        while (iter.hasNext()) {
            Object nextKey = iter.next();
            java.util.List<GlobalRef> value = getGlobalRefs().get(nextKey);
            java.util.List refsToRemove = new ArrayList();
            if (value != null) {
                for (int i = 0; i < value.size(); i++) {
                    GlobalRef nextGlobalRef = value.get(i);
                    SDOProperty p = processRef(nextGlobalRef);
                    if (p.isFinalized()) {
                        refsToRemove.add(nextGlobalRef);
                    }
                }
            }
            for (int i = 0; i < refsToRemove.size(); i++) {
                value.remove(refsToRemove.get(i));
            }
        }
    }

    private void addGlobalRef(GlobalRef ref) {
        java.util.List<GlobalRef> refs = getGlobalRefs().get(ref.getOwningType());
        if (null == refs) {
            refs = new ArrayList<GlobalRef>();
            refs.add(ref);
            getGlobalRefs().put(ref.getOwningType(), refs);
        } else {
            refs.add(ref);
        }
    }

    /**
     * INTERNAL:
     * Initialize this SchemaParser by configuring the package name based on the targetNamespace.
     */
    private void initialize() {
        if (null == packageName) {
            String packageValue = (String) rootSchema.getAttributesMap().get(SDOConstants.SDOJAVA_PACKAGE_QNAME);
            if (null != packageValue) {
                packageName = packageValue;
            } else if ((null == rootSchema.getTargetNamespace()) || rootSchema.getTargetNamespace().equals(SDOConstants.EMPTY_STRING)) {
                packageName = SDOConstants.JAVA_TYPEGENERATION_NO_NAMESPACE;
            } else {
                packageName = SDOUtil.getPackageNameFromURI(rootSchema.getTargetNamespace());
            }
            packageName += SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR;
        }
    }

    private SDOType createSDOTypeForName(String targetNamespace, String name, String xsdLocalName) {
        SDOType returnType = null;
        int index = name.indexOf(':');
        if (index != -1) {
            String prefix = name.substring(0, index);
            String localName = name.substring(index + 1, name.length());
            String theURI = getURIForPrefix(prefix);
            returnType = getOrCreateType(theURI, localName, xsdLocalName);
        } else {
            // returnType = getOrCreateType(targetNamespace, name, xsdLocalName);
            SDOType sdoType = new SDOType(targetNamespace, name, (SDOTypeHelper)aHelperContext.getTypeHelper());
            this.anonymousTypes.add(sdoType);
            return sdoType;
        }
        return returnType;
    }

    private SDOType getSDOTypeForName(String targetNamespace, String defaultNamespace, String name) {
        return getSDOTypeForName(targetNamespace, defaultNamespace, true, name);
    }

    private SDOType getSDOTypeForName(String targetNamespace, String defaultNamespace, boolean checkDefaultNamespace, String name) {
        int index = name.indexOf(':');
        if (index != -1) {
            String prefix = name.substring(0, index);
            String localName = name.substring(index + 1, name.length());
            String theURI = getURIForPrefix(prefix);
            QName qname = new QName(theURI, localName);
            SDOType sdoType = generatedTypesByXsdQName.get(qname);
            if(null == sdoType) {
                sdoType = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getSDOTypeFromXSDType(qname);
                if (null == sdoType) {
                    sdoType = getExisitingType(theURI, localName);
                    if (null == sdoType) {
                        sdoType = findSdoType(targetNamespace, defaultNamespace, name, localName, theURI);
                    }
                }
            }
            if (null == sdoType) {
                sdoType = getOrCreateType(theURI, localName, localName);
                if (!sdoType.isFinalized()) {
                    //if it's not finalized, then it's new, so add it to the generated types map
                    getGeneratedTypes().put(new QName(sdoType.getURI(), sdoType.getName()), sdoType);
                }
            }
            return sdoType;

        } else {
            String sdoName = (String) itemNameToSDOName.get(name);
            if (sdoName != null) {
                name = sdoName;
            }

            SDOType sdoType = null;
            if (checkDefaultNamespace && (defaultNamespace != null)) {
                QName qname = new QName(defaultNamespace, name);
                sdoType = ((SDOTypeHelper) aHelperContext.getTypeHelper()).getSDOTypeFromXSDType(qname);
                if(null == sdoType) {
                    sdoType = generatedTypesByXsdQName.get(qname);
                }
            }
            if (null == sdoType) {
                sdoType = getExisitingType(targetNamespace, name);
                if (null == sdoType) {
                    return findSdoType(targetNamespace, defaultNamespace, name, name, targetNamespace);
                }
                return getOrCreateType(targetNamespace, name, name);
            }
            return sdoType;
        }
    }

    //Since types aren't registered until the end of the define call we need to check typeHelper
    //and the generatedTypesmap to see if a type already exists.  The if the type doesn't exist
    //we create a new one
    private SDOType getOrCreateType(String uri, String typeName, String xsdLocalName) {
        String lookupName = typeName;
        int index = lookupName.indexOf(':');
        if (index != -1) {
            lookupName = lookupName.substring(index + 1, lookupName.length());
        }
        SDOTypeHelper sdoTypeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();
        SDOType returnType = (SDOType) sdoTypeHelper.getType(uri, lookupName);
        if (returnType == null) {
            QName qname = new QName(uri, lookupName);
            returnType = (SDOType) getGeneratedTypes().get(qname);

            if (returnType == null) {
                QName xsdQName = new QName(uri, xsdLocalName);
                returnType = getTypeForXSDQName(xsdQName);
                if (returnType == null) {
                    returnType = new SDOType(uri, lookupName, sdoTypeHelper);
                    returnType.setXsd(true);
                    returnType.setXsdLocalName(xsdLocalName);
                } else {
                    returnType.setQName(qname);
                }
            }
        }
        return returnType;
    }

    //Since global properties aren't registered until the end of the define call we need to check XSDhelper
    //and the generatedProperties map to see if a type already exists
    private SDOProperty getExistingGlobalProperty(String uri, String localName, boolean isElement) {
        SDOProperty prop = (SDOProperty) aHelperContext.getXSDHelper().getGlobalProperty(uri, localName, isElement);
        if (prop == null) {
            QName qName = new QName(uri, localName);
            if (isElement) {
                prop = (SDOProperty) getGeneratedGlobalElements().get(qName);
            } else {
                prop = (SDOProperty) getGeneratedGlobalAttributes().get(qName);
            }
        }
        return prop;
    }

    //Since types aren't registered until the end of the define call we need to check type helper
    //and the generatedTypesmap to see if a type already exists
    private SDOType getExisitingType(String uri, String localName) {
        SDOType type = (SDOType) aHelperContext.getTypeHelper().getType(uri, localName);
        if (type == null) {
            QName qName = new QName(uri, localName);
            type = (SDOType) getGeneratedTypes().get(qName);
        }
        return type;
    }

    private SDOType findSdoType(String targetNamespace, String defaultNamespace, String qualifiedName, String localName, String theURI) {
        //need to also check imports
        SDOType type = getExisitingType(theURI, localName);

        // Do not execute the following if theURI isn't the target namespace
        if (type == null && ((theURI != null && theURI.equals(targetNamespace)) || (theURI == null && targetNamespace == null))) {
            processGlobalItem(targetNamespace, defaultNamespace, qualifiedName);
            String sdoName = (String) itemNameToSDOName.get(localName);
            if (sdoName != null) {
                localName = sdoName;
            }
            type = getExisitingType(theURI, localName);
        }
        if (null == type) {
            type = getOrCreateType(theURI, localName, localName);

            if (!type.isFinalized()) {
                //if it's not finalized, then it's new, so add it to the generated types map
                getGeneratedTypes().put(new QName(type.getURI(), type.getName()), type);
            }

        }
        return type;
    }

    public void setGeneratedTypes(Map<QName, Type> generatedTypes) {
        this.generatedTypes = generatedTypes;
    }

    public void setGeneratedGlobalElements(Map<QName, Property> generatedElements) {
        this.generatedGlobalElements = generatedElements;
    }

    public void setGeneratedGlobalAttributes(Map<QName, Property> generatedAttributes) {
        this.generatedGlobalAttributes = generatedAttributes;
    }

    public java.util.List<SDOType> getAnonymousTypes() {
        return anonymousTypes;
    }

    public void setAnonymousTypes(java.util.List<SDOType> anonymousTypes) {
        this.anonymousTypes = anonymousTypes;
    }

    public Map<QName, Type> getGeneratedTypes() {
        if (null == generatedTypes) {
            generatedTypes = new HashMap<QName, Type>();
        }
        return generatedTypes;
    }

    public Map<QName, Property> getGeneratedGlobalElements() {
        if (null == generatedGlobalElements) {
            generatedGlobalElements = new HashMap<QName, Property>();
        }
        return generatedGlobalElements;
    }

    public Map<QName, SDOType> getGeneratedTypesByXsdQName() {
        return generatedTypesByXsdQName;
    }

    public void setGeneratedTypesByXsdQName(Map<QName, SDOType> generatedTypesByXsdQName) {
        this.generatedTypesByXsdQName = generatedTypesByXsdQName;
    }

    public Map<QName, Property> getGeneratedGlobalAttributes() {
        if (null == generatedGlobalAttributes) {
            generatedGlobalAttributes = new HashMap<QName, Property>();
        }
        return generatedGlobalAttributes;
    }

    private void processSubstitutionGroups(Collection elements, String targetNamespace, String defaultNamespace) {
        Iterator elementsIter = elements.iterator();
        while (elementsIter.hasNext()) {
            Element nextElement = (Element) elementsIter.next();
            if (nextElement.getSubstitutionGroup() != null) {
                String substitutionGroup = nextElement.getSubstitutionGroup();
                String localName = null;
                String uri = null;

                int index = substitutionGroup.indexOf(':');
                if (index != -1) {
                    String prefix = substitutionGroup.substring(0, index);
                    localName = substitutionGroup.substring(index + 1, substitutionGroup.length());
                    uri = getURIForPrefix(prefix);
                } else {
                    localName = substitutionGroup;
                    uri = defaultNamespace;
                }
                SDOProperty rootProp = getExistingGlobalProperty(uri, localName, true);
                SDOProperty thisProperty = getExistingGlobalProperty(targetNamespace, nextElement.getName(), true);

                if (rootProp != null && thisProperty != null) {
                    if (rootProp.getSubstitutableElements() == null) {
                        rootProp.setSubstitutableElements(new java.util.ArrayList<SDOProperty>());
                        rootProp.setSubstitutable(true);
                    }
                    rootProp.getSubstitutableElements().add(thisProperty);
                }
            }
        }
    }

    private void processAnyAttribute(String targetNamespace, String defaultNamespace, SDOType owningType) {
        owningType.setOpen(true);
    }

    private SDOType getTypeForName(String targetNamespace, String defaultNamespace, String typeName) {
        Object value = getGeneratedTypes().get(getQNameForString(defaultNamespace, typeName));
        if (value != null) {
            return (SDOType) value;
        } else {
            String sdoName = (String) itemNameToSDOName.get(typeName);
            if (sdoName != null) {
                return getTypeForName(targetNamespace, defaultNamespace, sdoName);
            } else {
                return getSDOTypeForName(targetNamespace, defaultNamespace, false, typeName);
            }
        }
    }

    private QName getQNameForString(String defaultNamespace, String name) {
        if (null == name) {
            return null;
        }
        int index = name.indexOf(':');
        if (index != -1) {
            String prefix = name.substring(0, index);
            String localName = name.substring(index + 1, name.length());
            String theURI = getURIForPrefix(prefix);
            QName qname = new QName(theURI, localName);
            return qname;
        } else {
            QName qname = new QName(defaultNamespace, name);
            return qname;
        }
    }

    private void processGlobalItem(String targetNamespace, String defaultNamespace, String qualifiedName) {
        if (rootSchema == null) {
            return;
        }
        String localName = null;
        int index = qualifiedName.indexOf(':');
        if (index != -1) {
            localName = qualifiedName.substring(index + 1, qualifiedName.length());
        } else {
            localName = qualifiedName;
        }

        SimpleType simpleType = (SimpleType) rootSchema.getTopLevelSimpleTypes().get(localName);
        if (simpleType == null) {
            ComplexType complexType = (ComplexType) rootSchema.getTopLevelComplexTypes().get(localName);
            if (complexType == null) {
                Element element = (Element) rootSchema.getTopLevelElements().get(localName);
                if (element == null) {
                    Attribute attribute = (Attribute) rootSchema.getTopLevelAttributes().get(localName);
                    if (attribute != null) {
                        processGlobalAttribute(targetNamespace, defaultNamespace, attribute);
                    }
                } else {
                    processGlobalElement(targetNamespace, defaultNamespace, element);
                }
            } else {
                processGlobalComplexType(targetNamespace, defaultNamespace, complexType);
            }
        } else {
            processGlobalSimpleType(targetNamespace, defaultNamespace, simpleType);
        }
    }

    /**
     * Return a Schema for the given Source object.
     *
     * A SchemaResolverWrapper is created to wrap the given SchemaResolver.  The wrapper
     * will prevent schemas from being processed multiple times (such as in the case of
     * circular includes/imports)
     *
     * This method should not be called recursively if a given schema could potentially
     * and undesirably be processed multiple times (again, such as in the case of
     * circular includes/imports)
     *
     * @param xsdSource
     * @param schemaResolver the schema resolver to be used to resolve imports/includes
     * @return
     */
    public Schema getSchema(Source xsdSource, SchemaResolver schemaResolver, boolean closeStream) {
        // Create a resolver wrapper that will prevent schemas from being processed
        // multiple times (such as in the case of circular includes/imports)
        return getSchema(xsdSource, new SchemaResolverWrapper(schemaResolver), closeStream);
    }

    /**
     * Return a Schema for the given Source object.
     *
     * Since this method is called recursively, and the SchemaResolverWrapper is stateful,
     * the resolver wrapper must be created outside of this method.
     *
     * @param xsdSource
     * @param schemaResolverWrapper wraps the schema resolver to be used to resolve imports/includes
     * @return
     */
    public Schema getSchema(Source xsdSource, SchemaResolverWrapper schemaResolverWrapper, boolean closeStream) {

       xsdSource = schemaResolverWrapper.resolveSchema(xsdSource);

       XMLContext context = new XMLContext(getSchemaProject());
       XMLUnmarshaller unmarshaller = context.createUnmarshaller();
       unmarshaller.setEntityResolver(schemaResolverWrapper.getSchemaResolver());

       Schema schema = (Schema) unmarshaller.unmarshal(xsdSource);
       if(closeStream){

           closeSource(xsdSource);
       }
       //populate Imports
       java.util.List imports = schema.getImports();
       Iterator iter = imports.iterator();
       while (iter.hasNext()) {
           Import nextImport = (Import) iter.next();
           Source referencedSchema = getReferencedSchema(xsdSource, nextImport.getNamespace(), nextImport.getSchemaLocation(), schemaResolverWrapper);
           if (referencedSchema != null) {
               Schema importedSchema = getSchema(referencedSchema, schemaResolverWrapper, true);
               nextImport.setSchema(importedSchema);
            }
       }

       //populate includes
       java.util.List includes = schema.getIncludes();
       Iterator includesIter = includes.iterator();
       while (includesIter.hasNext()) {
            Include nextInclude = (Include) includesIter.next();

            Source referencedSchema = getReferencedSchema(xsdSource, schema.getTargetNamespace(), nextInclude.getSchemaLocation(), schemaResolverWrapper);
            if (referencedSchema != null) {
                Schema includedSchema = getSchema(referencedSchema, schemaResolverWrapper, true);
                nextInclude.setSchema(includedSchema);
            }
        }
        return schema;

    }

    private void closeSource(Source source){
        if(source != null && source instanceof StreamSource){
            StreamSource ss = (StreamSource)source;
            try{
                if(ss.getInputStream() != null){
                   ss.getInputStream().close();
                } else if(ss.getReader() != null){
                   ss.getReader().close();
                }

            }catch (IOException e) {
                throw SDOException.errorResolvingSchema(e);
           }
        }
    }

    private Source getReferencedSchema(Source xsdSource, String namespace, String schemaLocation, SchemaResolverWrapper schemaResolverWrapper) {
        if (namespace.equals(SDOConstants.SDOJAVA_URL) || namespace.equals(SDOConstants.SDO_URL) || namespace.equals(SDOConstants.SDOXML_URL)) {
            return null;
        }
        return schemaResolverWrapper.resolveSchema(xsdSource, namespace, schemaLocation);
    }

    public Project getSchemaProject() {
        if (schemaProject == null) {
            schemaProject = new SchemaModelProject();

        }
        return schemaProject;
    }

    public Schema getRootSchema() {
        return rootSchema;
    }

    public void setProcessImports(boolean processImports) {
        this.processImports = processImports;
    }

    public boolean isProcessImports() {
        return processImports;
    }

    public void setReturnAllTypes(boolean returnAllTypes) {
        this.returnAllTypes = returnAllTypes;
    }

    public boolean isReturnAllTypes() {
        return returnAllTypes;
    }

    private boolean maxOccursGreaterThanOne(String maxOccurs) {
        if (maxOccurs == null) {
            return false;
        }
        if (maxOccurs.equalsIgnoreCase(Occurs.UNBOUNDED)) {
            return true;
        }
        return !maxOccurs.equals(Occurs.ONE);
    }

    private String getURIForPrefix(String prefix) {
        String uri = null;

        for (int i = namespaceResolvers.size() - 1; i >= 0; i--) {
            NamespaceResolver next = namespaceResolvers.get(i);
            uri = next.resolveNamespacePrefix(prefix);
            if ((uri != null) && !uri.equals(SDOConstants.EMPTY_STRING)) {
                break;
            }
        }

        if (null == uri) {
            throw SDOException.prefixUsedButNotDefined(prefix);
        }
        return uri;
    }

    public class NonContainmentReference {
        private SDOType owningType;
        private SDOProperty owningProp;
        private String propertyTypeName;
        private String propertyTypeURI;
        private String oppositePropName;

        /**
         * Default constructor.
         */
        public NonContainmentReference() {
        }

        public void setOwningType(SDOType owningType) {
            this.owningType = owningType;
        }

        public SDOType getOwningType() {
            return owningType;
        }

        public void setOwningProp(SDOProperty owningProp) {
            this.owningProp = owningProp;
        }

        public SDOProperty getOwningProp() {
            return owningProp;
        }

        public void setPropertyTypeName(String propertyTypeName) {
            this.propertyTypeName = propertyTypeName;
        }

        public String getPropertyTypeName() {
            return propertyTypeName;
        }

        public void setPropertyTypeURI(String propertyTypeURI) {
            this.propertyTypeURI = propertyTypeURI;
        }

        public String getPropertyTypeURI() {
            return propertyTypeURI;
        }

        public void setOppositePropName(String oppositePropName) {
            this.oppositePropName = oppositePropName;
        }

        public String getOppositePropName() {
            return oppositePropName;
        }
    }

    public class GlobalRef {
        private SDOType owningType;
        private boolean isElement;
        private String uri;
        private String localName;
        private Property property;

        /**
         * Default constructor.
         */
        protected GlobalRef() {
        }

        public void setOwningType(SDOType owningType) {
            this.owningType = owningType;
        }

        public SDOType getOwningType() {
            return owningType;
        }

        public String getUri() {
            return uri;
        }

        public void setUri(String theUri) {
            uri = theUri;
        }

        public Property getProperty() {
            return property;
        }

        public void setProperty(Property theProperty) {
            property = theProperty;
        }

        public String getLocalName() {
            return localName;
        }

        public void setLocalName(String theLocalName) {
            localName = theLocalName;
        }

        public boolean isElement() {
            return isElement;
        }

        public void setIsElement(boolean isElem) {
            isElement = isElem;
        }
    }

    private java.util.List<NonContainmentReference> getNonContainmentReferences() {
        if (null == nonContainmentReferences) {
            nonContainmentReferences = new ArrayList<NonContainmentReference>();
        }
        return nonContainmentReferences;
    }

    private Map<Type, java.util.List<GlobalRef>> getGlobalRefs() {
        if (null == globalRefs) {
            globalRefs = new HashMap<Type, java.util.List<GlobalRef>>();
        }
        return globalRefs;
    }

    public boolean isImportProcessor() {
        return isImportProcessor;
    }

    public void setIsImportProcessor(boolean isImport) {
        isImportProcessor = isImport;
    }

    private void preprocessGlobalTypes(Schema schema) {
        String targetNamespace = schema.getTargetNamespace();

        // Global Complex Types
        Collection<ComplexType> globalComplexTypes = schema.getTopLevelComplexTypes().values();
        for(ComplexType globalComplexType : globalComplexTypes) {
            QName xsdQName = new QName(targetNamespace, globalComplexType.getName());
            SDOType sdoType = preprocessComplexType(globalComplexType, schema);
            sdoType.setXsdType(xsdQName);
            generatedTypesByXsdQName.put(xsdQName, sdoType);
        }

        // Global Simple Types
        Collection<SimpleType> globalSimpleTypes = schema.getTopLevelSimpleTypes().values();
        for(SimpleType globalSimpleType : globalSimpleTypes) {
            QName xsdQName = new QName(targetNamespace, globalSimpleType.getName());
            SDOType sdoType = preprocessSimpleType(globalSimpleType, schema);
            sdoType.setXsdType(xsdQName);
            generatedTypesByXsdQName.put(xsdQName, sdoType);
        }
    }

    /**
     * Return the SDOType (new or existing) corresponding to this complex type.
     */
    private SDOType preprocessComplexType(ComplexType complexType, Schema schema) {
        String typeName = (String) complexType.getAttributesMap().get(SDOConstants.SDOXML_NAME_QNAME);
        if(null == typeName) {
            typeName = complexType.getName();
        }

        SDOTypeHelper sdoTypeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();
        String typeURI = schema.getTargetNamespace();
        SDOType sdoType = (SDOType) sdoTypeHelper.getType(typeURI, typeName);
        QName qName = new QName(schema.getTargetNamespace(), complexType.getName());

        if(null == sdoType) {
            sdoType = (SDOType)getGeneratedTypes().get(qName);
            if(sdoType == null) {
                sdoType = new SDOType(typeURI, typeName, sdoTypeHelper);
                sdoType.setXsdLocalName(complexType.getName());
                sdoType.preInitialize(packageName, namespaceResolvers);
            }
            sdoType.setXsd(true);
            if(!sdoType.getQName().equals(sdoType.getXsdType())) {
            // sdoType.setInstanceProperty(nameProperty, typeName);
            }
            getGeneratedTypesByXsdQName().put(qName, sdoType);
            getGeneratedTypes().put(sdoType.getQName(), sdoType);
        } else if(!returnAllTypes) {
            processedComplexTypes.put(qName, complexType);
        }
        return sdoType;
    }

    /**
     * Return the SDODataType (new or existing) corresponding to this simple type.
     */
    private SDODataType preprocessSimpleType(SimpleType simpleType, Schema schema) {
        String typeName = (String) simpleType.getAttributesMap().get(SDOConstants.SDOXML_NAME_QNAME);
        if(null == typeName) {
            typeName = simpleType.getName();
        }

        SDOTypeHelper sdoTypeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();
        String typeURI = schema.getTargetNamespace();
        SDODataType sdoDataType = (SDODataType) sdoTypeHelper.getType(typeURI, typeName);
        QName qName = new QName(schema.getTargetNamespace(), simpleType.getName());
        if(null == sdoDataType) {
            SDOType existingType = (SDOType)getGeneratedTypes().get(qName);
            if(null == existingType) {
                existingType = (SDOType) aHelperContext.getTypeHelper().getType(qName.getNamespaceURI(), qName.getLocalPart());
            }
            if(existingType != null && existingType.isFinalized()) {
                return (SDODataType)existingType;
            }
            sdoDataType = new SDODataType(typeURI, typeName, sdoTypeHelper);
            String instanceClassValue = (String) simpleType.getAttributesMap().get(SDOConstants.SDOJAVA_INSTANCECLASS_QNAME);
            if (instanceClassValue != null) {
                sdoDataType.setInstanceProperty(SDOConstants.JAVA_CLASS_PROPERTY, instanceClassValue);
            }

            if(existingType != null) {
                //Existing type was started in an import, but not as an instance of
                //SDODataType. Remove original type and copy referencing properties
                generatedTypes.remove(qName);
                generatedTypesByXsdQName.remove(qName);
                Iterator nonFinalizedProps = existingType.getNonFinalizedReferencingProps().iterator();
                Iterator nonFinalizedUris = existingType.getNonFinalizedMappingURIs().iterator();
                while(nonFinalizedProps.hasNext()) {
                    SDOProperty next = (SDOProperty)nonFinalizedProps.next();
                    next.setType(sdoDataType);
                    sdoDataType.getNonFinalizedReferencingProps().add(next);
                    sdoDataType.getNonFinalizedMappingURIs().add(nonFinalizedUris.next());
                }
                if(anonymousTypes.contains(existingType)) {
                  anonymousTypes.remove(existingType);
                }
            }
            sdoDataType.setXsdLocalName(simpleType.getName());
            sdoDataType.setXsd(true);
            if(!sdoDataType.getQName().equals(sdoDataType.getXsdType())) {
                // sdoDataType.setInstanceProperty(nameProperty, typeName);
            }
            generatedTypesByXsdQName.put(qName, sdoDataType);
            getGeneratedTypes().put(sdoDataType.getQName(), sdoDataType);
        } else if(!returnAllTypes) {
            processedSimpleTypes.put(qName, simpleType);
        }
        return sdoDataType;
    }

    private SDOType getTypeForXSDQName(QName xsdQName) {
        SDOType sdoType = generatedTypesByXsdQName.get(xsdQName);
        if(null == sdoType) {
            SDOTypeHelper sdoTypeHelper = (SDOTypeHelper)aHelperContext.getTypeHelper();
            sdoType = sdoTypeHelper.getSDOTypeFromXSDType(xsdQName);
        }
        return sdoType;
    }

}
