/*
 * 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 anonymousIterator = getAnonymousTypes().iterator();

            while (anonymousIterator.hasNext()) {
                SDOType nextSDOType = (SDOType) 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 = (java.util.List) 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 = (java.util.List) 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 = (java.util.List) 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;
    }

}
