/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights 
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must 
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written 
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans.impl.schema;

import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.QNameSetBuilder;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.XmlAnySimpleType;
import org.apache.xmlbeans.SchemaStringEnumEntry;
import org.apache.xmlbeans.XmlByte;
import org.apache.xmlbeans.XmlShort;

import java.util.*;
import java.math.BigInteger;

import javax.xml.namespace.QName;

public class StscJavaizer
{
    /**
     * Does a topo walk of all the types to resolve them.
     */
    public static void javaizeAllTypes(boolean javaize)
    {
        StscState state = StscState.get();

        List allSeenTypes = new ArrayList();
        allSeenTypes.addAll(Arrays.asList(state.documentTypes()));
        allSeenTypes.addAll(Arrays.asList(state.attributeTypes()));
        allSeenTypes.addAll(Arrays.asList(state.globalTypes()));

        // First distribute the global names among the top entities.
        if (javaize)
            assignGlobalJavaNames(allSeenTypes);

        // now fully javaize everything deeply.
        for (int i = 0; i < allSeenTypes.size(); i++)
        {
            SchemaType gType = (SchemaType)allSeenTypes.get(i);
            if (javaize)
            {
                javaizeType((SchemaTypeImpl)gType);
                String className = gType.getFullJavaName();
                if (className != null)
                    state.addClassname(className.replace('$', '.'), gType);
            }
            else
                skipJavaizingType((SchemaTypeImpl)gType);
            allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes()));
        }
    }

    static void assignGlobalJavaNames(Collection schemaTypes)
    {
        HashSet usedNames = new HashSet();
        StscState state = StscState.get();

        for (Iterator i = schemaTypes.iterator(); i.hasNext(); )
        {
            SchemaTypeImpl sImpl = (SchemaTypeImpl)i.next();
            QName topName = findTopName(sImpl);
            String pickedName = state.getJavaname(topName);
            if (sImpl.isUnjavaized())
            {
                sImpl.setFullJavaName(pickFullJavaClassName(usedNames, findTopName(sImpl), pickedName, sImpl.isDocumentType(), sImpl.isAttributeType()));
                sImpl.setFullJavaImplName(pickFullJavaImplName(usedNames, sImpl.getFullJavaName()));
            }
        }
    }

    private static boolean isStringType(SchemaType type)
    {
        if (type == null || type.getSimpleVariety() != SchemaType.ATOMIC)
            return false;
        return (type.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_STRING);
    }

    static String pickConstantName(Set usedNames, String words)
    {
        String base = NameUtil.upperCaseUnderbar(words);

        if (base.length() == 0)
        {
            base = "X";
        }

        if (base.startsWith("INT_")) // reserved for int codes
        {
            base = "X_" + base;
        }

        String uniqName;
        int index = 1;
        for (uniqName = base; usedNames.contains(uniqName); )
        {
            index++;
            uniqName = base + "_" + index;
        }

        usedNames.add(uniqName);

        return uniqName;
    }

    static void skipJavaizingType(SchemaTypeImpl sImpl)
    {
        if (sImpl.isJavaized())
            return;
        
        SchemaTypeImpl baseType = (SchemaTypeImpl)sImpl.getBaseType();
        if (baseType != null)
            skipJavaizingType(baseType);
        
        sImpl.startJavaizing();
        secondPassProcessType(sImpl);
        sImpl.finishJavaizing();
    }

    static void secondPassProcessType(SchemaTypeImpl sImpl)
    {
        if (isStringType(sImpl))
        {
            XmlAnySimpleType[] enumVals = sImpl.getEnumerationValues();

            // if this is an enumerated string type, values are to be
            // javaized as constants.
            if (enumVals != null)
            {
                SchemaStringEnumEntry[] entryArray = new SchemaStringEnumEntry[enumVals.length];
                SchemaType basedOn = sImpl.getBaseEnumType();
                if (basedOn == sImpl)
                {
                    Set usedNames = new HashSet();
                    for (int i = 0; i < enumVals.length; i++)
                    {
                        String val = enumVals[i].getStringValue();

                        entryArray[i] = new SchemaStringEnumEntryImpl(val, i + 1, pickConstantName(usedNames, val));
                    }
                }
                else
                {
                    for (int i = 0; i < enumVals.length; i++)
                    {
                        String val = enumVals[i].getStringValue();
                        entryArray[i] = basedOn.enumEntryForString(val);
                    }
                }
                sImpl.setStringEnumEntries(entryArray);
            }
        }
    }

    static void javaizeType(SchemaTypeImpl sImpl)
    {
        if (sImpl.isJavaized())
            return;

        SchemaTypeImpl baseType = (SchemaTypeImpl)sImpl.getBaseType();
        if (baseType != null)
            javaizeType(baseType);

        sImpl.startJavaizing();

        sImpl.setCompiled(true);

        secondPassProcessType(sImpl);

        if (!sImpl.isSimpleType())
        {
            SchemaProperty[] eltProps = sImpl.getElementProperties();
            SchemaProperty[] attrProps = sImpl.getAttributeProperties();

            // element setters result from a computation
            if (eltProps.length > 0)
                assignJavaElementSetterModel(eltProps, sImpl.getContentModel());

            // Handing out java names - this permits us to avoid collisions.
            Set usedPropNames = new HashSet();

            // Assign names in two passes: first inherited names, then others.
            for (boolean doInherited = true; ; doInherited = false)
            {
                if (eltProps.length > 0)
                    assignJavaPropertyNames(usedPropNames, eltProps, baseType, doInherited);

                assignJavaPropertyNames(usedPropNames, attrProps, baseType, doInherited);

                if (doInherited == false)
                    break;
            }

            SchemaProperty[] allprops = sImpl.getProperties();

            // determine whether order insensitive
            boolean insensitive = isPropertyModelOrderInsensitive(allprops);

            // Fill in the java type codes now.
            // This depends on recursive type information, so it's done in typechecking
            assignJavaTypeCodes(allprops);

            sImpl.setOrderSensitive(!insensitive);
        }

        // assign java type names to anonymous types
        assignJavaAnonymousTypeNames(sImpl);

        sImpl.finishJavaizing();
    }

    static void assignJavaAnonymousTypeNames(SchemaTypeImpl outerType)
    {
        Set usedTypeNames = new HashSet();
        SchemaType[] anonymousTypes = outerType.getAnonymousTypes();
        StscState state = StscState.get();

        // Because we generate nested java interfaces, and nested
        // interface names must not be the same as an ancestor, use up
        // the ancestors

        for ( SchemaType scanOuterType = outerType ;
              scanOuterType != null ;
              scanOuterType = scanOuterType.getOuterType() )
        {
            usedTypeNames.add( scanOuterType.getShortJavaName() );
        }

        for ( SchemaType scanOuterType = outerType ;
              scanOuterType != null ;
              scanOuterType = scanOuterType.getOuterType() )
        {
            usedTypeNames.add( scanOuterType.getShortJavaImplName() );
        }

        // and because things are problematic if an inner type name
        // is the same as a top-level package name, also get rid of that
        // collision
        usedTypeNames.add(getOutermostPackage(outerType.getFullJavaName()));

        // assign names
        for (int i = 0; i < anonymousTypes.length; i++)
        {
            SchemaTypeImpl sImpl = (SchemaTypeImpl)anonymousTypes[i];
            if (sImpl == null) // already handled in first pass
                continue;
            if (sImpl.isSkippedAnonymousType())
                continue;
            String localname = null;
            String javaname = null;

            SchemaField containerField = sImpl.getContainerField();
            if (containerField != null)
            {
                QName qname = sImpl.getContainerField().getName();
                localname = qname.getLocalPart();
                javaname = state.getJavaname(sImpl.getContainerField().getName());
            }
            else
            {
                // not defined inside an Elt or Attr: must be a nested simple type
                switch (sImpl.getOuterType().getSimpleVariety())
                {
                    case SchemaType.UNION:
                        javaname = "Member"; break;
                    case SchemaType.LIST:
                        javaname = "Item"; break;
                    case SchemaType.ATOMIC:
                    default:
                        assert(false) : "Weird type " + sImpl.toString();
                        javaname = "Base"; break;
                }
            }
            sImpl.setShortJavaName(
                    pickInnerJavaClassName(usedTypeNames, localname, javaname));
            sImpl.setShortJavaImplName(
                    pickInnerJavaImplName(usedTypeNames, localname, javaname == null ? null : javaname + "Impl"));
        }
    }

    /**
     * Used to compute the setter model.
     *
     * Returns the set of all QNames of elements that could possibly be
     * contained in the given contentModel. The state variable is used
     * to record the results, so that if they are needed again later,
     * they do not need to be recomputed.
     */
    static QNameSet computeAllContainedElements(SchemaParticle contentModel, Map state)
    {
        // Remember previously computed results to avoid complexity explosion
        QNameSet result = (QNameSet)state.get(contentModel);
        if (result != null)
            return result;

        QNameSetBuilder builder;

        switch (contentModel.getParticleType())
        {
            case SchemaParticle.ALL:
            case SchemaParticle.CHOICE:
            case SchemaParticle.SEQUENCE:
            default:
                builder = new QNameSetBuilder();
                for (int i = 0; i < contentModel.countOfParticleChild(); i++)
                {
                    builder.addAll(computeAllContainedElements(contentModel.getParticleChild(i), state));
                }
                result = builder.toQNameSet();
                break;

            case SchemaParticle.WILDCARD:
                result = contentModel.getWildcardSet();
                break;

            case SchemaParticle.ELEMENT:
                result = QNameSet.singleton(contentModel.getName());
                break;
        }
        state.put(contentModel, result);
        return result;
    }

    /**
     * Used to compute setter model.
     *
     * Returns the QNameSet of all elements that can possibly come before an
     * element whose name is given by the target in a valid instance of the
     * contentModel.  When appending an element, it comes before the first
     * one that is not in this set.
     */
    static QNameSet computeNondelimitingElements(QName target, SchemaParticle contentModel, Map state)
    {
        QNameSet allContents = computeAllContainedElements(contentModel, state);
        if (!allContents.contains(target))
            return QNameSet.EMPTY;

        // If iterated, then all contents are delimiting.
        if (contentModel.getMaxOccurs() == null ||
            contentModel.getMaxOccurs().compareTo(BigInteger.ONE) > 0)
            return allContents;

        QNameSetBuilder builder;

        switch (contentModel.getParticleType())
        {
            case SchemaParticle.ALL:
            case SchemaParticle.ELEMENT:
            default:
                return allContents;

            case SchemaParticle.WILDCARD:
                return QNameSet.singleton(target);

            case SchemaParticle.CHOICE:
                builder = new QNameSetBuilder();
                for (int i = 0; i < contentModel.countOfParticleChild(); i++)
                {
                    QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state);
                    if (childContents.contains(target))
                        builder.addAll(computeNondelimitingElements(target, contentModel.getParticleChild(i), state));
                }
                return builder.toQNameSet();

            case SchemaParticle.SEQUENCE:
                builder = new QNameSetBuilder();
                boolean seenTarget = false;
                for (int i = contentModel.countOfParticleChild(); i > 0; )
                {
                    i--;
                    QNameSet childContents = computeAllContainedElements(contentModel.getParticleChild(i), state);
                    if (seenTarget)
                    {
                        builder.addAll(childContents);
                    }
                    else if (childContents.contains(target))
                    {
                        builder.addAll(computeAllContainedElements(contentModel.getParticleChild(i), state));
                        seenTarget = true;
                    }
                }
                return builder.toQNameSet();
        }
    }

    static void assignJavaElementSetterModel(SchemaProperty[] eltProps, SchemaParticle contentModel)
    {
        // To compute the element setter model, we need to compute the
        // delimiting elements for each element.

        Map state = new HashMap();
        QNameSet allContents = computeAllContainedElements(contentModel, state);

        for (int i = 0; i < eltProps.length; i++)
        {
            SchemaPropertyImpl sImpl = (SchemaPropertyImpl)eltProps[i];
            QNameSet nde = computeNondelimitingElements(sImpl.getName(), contentModel, state);
            QNameSetBuilder builder = new QNameSetBuilder(allContents);
            builder.removeAll(nde);
            sImpl.setJavaSetterDelimiter(builder.toQNameSet());
        }
    }

    static void assignJavaPropertyNames(Set usedNames, SchemaProperty[] props, SchemaType baseType, boolean doInherited)
    {
        StscState state = StscState.get();

        // two passes: first deal with inherited properties, then with new ones.
        // this ensures that we match up with base class definitions cleanly

        for (int i = 0; i < props.length; i++)
        {
            SchemaPropertyImpl sImpl = (SchemaPropertyImpl)props[i];

            SchemaProperty baseProp =
               (sImpl.isAttribute() ?
                    baseType.getAttributeProperty(sImpl.getName()) :
                    baseType.getElementProperty(sImpl.getName()));

            if ((baseProp != null) != doInherited)
                continue;

            QName propQName = sImpl.getName();

            String theName;

            if (baseProp == null)
                theName = pickJavaPropertyName(usedNames, propQName.getLocalPart(), state.getJavaname(propQName));
            else
            {
                theName = baseProp.getJavaPropertyName();
                assert(!usedNames.contains(theName));
                usedNames.add(theName);
            }

            sImpl.setJavaPropertyName(theName);

            boolean isArray = (sImpl.getMaxOccurs() == null ||
                sImpl.getMaxOccurs().compareTo(BigInteger.ONE) > 0);
            boolean isSingleton = !isArray && (sImpl.getMaxOccurs().signum() > 0);
            boolean isOption = isSingleton && (sImpl.getMinOccurs().signum() == 0);
            SchemaType javaBasedOnType = sImpl.getType();

            if (baseProp != null)
            {
                if (baseProp.extendsJavaArray())
                {
                    isSingleton = false;
                    isOption = false;
                    isArray = true;
                }
                if (baseProp.extendsJavaSingleton())
                {
                    isSingleton = true;
                }
                if (baseProp.extendsJavaOption())
                {
                    isOption = true;
                }
                javaBasedOnType = baseProp.javaBasedOnType();
            }

            sImpl.setExtendsJava(javaBasedOnType.getRef(), isSingleton, isOption, isArray);
        }

    }

    static void assignJavaTypeCodes(SchemaProperty[] properties)
    {
        for (int i = 0; i < properties.length; i++)
        {
            SchemaPropertyImpl sImpl = (SchemaPropertyImpl)properties[i];
            SchemaType sType = sImpl.javaBasedOnType();
            sImpl.setJavaTypeCode(javaTypeCodeForType(sType));
        }
    }

    static int javaTypeCodeInCommon(SchemaType[] types)
    {
        if (types == null || types.length == 0)
            return SchemaProperty.XML_OBJECT;

        int code = javaTypeCodeForType(types[0]);
        if (code == SchemaProperty.JAVA_OBJECT)
            return code;
        for (int i = 1; i < types.length; i++)
        {
            // if any two are different, the answer is java.lang.Object
            if (code != javaTypeCodeForType(types[i]))
                return SchemaProperty.JAVA_OBJECT;
        }
        return code;
    }

    static int javaTypeCodeForType(SchemaType sType)
    {
        if (!sType.isSimpleType())
            return SchemaProperty.XML_OBJECT;

        if (sType.getSimpleVariety() == SchemaType.UNION)
        {
            // see if we can find an interesting common base type, e.g., for string enums
            SchemaType baseType = sType.getUnionCommonBaseType();
            if (baseType != null && !baseType.isURType())
                sType = baseType;
            else
                return javaTypeCodeInCommon(sType.getUnionConstituentTypes());
        }

        if (sType.getSimpleVariety() == SchemaType.LIST)
            return SchemaProperty.JAVA_LIST;

        if (sType.isURType())
            return SchemaProperty.XML_OBJECT;

        switch (sType.getPrimitiveType().getBuiltinTypeCode())
        {
            case SchemaType.BTC_ANY_SIMPLE:
                // return SchemaProperty.XML_OBJECT;
                return SchemaProperty.JAVA_STRING;

            case SchemaType.BTC_BOOLEAN:
                return SchemaProperty.JAVA_BOOLEAN;

            case SchemaType.BTC_BASE_64_BINARY:
                return SchemaProperty.JAVA_BYTE_ARRAY;

            case SchemaType.BTC_HEX_BINARY:
                return SchemaProperty.JAVA_BYTE_ARRAY;

            case SchemaType.BTC_ANY_URI:
                return SchemaProperty.JAVA_STRING;

            case SchemaType.BTC_QNAME:
                return SchemaProperty.JAVA_QNAME;

            case SchemaType.BTC_NOTATION:
                return SchemaProperty.XML_OBJECT;

            case SchemaType.BTC_FLOAT:
                return SchemaProperty.JAVA_FLOAT;

            case SchemaType.BTC_DOUBLE:
                return SchemaProperty.JAVA_DOUBLE;

            case SchemaType.BTC_DECIMAL:
                switch (sType.getDecimalSize())
                {
                    case SchemaType.SIZE_BYTE:
                        return SchemaProperty.JAVA_BYTE;
                    case SchemaType.SIZE_SHORT:
                        return SchemaProperty.JAVA_SHORT;
                    case SchemaType.SIZE_INT:
                        return SchemaProperty.JAVA_INT;
                    case SchemaType.SIZE_LONG:
                        return SchemaProperty.JAVA_LONG;
                    case SchemaType.SIZE_BIG_INTEGER:
                        return SchemaProperty.JAVA_BIG_INTEGER;
                    case SchemaType.SIZE_BIG_DECIMAL:
                    default:
                        return SchemaProperty.JAVA_BIG_DECIMAL;
                }

            case SchemaType.BTC_STRING:
                if (isStringType(sType.getBaseEnumType()))
                    return SchemaProperty.JAVA_ENUM;
                return SchemaProperty.JAVA_STRING;

            case SchemaType.BTC_DURATION:
                return SchemaProperty.JAVA_GDURATION;

            case SchemaType.BTC_DATE_TIME:
            case SchemaType.BTC_DATE:
                // return SchemaProperty.JAVA_DATE; // converted to calendar

            case SchemaType.BTC_TIME:
            case SchemaType.BTC_G_YEAR_MONTH:
            case SchemaType.BTC_G_YEAR:
            case SchemaType.BTC_G_MONTH_DAY:
            case SchemaType.BTC_G_DAY:
            case SchemaType.BTC_G_MONTH:
                // return SchemaProperty.JAVA_GDATE; // converted to calendar (JAX-B)
                return SchemaProperty.JAVA_CALENDAR;

            default:
                assert(false) : "unrecognized code " + sType.getPrimitiveType().getBuiltinTypeCode();
                throw new IllegalStateException("unrecognized code " + sType.getPrimitiveType().getBuiltinTypeCode() + " of " + sType.getPrimitiveType().getName());
        }
    }

    static boolean isPropertyModelOrderInsensitive(SchemaProperty[] properties)
    {
        for (int i = 0; i < properties.length; i++)
        {
            SchemaProperty prop = properties[i];
            if (prop.hasNillable() == SchemaProperty.VARIABLE)
                return false;
            if (prop.hasDefault() == SchemaProperty.VARIABLE)
                return false;
            if (prop.hasFixed() == SchemaProperty.VARIABLE)
                return false;
            if (prop.hasDefault() != SchemaProperty.NEVER &&
                prop.getDefaultText() == null)
                return false;
        }
        return true;
    }

    static boolean protectReservedGlobalClassNames(String name)
    {
        int i = name.lastIndexOf('.');
        String lastSegment = name.substring(i + 1);
        if (lastSegment.endsWith("Document") && !lastSegment.equals("Document"))
            return true;
        return false;
    }

    static boolean protectReservedInnerClassNames(String name)
    {
        return (name.equals("Enum") || name.equals("Factory"));
    }

    static String[] PROTECTED_PROPERTIES = {
        "StringValue",
        "BooleanValue",
        "ByteValue",
        "ShortValue",
        "IntValue",
        "LongValue",
        "BigIntegerValue",
        "BigDecimalValue",
        "FloatValue",
        "DoubleValue",
        "ByteArrayValue",
        "EnumValue",
        "CalendarValue",
        "DateValue",
        "GDateValue",
        "GDurationValue",
        "QNameValue",
        "ListValue",
        "ObjectValue",
        "Class",
    };
    static Set PROTECTED_PROPERTIES_SET = new HashSet(Arrays.asList(PROTECTED_PROPERTIES));

    static boolean protectReservedPropertyNames(String name)
    {
        return PROTECTED_PROPERTIES_SET.contains(name) ||
            (name.endsWith("Array") && !name.equals("Array"));
    }

    static String pickFullJavaClassName(Set usedNames, QName qName, String configname, boolean isDocument, boolean isAttrType)
    {
        String base;
        boolean protect;

        if (configname != null && configname.indexOf('.') >= 0)
        {
            // a configname with dots defines the fully qualified java class name
            base = configname;
            protect = protectReservedGlobalClassNames(base);
        }
        else
        {
            StscState state = StscState.get();
            String uri = qName.getNamespaceURI();

            base = NameUtil.getClassNameFromQName(qName);

            // Check to see if we have a mapping from namespace URI to Java package
            // name. If so, apply the mapped package prefix at the beginning of
            // the base name

            String pkgPrefix = state.getPackageOverride(uri);

            if (pkgPrefix != null)
            {
                // Form the new qualified class name from the new package name
                // and the old class name
                base = pkgPrefix + "." + base.substring(base.lastIndexOf('.') + 1);
            }

            // See if there is a prefix...
            String javaPrefix = state.getJavaPrefix(uri);
            if (javaPrefix != null)
                base = base.substring(0, base.lastIndexOf('.') + 1) + javaPrefix + base.substring(base.lastIndexOf('.') + 1);

            // a configname without dots may override the shortname part.
            if (configname != null)
            {
                base = base.substring(0, base.lastIndexOf('.') + 1) + configname;
            }

            protect = protectReservedGlobalClassNames(base);
            if (configname == null)
            {
                // add special suffix
                if (isDocument)
                    base = base + "Document";
                else if (isAttrType)
                    base = base + "Attribute";

                // add configured suffix
                String javaSuffix = state.getJavaSuffix(uri);
                if (javaSuffix != null)
                    base = base + javaSuffix;
            }
        }

        String outermostPkg = getOutermostPackage(base);

        int index = 1;
        String uniqName;
        if (protect)
            uniqName = base + index;
        else
            uniqName = base;
        while (usedNames.contains(uniqName.toLowerCase()) || uniqName.equals(outermostPkg))
        {
            index++;
            uniqName = base + index;
        }

        usedNames.add(uniqName.toLowerCase());

        return uniqName;
    }

    static String getOutermostPackage(String fqcn)
    {
        if (fqcn == null)
            return "";

        // remove class name
        int lastdot = fqcn.indexOf('.');
        if (lastdot < 0)
            return "";

        // remove outer package names
        return fqcn.substring(0, lastdot);
    }

    static String pickFullJavaImplName(Set usedNames, String intfName)
    {
        // Strip off the package from the class name so we can replace it
        String className = intfName;
        String pkgName = null;
        int index = intfName.lastIndexOf('.');
        if (index >= 0)
        {
            className = intfName.substring(index + 1);
            pkgName = intfName.substring(0, index);
        }

        // Form the new qualified class name from the new package name
        // and the old class name
        String base = pkgName + ".impl." + className + "Impl";

        index = 1;
        String uniqName = base;
        while (usedNames.contains(uniqName.toLowerCase()))
        {
            index++;
            uniqName = base + index;
        }

        usedNames.add(uniqName.toLowerCase());

        return uniqName;
    }

    static String pickJavaPropertyName(Set usedNames, String localName, String javaName)
    {
        if (javaName == null)
            javaName = NameUtil.upperCamelCase(localName);
        boolean protect = protectReservedPropertyNames(javaName);
        String uniqName;
        int index = 1;
        if (protect)
            uniqName = javaName + index;
        else
            uniqName = javaName;
        while (usedNames.contains(uniqName))
        {
            index++;
            uniqName = javaName + index;
        }

        usedNames.add(uniqName);

        return uniqName;
    }

    static String pickInnerJavaClassName(Set usedNames, String localName, String javaName)
    {
        if (javaName == null)
            javaName = NameUtil.upperCamelCase(localName);
        boolean protect = protectReservedInnerClassNames(javaName);
        String uniqName;
        int index = 1;
        if (protect)
            uniqName = javaName + index;
        else
            uniqName = javaName;
        while (usedNames.contains(uniqName))
        {
            index++;
            uniqName = javaName + index;
        }

        usedNames.add(uniqName);

        return uniqName;
    }

    static String pickInnerJavaImplName(Set usedNames, String localName, String javaName)
    {
        if (javaName == null)
            javaName = NameUtil.upperCamelCase(localName) + "Impl";
        String uniqName = javaName;
        int index = 1;
        while (usedNames.contains(uniqName))
        {
            index++;
            uniqName = javaName + index;
        }

        usedNames.add(uniqName);

        return uniqName;
    }

    static QName findTopName(SchemaType sType)
    {
        if (sType.getName() != null)
            return sType.getName();

        if (sType.isDocumentType())
        {
            // A document type must have a content model consisting of a single elt
            if (sType.getContentModel() == null || sType.getContentModel().getParticleType() != SchemaParticle.ELEMENT)
                throw new IllegalStateException();
            return (sType.getDocumentElementName());
        }

        if (sType.isAttributeType())
        {
            if (sType.getAttributeModel() == null || sType.getAttributeModel().getAttributes().length != 1)
                throw new IllegalStateException();
            return sType.getAttributeTypeAttributeName();
        }

        SchemaField sElt = sType.getContainerField();
        assert(sElt != null);
        assert(sType.getOuterType() == null);
        return sElt.getName();
    }

}
