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

package com.sun.tools.xjc.reader.xmlschema;

import java.io.StringWriter;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import jakarta.activation.MimeTypeParseException;
import jakarta.xml.bind.DatatypeConverter;

import com.sun.codemodel.JJavaName;
import com.sun.codemodel.util.JavadocEscapeWriter;
import org.glassfish.jaxb.core.v2.WellKnownNamespace;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.model.CBuiltinLeafInfo;
import com.sun.tools.xjc.model.CClassInfo;
import com.sun.tools.xjc.model.CClassInfoParent;
import com.sun.tools.xjc.model.CClassRef;
import com.sun.tools.xjc.model.CEnumConstant;
import com.sun.tools.xjc.model.CEnumLeafInfo;
import com.sun.tools.xjc.model.CNonElement;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.model.TypeUse;
import com.sun.tools.xjc.model.TypeUseFactory;
import com.sun.tools.xjc.reader.Const;
import com.sun.tools.xjc.reader.Ring;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIEnum;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIEnumMember;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIProperty;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.BindInfo;
import com.sun.tools.xjc.reader.xmlschema.bindinfo.EnumMemberMode;
import com.sun.tools.xjc.util.MimeTypeRange;

import static org.glassfish.jaxb.core.v2.WellKnownNamespace.XML_MIME_URI;

import org.glassfish.jaxb.core.v2.runtime.SwaRefAdapterMarker;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSFacet;
import com.sun.xml.xsom.XSListSimpleType;
import com.sun.xml.xsom.XSRestrictionSimpleType;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSUnionSimpleType;
import com.sun.xml.xsom.XSVariety;
import com.sun.xml.xsom.impl.util.SchemaWriter;
import com.sun.xml.xsom.visitor.XSSimpleTypeFunction;
import com.sun.xml.xsom.visitor.XSVisitor;

import org.xml.sax.Locator;

import javax.xml.XMLConstants;

/**
 * Builds {@link TypeUse} from simple types.
 *
 * <p>
 * This code consists of two main portions. The {@link #compose(XSSimpleType)} method
 * and {@link #composer} forms an outer cycle, which gradually ascends the type
 * inheritance chain until it finds the suitable binding. When it does this
 * {@link #initiatingType} is set to the type which started binding, so that we can refer
 * to the actual constraint facets and such that are applicable on the type.
 *
 * <p>
 * For each intermediate type in the chain, the {@link #find(XSSimpleType)} method
 * is used to find the binding on that type, sine the outer loop is doing the ascending,
 * this method only sees if the current type has some binding available.
 *
 * <p>
 * There is at least one ugly code that you need to aware of
 * when you are modifying the code. See the documentation
 * about <a href="package.html#stref_cust">
 * "simple type customization at the point of reference."</a>
 *
 *
 * @author
 *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
 */
public final class SimpleTypeBuilder extends BindingComponent {

    protected final BGMBuilder builder = Ring.get(BGMBuilder.class);

    private final Model model = Ring.get(Model.class);

    /**
     * The component that is refering to the simple type
     * which we are building. This is ugly but necessary
     * to support the customization of simple types at
     * its point of reference. See my comment at the header
     * of this class for details.
     *
     * UGLY: Implemented as a Stack of XSComponent to fix a bug
     */
    public final Stack<XSComponent> refererStack = new Stack<>();

    /**
     * Records what xmime:expectedContentTypes annotations we honored and processed,
     * so that we can later check if the user had these annotations in the places
     * where we didn't anticipate them.
     */
    private final Set<XSComponent> acknowledgedXmimeContentTypes = new HashSet<>();

    /**
     * The type that was originally passed to this {@link SimpleTypeBuilder#build(XSSimpleType)}.
     * Never null.
     */
    private XSSimpleType initiatingType;

    /** {@link TypeUse}s for the built-in types. Read-only. */
    public static final Map<String,TypeUse> builtinConversions;


    /**
     * Entry point from outside. Builds a BGM type expression
     * from a simple type schema component.
     *
     * @param type
     *      the simple type to be bound.
     */
    public TypeUse build( XSSimpleType type ) {
        XSSimpleType oldi = initiatingType;
        this.initiatingType = type;

        TypeUse e = checkRefererCustomization(type);
        if(e==null)
            e = compose(type);

        initiatingType = oldi;

        return e;
    }

    /**
     * A version of the {@link #build(XSSimpleType)} method
     * used to bind the definition of a class generated from
     * the given simple type.
     */
    public TypeUse buildDef( XSSimpleType type ) {
        XSSimpleType oldi = initiatingType;
        this.initiatingType = type;

        TypeUse e = type.apply(composer);

        initiatingType = oldi;

        return e;
    }


    /**
     * Returns a javaType customization specified to the referer, if present.
     * @return can be null.
     */
    private BIConversion getRefererCustomization() {
        BindInfo info = builder.getBindInfo(getReferer());
        BIProperty prop = info.get(BIProperty.class);
        if(prop==null)  return null;
        return prop.getConv();
    }

    public XSComponent getReferer() {
        return refererStack.peek();
    }

    /**
     * Checks if the referer has a conversion customization or not.
     * If it does, use it to bind this simple type. Otherwise
     * return null;
     */
    private TypeUse checkRefererCustomization( XSSimpleType type ) {

        // assertion check. referer must be set properly
        // before the build method is called.
        // since the handling of the simple type point-of-reference
        // customization is very error prone, it deserves a strict
        // assertion check.
        // UGLY CODE WARNING
        XSComponent top = getReferer();

        if( top instanceof XSElementDecl ) {
            // if the parent is element type, its content type must be us.
            XSElementDecl eref = (XSElementDecl)top;
            assert eref.getType()==type;

            // for elements, you can't use <property>,
            // so we allow javaType to appear directly.
            BindInfo info = builder.getBindInfo(top);
            BIConversion conv = info.get(BIConversion.class);
            if(conv!=null) {
                conv.markAsAcknowledged();
                // the conversion is given.
                return conv.getTypeUse(type);
            }
            detectJavaTypeCustomization();
        } else
        if( top instanceof XSAttributeDecl ) {
            XSAttributeDecl aref = (XSAttributeDecl)top;
            assert aref.getType()==type;
            detectJavaTypeCustomization();
        } else
        if( top instanceof XSComplexType ) {
            XSComplexType tref = (XSComplexType)top;
            assert tref.getBaseType()==type || tref.getContentType()==type;
            detectJavaTypeCustomization();
        } else
        if( top == type ) {
            // this means the simple type is built by itself and
            // not because it's referenced by something.
        } else
            // unexpected referer type.
            assert false;

        // now we are certain that the referer is OK.
        // see if it has a conversion customization.
        BIConversion conv = getRefererCustomization();
        if(conv!=null) {
            conv.markAsAcknowledged();
            // the conversion is given.
            return conv.getTypeUse(type);
        } else
            // not found
            return null;
    }

    /**
     * Detect "javaType" customizations placed directly on simple types, rather
     * than being enclosed by "property" and "baseType" customizations (see
     * sec 6.8.1 of the spec).
     *
     * Report an error if any exist.
     */
    private void detectJavaTypeCustomization() {
        BindInfo info = builder.getBindInfo(getReferer());
        BIConversion conv = info.get(BIConversion.class);

        if( conv != null ) {
            // ack this conversion to prevent further error messages
            conv.markAsAcknowledged();

            // report the error
            getErrorReporter().error( conv.getLocation(),
                    Messages.ERR_UNNESTED_JAVATYPE_CUSTOMIZATION_ON_SIMPLETYPE );
        }
    }

    /**
     * Recursively decend the type inheritance chain to find a binding.
     */
    TypeUse compose( XSSimpleType t ) {
        TypeUse e = find(t);
        if(e!=null)     return e;
        return t.apply(composer);
    }

    public final XSSimpleTypeFunction<TypeUse> composer = new XSSimpleTypeFunction<>() {

        @Override
        public TypeUse listSimpleType(XSListSimpleType type) {
            // bind item type individually and then compose them into a list
            // facets on the list shouldn't be taken account when binding item types,
            // so weed to call build(), not compose().
            XSSimpleType itemType = type.getItemType();
            refererStack.push(itemType);
            TypeUse tu = TypeUseFactory.makeCollection(build(type.getItemType()));
            refererStack.pop();
            return tu;
        }

        @Override
        public TypeUse unionSimpleType(XSUnionSimpleType type) {
            boolean isCollection = false;
            for (int i = 0; i < type.getMemberSize(); i++)
                if (type.getMember(i).getVariety() == XSVariety.LIST || type.getMember(i).getVariety() == XSVariety.UNION) {
                    isCollection = true;
                    break;
                }

            TypeUse r = CBuiltinLeafInfo.STRING;
            if (isCollection)
                r = TypeUseFactory.makeCollection(r);
            return r;
        }

        @Override
        public TypeUse restrictionSimpleType(XSRestrictionSimpleType type) {
            // just process the base type.
            return compose(type.getSimpleBaseType());
        }
    };


    /**
     * Checks if there's any binding available on the given type.
     *
     * @return
     *      null if not (which causes the {@link #compose(XSSimpleType)} method
     *      to do ascending.
     */
    private TypeUse find( XSSimpleType type ) {
        TypeUse r;
        boolean noAutoEnum = false;

        // check for user specified conversion
        BindInfo info = builder.getBindInfo(type);
        BIConversion conv = info.get(BIConversion.class);

        if( conv!=null ) {
            // a conversion was found
            conv.markAsAcknowledged();
            return conv.getTypeUse(type);
        }

        // look for enum customization, which is another user specified conversion
        BIEnum en = info.get(BIEnum.class);
        if( en!=null ) {
            en.markAsAcknowledged();

            if(!en.isMapped()) {
                noAutoEnum = true;
            } else {
                // if an enum customization is specified, make sure
                // the type is OK
                if( !canBeMappedToTypeSafeEnum(type) ) {
                    getErrorReporter().error( en.getLocation(),
                        Messages.ERR_CANNOT_BE_TYPE_SAFE_ENUM );
                    getErrorReporter().error( type.getLocator(),
                        Messages.ERR_CANNOT_BE_TYPE_SAFE_ENUM_LOCATION );
                    // recover by ignoring this customization
                    return null;
                }

                // reference?
                if(en.ref!=null) {
                    if(!JJavaName.isFullyQualifiedClassName(en.ref)) {
                        Ring.get(ErrorReceiver.class).error( en.getLocation(),
                            Messages.format(Messages.ERR_INCORRECT_CLASS_NAME, en.ref) );
                        // recover by ignoring @ref
                        return null;
                    }

                    return new CClassRef(model, type, en, info.toCustomizationList() );
                }

                // list and union cannot be mapped to a type-safe enum,
                // so in this stage we can safely cast it to XSRestrictionSimpleType
                return bindToTypeSafeEnum( (XSRestrictionSimpleType)type,
                        en.className, en.javadoc, en.members,
                        getEnumMemberMode().getModeWithEnum(),
                        en.getLocation() );
            }
        }


        // if the type is built in, look for the default binding
        if(XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(type.getTargetNamespace())) {
            String name = type.getName();
            if(name!=null) {
                r = lookupBuiltin(name);
                if(r!=null)
                    return r;
            }
        }

        // also check for swaRef
        if(type.getTargetNamespace().equals(WellKnownNamespace.SWA_URI)) {
            String name = type.getName();
            if(name!=null && name.equals("swaRef"))
                return CBuiltinLeafInfo.STRING.makeAdapted(SwaRefAdapterMarker.class,false);
        }


        // see if this type should be mapped to a type-safe enumeration by default.
        // if so, built a EnumXDucer from it and return it.
        if(type.isRestriction() && !noAutoEnum) {
            XSRestrictionSimpleType rst = type.asRestriction();
            if(shouldBeMappedToTypeSafeEnumByDefault(rst)) {
                r = bindToTypeSafeEnum(rst,null,null, Collections.emptyMap(),
                            getEnumMemberMode(),null);
                if(r!=null)
                    return r;
            }
        }

        return (CNonElement)getClassSelector()._bindToClass(type,null,false);
    }

    private static Set<XSRestrictionSimpleType> reportedEnumMemberSizeWarnings;

    /**
     * Returns true if a type-safe enum should be created from
     * the given simple type by default without an explicit {@code <jaxb:enum>} customization.
     */
    private boolean shouldBeMappedToTypeSafeEnumByDefault( XSRestrictionSimpleType type ) {

        // if not, there will be a problem wrt the class name of this type safe enum type.
        if( type.isLocal() )    return false;

        // if redefined, we should map the new definition, not the old one.
        if( type.getRedefinedBy()!=null )   return false;

        List<XSFacet> facets = type.getDeclaredFacets(XSFacet.FACET_ENUMERATION);
        if( facets.isEmpty() )
            // if the type itself doesn't have the enumeration facet,
            // it won't be mapped to a type-safe enum.
            return false;

        if(facets.size() > builder.getGlobalBinding().getDefaultEnumMemberSizeCap()) {
            // if there are too many facets, it's not very useful
            // produce warning when simple type is not mapped to enum
            // see issue https://jaxb.dev.java.net/issues/show_bug.cgi?id=711

            if(reportedEnumMemberSizeWarnings == null)
                reportedEnumMemberSizeWarnings = new HashSet<>();

            if(!reportedEnumMemberSizeWarnings.contains(type)) {
                getErrorReporter().warning(type.getLocator(), Messages.WARN_ENUM_MEMBER_SIZE_CAP,
                        type.getName(), facets.size(), builder.getGlobalBinding().getDefaultEnumMemberSizeCap());

                reportedEnumMemberSizeWarnings.add(type);
            }

            return false;
        }

        if( !canBeMappedToTypeSafeEnum(type) )
            // we simply can't map this to an enumeration
            return false;

        // check for collisions among constant names. if a collision will happen,
        // don't try to bind it to an enum.

        // return true only when this type is derived from one of the "enum base type".
        for( XSSimpleType t = type; t!=null; t=t.getSimpleBaseType() )
            if( t.isGlobal() && builder.getGlobalBinding().canBeMappedToTypeSafeEnum(t) )
                return true;

        return false;
    }


    private static final Set<String> builtinTypeSafeEnumCapableTypes;

    static {

        // see a bullet of 6.5.1 of the spec.
        String[] typeNames = new String[] {
            "string", "boolean", "float", "decimal", "double", "anyURI"
        };
        Set<String> s = new HashSet<>(Arrays.asList(typeNames));

        builtinTypeSafeEnumCapableTypes = Collections.unmodifiableSet(s);
    }


    /**
     * Returns true if the given simple type can be mapped to a
     * type-safe enum class.
     *
     * <p>
     * JAXB spec places a restrictrion as to what type can be
     * mapped to a type-safe enum. This method enforces this
     * constraint.
     */
    public static boolean canBeMappedToTypeSafeEnum( XSSimpleType type ) {
        do {
            if( XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(type.getTargetNamespace()) ) {
                // type must be derived from one of these types
                String localName = type.getName();
                if( localName!=null ) {
                    if( localName.equals("anySimpleType") )
                        return false;   // catch all case
                    if( localName.equals("ID") || localName.equals("IDREF") )
                        return false;   // not ID/IDREF

                    // other allowed list
                    if( builtinTypeSafeEnumCapableTypes.contains(localName) )
                        return true;
                }
            }

            type = type.getSimpleBaseType();
        } while( type!=null );

        return false;
    }



    /**
     * Builds a type-safe enum conversion from a simple type
     * with enumeration facets.
     *
     * @param className
     *      The class name of the type-safe enum. Or null to
     *      create a default name.
     * @param javadoc
     *      Additional javadoc that will be added at the beginning of the
     *      class, or null if none is necessary.
     * @param members
     *      A map from enumeration values (as String) to BIEnumMember objects.
     *      if some of the value names need to be overrided.
     *      Cannot be null, but the map may not contain entries
     *      for all enumeration values.
     * @param loc
     *      The source location where the above customizations are
     *      specified, or null if none is available.
     */
    private TypeUse bindToTypeSafeEnum( XSRestrictionSimpleType type,
                                        String className, String javadoc, Map<String,BIEnumMember> members,
                                        EnumMemberMode mode, Locator loc ) {

        if( loc==null )  // use the location of the simple type as the default
            loc = type.getLocator();

        if( className==null ) {
            // infer the class name. For this to be possible,
            // the simple type must be a global one.
            if( !type.isGlobal() ) {
                getErrorReporter().error( loc, Messages.ERR_NO_ENUM_NAME_AVAILABLE );
                // recover by returning a meaningless conversion
                return CBuiltinLeafInfo.STRING;
            }
            className = type.getName();
        }

        // we apply name conversion in any case
        className = builder.deriveName(className,type);

        {// compute Javadoc
            StringWriter out = new StringWriter();
            SchemaWriter sw = new SchemaWriter(new JavadocEscapeWriter(out));
            type.visit((XSVisitor)sw);

            if(javadoc!=null)   javadoc += "\n\n";
            else                javadoc = "";

            javadoc += Messages.format( Messages.JAVADOC_HEADING, type.getName() )
                +"\n<pre>\n"+out.getBuffer()+"</pre>";

        }

        // build base type
        refererStack.push(type.getSimpleBaseType());
        TypeUse use = build(type.getSimpleBaseType());
        refererStack.pop();

        if(use.isCollection())
            return null;    // can't bind a list to enum constant

        CNonElement baseDt = use.getInfo();   // for now just ignore that case

        if(baseDt instanceof CClassInfo)
            return null;    // can't bind to an enum if the base is a class, since we don't have the value constrctor

        // if the member names collide, re-generate numbered constant names.
        XSFacet[] errorRef = new XSFacet[1];
        List<CEnumConstant> memberList = buildCEnumConstants(type, false, members, errorRef);
        if(memberList==null || checkMemberNameCollision(memberList)!=null) {
            switch(mode) {
            case SKIP:
                // abort
                return null;
            case ERROR:
                // error
                if(memberList==null) {
                    getErrorReporter().error( errorRef[0].getLocator(),
                        Messages.ERR_CANNOT_GENERATE_ENUM_NAME,
                        errorRef[0].getValue() );
                } else {
                    CEnumConstant[] collision = checkMemberNameCollision(memberList);
                    getErrorReporter().error( collision[0].getLocator(),
                        Messages.ERR_ENUM_MEMBER_NAME_COLLISION,
                        collision[0].getName() );
                    getErrorReporter().error( collision[1].getLocator(),
                        Messages.ERR_ENUM_MEMBER_NAME_COLLISION_RELATED );
                }
                return null;    // recover from error
            case GENERATE:
                // generate
                memberList = buildCEnumConstants(type,true,members,null);
                break;
            }
        }
        if(memberList.isEmpty()) {
            getErrorReporter().error( loc, Messages.ERR_NO_ENUM_FACET );
            return null;
        }

        // use the name of the simple type as the name of the class.
        CClassInfoParent scope;
        if(type.isGlobal())
            scope = new CClassInfoParent.Package(getClassSelector().getPackage(type.getTargetNamespace()));
        else
            scope = getClassSelector().getClassScope();
        CEnumLeafInfo xducer = new CEnumLeafInfo( model, BGMBuilder.getName(type), scope,
            className, baseDt, memberList, type,
            builder.getBindInfo(type).toCustomizationList(), loc );
        xducer.javadoc = javadoc;

        BIConversion conv = new BIConversion.Static( type.getLocator(),xducer);
        conv.markAsAcknowledged();

        // attach this new conversion object to this simple type
        // so that successive look up will use the same object.
        builder.getOrCreateBindInfo(type).addDecl(conv);

        return conv.getTypeUse(type);
    }

    /**
     *
     * @param errorRef
     *      if constant names couldn't be generated, return a reference to that enum facet.
     * @return
     *      null if unable to generate names for some of the constants.
     */
    private List<CEnumConstant> buildCEnumConstants(XSRestrictionSimpleType type, boolean needsToGenerateMemberName, Map<String, BIEnumMember> members, XSFacet[] errorRef) {
        List<CEnumConstant> memberList = new ArrayList<>();
        int idx=1;
        Set<String> enums = new HashSet<>(); // to avoid duplicates. See issue #366

        for( XSFacet facet : type.getDeclaredFacets(XSFacet.FACET_ENUMERATION)) {
            String name=null;
            String mdoc=builder.getBindInfo(facet).getDocumentation();

            if(!enums.add(facet.getValue().value))
                continue;   // ignore the 2nd occasion

            if( needsToGenerateMemberName ) {
                // generate names for all member names.
                // this will even override names specified by the user. that's crazy.
                name = "VALUE_"+(idx++);
            } else {
                String facetValue = facet.getValue().value;
                BIEnumMember mem = members.get(facetValue);
                if( mem==null )
                    // look at the one attached to the facet object
                    mem = builder.getBindInfo(facet).get(BIEnumMember.class);

                if (mem!=null) {
                    name = mem.name;
                    if (mdoc == null) {
                        mdoc = mem.javadoc;
                    }
                }

                if(name==null) {
                    StringBuilder sb = new StringBuilder();
                    for( int i=0; i<facetValue.length(); i++) {
                        char ch = facetValue.charAt(i);
                        if(Character.isJavaIdentifierPart(ch))
                            sb.append(ch);
                        else
                            sb.append('_');
                    }
                    name = model.getNameConverter().toConstantName(sb.toString());
                }
            }

            if(!JJavaName.isJavaIdentifier(name)) {
                if(errorRef!=null)  errorRef[0] = facet;
                return null;    // unable to generate a name
            }

            memberList.add(new CEnumConstant(name,mdoc,facet.getValue().value,facet,builder.getBindInfo(facet).toCustomizationList(),facet.getLocator()));
        }
        return memberList;
    }

    /**
     * Returns non-null if {@link CEnumConstant}s have name collisions among them.
     *
     * @return
     *      if there's a collision, return two {@link CEnumConstant}s that collided.
     *      otherwise return null.
     */
    private CEnumConstant[] checkMemberNameCollision( List<CEnumConstant> memberList ) {
        Map<String,CEnumConstant> names = new HashMap<>();
        for (CEnumConstant c : memberList) {
            CEnumConstant old = names.put(c.getName(),c);
            if(old!=null)
                // collision detected
                return new CEnumConstant[]{old,c};
        }
        return null;
    }



    private EnumMemberMode getEnumMemberMode() {
        return builder.getGlobalBinding().getEnumMemberMode();
    }

    private TypeUse lookupBuiltin( String typeLocalName ) {
        if(typeLocalName.equals("integer") || typeLocalName.equals("long")) {
            /*
                attempt an optimization so that we can
                improve the binding for types like this:

                <simpleType>
                  <restriciton baseType="integer">
                    <maxInclusive value="100" />
                  </
                </

                ... to int, not BigInteger.
            */

            BigInteger xe = readFacet(XSFacet.FACET_MAXEXCLUSIVE,-1);
            BigInteger xi = readFacet(XSFacet.FACET_MAXINCLUSIVE,0);
            BigInteger max = min(xe,xi);    // most restrictive one takes precedence

            if(max!=null) {
                BigInteger ne = readFacet(XSFacet.FACET_MINEXCLUSIVE,+1);
                BigInteger ni = readFacet(XSFacet.FACET_MININCLUSIVE,0);
                BigInteger min = max(ne,ni);

                if(min!=null) {
                    if(min.compareTo(INT_MIN )>=0 && max.compareTo(INT_MAX )<=0)
                        typeLocalName = "int";
                    else
                    if(min.compareTo(LONG_MIN)>=0 && max.compareTo(LONG_MAX)<=0)
                        typeLocalName = "long";
                }
            }
        } else
        if(typeLocalName.equals("boolean") && isRestrictedTo0And1()) {
            // this is seen in the SOAP schema and too common to ignore
            return CBuiltinLeafInfo.BOOLEAN_ZERO_OR_ONE;
        } else
        if(typeLocalName.equals("base64Binary")) {
            return lookupBinaryTypeBinding();
        } else
        if(typeLocalName.equals("anySimpleType")) {
            if(getReferer() instanceof XSAttributeDecl || getReferer() instanceof XSSimpleType)
                return CBuiltinLeafInfo.STRING;
            else
                return CBuiltinLeafInfo.ANYTYPE;
        }
        return builtinConversions.get(typeLocalName);
    }

    /**
     * Decides the way xs:base64Binary binds.
     *
     * This method checks the expected media type.
     */
    private TypeUse lookupBinaryTypeBinding() {
        XSComponent referer = getReferer();
        String emt = referer.getForeignAttribute(XML_MIME_URI, Const.EXPECTED_CONTENT_TYPES);
        if(emt!=null) {
            acknowledgedXmimeContentTypes.add(referer);
            try {
                // see http://www.xml.com/lpt/a/2004/07/21/dive.html
                List<MimeTypeRange> types = MimeTypeRange.parseRanges(emt);
                MimeTypeRange mt = MimeTypeRange.merge(types);

                // see spec table I-1 in appendix I section 2.1.1 for bindings
                if(mt.majorType.equalsIgnoreCase("image"))
                    return CBuiltinLeafInfo.IMAGE.makeMimeTyped(mt.toMimeType());

                if(( mt.majorType.equalsIgnoreCase("application") || mt.majorType.equalsIgnoreCase("text"))
                        && isXml(mt.subType))
                    return CBuiltinLeafInfo.XML_SOURCE.makeMimeTyped(mt.toMimeType());

                if((mt.majorType.equalsIgnoreCase("text") && (mt.subType.equalsIgnoreCase("plain")) )) {
                    return CBuiltinLeafInfo.STRING.makeMimeTyped(mt.toMimeType());
                }

                return CBuiltinLeafInfo.DATA_HANDLER.makeMimeTyped(mt.toMimeType());
            } catch (ParseException | MimeTypeParseException e) {
                getErrorReporter().error( referer.getLocator(),
                    Messages.format(Messages.ERR_ILLEGAL_EXPECTED_MIME_TYPE,emt, e.getMessage()) );
                // recover by using the default
            }
        }
        // default
        return CBuiltinLeafInfo.BASE64_BYTE_ARRAY;
    }

    public boolean isAcknowledgedXmimeContentTypes(XSComponent c) {
        return acknowledgedXmimeContentTypes.contains(c);
    }

    /**
     * Returns true if the specified sub-type is an XML type.
     */
    private boolean isXml(String subType) {
        return subType.equals("xml") || subType.endsWith("+xml");
    }

    /**
     * Returns true if the {@link #initiatingType} is restricted
     * to '0' and '1'. This logic is not complete, but it at least
     * finds the such definition in SOAP @mustUnderstand.
     */
    private boolean isRestrictedTo0And1() {
        XSFacet pattern = initiatingType.getFacet(XSFacet.FACET_PATTERN);
        if(pattern!=null) {
            String v = pattern.getValue().value;
            if(v.equals("0|1") || v.equals("1|0") || v.equals("\\d"))
                return true;
        }
        XSFacet enumf = initiatingType.getFacet(XSFacet.FACET_ENUMERATION);
        if(enumf!=null) {
            String v = enumf.getValue().value;
            return v.equals("0") || v.equals("1");
        }
        return false;
    }

    private BigInteger readFacet(String facetName,int offset) {
        XSFacet me = initiatingType.getFacet(facetName);
        if(me==null)
            return null;
        BigInteger bi = DatatypeConverter.parseInteger(me.getValue().value);
        if(offset!=0)
            bi = bi.add(BigInteger.valueOf(offset));
        return bi;
    }

    private BigInteger min(BigInteger a, BigInteger b) {
        if(a==null) return b;
        if(b==null) return a;
        return a.min(b);
    }

    private BigInteger max(BigInteger a, BigInteger b) {
        if(a==null) return b;
        if(b==null) return a;
        return a.max(b);
    }

    private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE);
    private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
    private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE);
    private static final BigInteger INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE);

    static {
        // list of datatypes which have built-in conversions.
        // note that although xs:token and xs:normalizedString are not
        // specified in the spec, they need to be here because they
        // have different whitespace normalization semantics.
        Map<String,TypeUse> m = new HashMap<>();

        // TODO: this is so dumb
        m.put("string",         CBuiltinLeafInfo.STRING);
        m.put("anyURI",         CBuiltinLeafInfo.STRING);
        m.put("boolean",        CBuiltinLeafInfo.BOOLEAN);
        // we'll also look at the expected media type, so don't just add this to the map
        // m.put("base64Binary",   CBuiltinLeafInfo.BASE64_BYTE_ARRAY);
        m.put("hexBinary",      CBuiltinLeafInfo.HEXBIN_BYTE_ARRAY);
        m.put("float",          CBuiltinLeafInfo.FLOAT);
        m.put("decimal",        CBuiltinLeafInfo.BIG_DECIMAL);
        m.put("integer",        CBuiltinLeafInfo.BIG_INTEGER);
        m.put("long",           CBuiltinLeafInfo.LONG);
        m.put("unsignedInt",    CBuiltinLeafInfo.LONG);
        m.put("int",            CBuiltinLeafInfo.INT);
        m.put("unsignedShort",  CBuiltinLeafInfo.INT);
        m.put("short",          CBuiltinLeafInfo.SHORT);
        m.put("unsignedByte",   CBuiltinLeafInfo.SHORT);
        m.put("byte",           CBuiltinLeafInfo.BYTE);
        m.put("double",         CBuiltinLeafInfo.DOUBLE);
        m.put("QName",          CBuiltinLeafInfo.QNAME);
        m.put("NOTATION",       CBuiltinLeafInfo.QNAME);
        m.put("dateTime",       CBuiltinLeafInfo.CALENDAR);
        m.put("date",           CBuiltinLeafInfo.CALENDAR);
        m.put("time",           CBuiltinLeafInfo.CALENDAR);
        m.put("gYearMonth",     CBuiltinLeafInfo.CALENDAR);
        m.put("gYear",          CBuiltinLeafInfo.CALENDAR);
        m.put("gMonthDay",      CBuiltinLeafInfo.CALENDAR);
        m.put("gDay",           CBuiltinLeafInfo.CALENDAR);
        m.put("gMonth",         CBuiltinLeafInfo.CALENDAR);
        m.put("duration",       CBuiltinLeafInfo.DURATION);
        m.put("token",          CBuiltinLeafInfo.TOKEN);
        m.put("normalizedString",CBuiltinLeafInfo.NORMALIZED_STRING);
        m.put("ID",             CBuiltinLeafInfo.ID);
        m.put("IDREF",          CBuiltinLeafInfo.IDREF);

        builtinConversions = Collections.unmodifiableMap(m);
        // TODO: handling dateTime, time, and date type
//        String[] names = {
//            "date", "dateTime", "time", "hexBinary" };
    }
}
