/*
* 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.XmlErrorContext;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.config.SchemaConfig;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaComponent;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaAttributeGroup;
import org.apache.xmlbeans.SchemaModelGroup;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlError;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.values.XmlStringImpl;
import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
import org.apache.xmlbeans.impl.util.HexBin;

import java.util.*;
import java.net.URISyntaxException;
import java.net.URI;
import java.io.File;


import javax.xml.namespace.QName;

import org.w3.x2001.xmlSchema.SchemaDocument;
import org.xml.sax.EntityResolver;

/**
 * This class represents the state of the SchemaTypeSystemCompiler as it's
 * going.
 */
public class StscState
{
    private String _givenStsName;
    private Collection _errorListener;
    private SchemaTypeSystemImpl _target;
    private SchemaConfig _config;
    private Map _compatMap;
    private boolean _doingDownloads;
    private byte[] _digest = null;
    private boolean _noDigest = false;

    private SchemaTypeLoader _importingLoader;

    private Map _redefinedGlobalTypes        = new LinkedHashMap();
    private Map _redefinedModelGroups        = new LinkedHashMap();
    private Map _redefinedAttributeGroups    = new LinkedHashMap();
        
    private Map _globalTypes        = new LinkedHashMap();
    private Map _globalElements     = new LinkedHashMap();
    private Map _globalAttributes   = new LinkedHashMap();
    private Map _modelGroups        = new LinkedHashMap();
    private Map _attributeGroups    = new LinkedHashMap();
    private Map _documentTypes      = new LinkedHashMap();
    private Map _attributeTypes     = new LinkedHashMap();
    private Map _typesByClassname   = new LinkedHashMap();
    private Map _misspelledNames    = new HashMap();
    private Set _processingGroups   = new HashSet();
    private Map _idConstraints      = new LinkedHashMap();
    private Set _namespaces         = new HashSet();
    private boolean _noUpa;
    private boolean _noPvr;
    private Set _mdefNamespaces     = buildDefaultMdefNamespaces();
    private EntityResolver _entityResolver;

    private static Set buildDefaultMdefNamespaces()
    {
        // namespaces which are known to appear in WSDLs redundantly
        return new HashSet(
                Arrays.asList( new String[] {
                    "http://www.openuri.org/2002/04/soap/conversation/",
                }));
    }

    /**
     * Used to store the new target namespace for a chameleon
     * included schema.
     */
    public static final Object CHAMELEON_INCLUDE_URI = new Object();

    /**
     * Only constructed via StscState.start().
     */
    private StscState()
    {
    }

    /**
     * Initializer for schematypepath
     */
    public void setImportingTypeLoader(SchemaTypeLoader loader)
    {
        _importingLoader = loader;
    }

    /**
     * Initializer for error handling.
     */
    public void setErrorListener(Collection errorListener)
        { _errorListener = errorListener; }

    /**
     * Passes an error on to the current XmlErrorContext.
     */
    public void error(String message, int code, XmlObject loc)
        { addError(_errorListener, message, code, loc); }

    /**
     * Passes a warning on to the current XmlErrorContext.
     */
    public void warning(String message, int code, XmlObject loc)
    {
        // it's OK for XMLSchema.xsd itself to have reserved type names
        if (code == XmlErrorContext.RESERVED_TYPE_NAME &&
                loc.documentProperties().getSourceName() != null &&
                loc.documentProperties().getSourceName().indexOf("XMLSchema.xsd") > 0)
            return;

        addWarning(_errorListener, message, code, loc);
    }

    /**
     * Passes a warning on to the current XmlErrorContext.
     */
    public void info(String message)
        { addInfo(_errorListener, message); }

    public static void addError(Collection errorListener, String message, int code, XmlObject location)
    {
        XmlError err =
            XmlError.forObject(
              message,
              XmlError.SEVERITY_ERROR,
              location);
        errorListener.add(err);
    }

    public static void addError(Collection errorListener, String message, int code, File location)
    {
        XmlError err =
            XmlError.forLocation(
              message,
              XmlError.SEVERITY_ERROR,
              location.toURI().toString(), 0, 0, 0);
        errorListener.add(err);
    }

    public static void addWarning(Collection errorListener, String message, int code, XmlObject location)
    {
        XmlError err =
            XmlError.forObject(
              message,
              XmlError.SEVERITY_WARNING,
              location);
        errorListener.add(err);
    }

    public static void addInfo(Collection errorListener, String message)
    {
        XmlError err = XmlError.forMessage(message, XmlError.SEVERITY_INFO);
        errorListener.add(err);
    }
    
    public void setGivenTypeSystemName(String name)
        { _givenStsName = name; }

    /**
     * Initializer for references to the SchemaTypeLoader
     */
    public void setTargetSchemaTypeSystem(SchemaTypeSystemImpl target)
        { _target = target; }
    
    /**
     * Accumulates a schema digest...
     */
    public void addSchemaDigest(byte[] digest)
    {
        if (_noDigest)
            return;
        
        if (digest == null)
        {
            _noDigest = true;
            _digest = null;
            return;
        }
        
        if (_digest == null)
            _digest = new byte[128/8]; // 128 bits.
        int len = _digest.length;
        if (digest.length < len)
            len = digest.length;
        for (int i = 0; i < len; i++)
            _digest[i] ^= digest[i];
    }
    
    /**
     * The SchemaTypeSystem which we're building types on behalf of.
     */
    public SchemaTypeSystemImpl sts()
    {
        if (_target != null)
            return _target;
        
        String name = _givenStsName;
        if (name == null && _digest != null)
            name = "s" + new String(HexBin.encode(_digest));
        
        _target = new SchemaTypeSystemImpl(name);
        return _target;
    }

    /**
     * True if the given URI is a local file
     */
    public boolean shouldDownloadURI(String uriString)
    {
        if (_doingDownloads)
            return true;

        if (uriString == null)
            return false;

        try
        {
            URI uri = new URI(uriString);
            return uri.getScheme().equalsIgnoreCase("file");
        }
        catch (Exception e)
        {
            return false;
        }
    }

    /**
     * Initializer for compatMap.
     */
    public void setOptions(XmlOptions options)
    {
        if (options == null)
        {
            return; // defaults are all false. 
        }
        
        _compatMap = (Map)options.get(XmlOptions.COMPILE_SUBSTITUTE_NAMES);
        _noUpa = options.hasOption(XmlOptions.COMPILE_NO_UPA_RULE) ? true :
                !"true".equals(System.getProperty("xmlbean.uniqueparticleattribution", "true"));
        _noPvr = options.hasOption(XmlOptions.COMPILE_NO_PVR_RULE) ? true :
                !"true".equals(System.getProperty("xmlbean.particlerestriction", "true"));
        _doingDownloads = options.hasOption(XmlOptions.COMPILE_DOWNLOAD_URLS) ? true :
                "true".equals(System.getProperty("xmlbean.downloadurls", "false"));
        _entityResolver = (EntityResolver)options.get(XmlOptions.ENTITY_RESOLVER);
        if (_entityResolver != null)
            _doingDownloads = true;
        
        if (options.hasOption(XmlOptions.COMPILE_MDEF_NAMESPACES))
            _mdefNamespaces.addAll((Collection)options.get(XmlOptions.COMPILE_MDEF_NAMESPACES));
    }
    
    /**
     * May return null if there is no custom entity resolver.
     */ 
    public EntityResolver getEntityResolver()
    {
        return _entityResolver;
    }
    
    /**
     * True if no unique particle attribution option is set
     */
    public boolean noUpa()
    {
        return _noUpa;
    }
    
    /**
     * True if no particle valid (restriciton) option is set
     */
    public boolean noPvr()
    {
        return _noPvr;
    }
    

    /**
     * Intercepts XML names and translates them
     * through the compat map, if any.
     *
     * Also looks for a default namespace for global definitions.
     */
    private QName compatName(QName name, String chameleonNamespace)
    {
        // first check for a chameleonNamespace namespace
        if (name.getNamespaceURI().length() == 0 && chameleonNamespace != null && chameleonNamespace.length() > 0)
            name = new QName(chameleonNamespace, name.getLocalPart());

        if (_compatMap == null)
            return name;

        QName subst = (QName)_compatMap.get(name);
        if (subst == null)
            return name;
        return subst;
    }

    /**
     * Initializer for the schema config object.
     */
    public void setSchemaConfig(SchemaConfig config)
        throws IllegalArgumentException
    {
        _config = config;
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getPackageOverride(String namespace)
    {
        return _config.lookupPackageForNamespace(namespace);
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getJavaPrefix(String namespace)
    {
        return _config.lookupPrefixForNamespace(namespace);
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getJavaSuffix(String namespace)
    {
        return _config.lookupSuffixForNamespace(namespace);
    }

    /**
     * Looks up configured java name for the given qname.
     */
    public String getJavaname(QName qname)
    {
        return _config.lookupJavanameForQName(qname);
    }

    /* SPELLINGS ======================================================*/

    private static String crunchName(QName name)
    {
        // lowercase, and drop namespace.
        return name.getLocalPart().toLowerCase();
    }

    void addSpelling(QName name, SchemaComponent comp)
    {
        _misspelledNames.put(crunchName(name), comp);
    }

    SchemaComponent findSpelling(QName name)
    {
        return (SchemaComponent)_misspelledNames.get(crunchName(name));
    }

    /* NAMESPACES ======================================================*/

    void addNamespace(String targetNamespace)
    {
        _namespaces.add(targetNamespace);
    }

    String[] getNamespaces()
    {
        return (String[])_namespaces.toArray(new String[_namespaces.size()]);
    }

    boolean linkerDefinesNamespace(String namespace)
    {
        return _importingLoader.isNamespaceDefined(namespace);
    }

    /* TYPES ==========================================================*/

    SchemaTypeImpl findGlobalType(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl)_globalTypes.get(name);
        if (result == null)
            result = (SchemaTypeImpl)_importingLoader.findType(name);
        return result;
    }
    
    SchemaTypeImpl findRedefinedGlobalType(QName name, String chameleonNamespace, QName redefinedName)
    {
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinedName))
        {
            return (SchemaTypeImpl)_redefinedGlobalTypes.get(name);
            // BUGBUG: should also link against _importingLoader.findRedefinedType
        }
        SchemaTypeImpl result = (SchemaTypeImpl)_globalTypes.get(name);
        if (result == null)
            result = (SchemaTypeImpl)_importingLoader.findType(name);
        return result;
    }

    void addGlobalType(SchemaTypeImpl type, boolean redefined)
    {
        if (type != null)
        {
            QName name = type.getName();
            
            if (redefined)
            {
                if (_redefinedGlobalTypes.containsKey(name))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate global type: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                    _redefinedGlobalTypes.put(name, type);
            }
            else
            {
                if (_globalTypes.containsKey(name))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate global type: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                {
                    _globalTypes.put(name, type);
                    addSpelling(name, type);
                }
            }
        }
    }

    private boolean ignoreMdef(QName name)
    {
        return _mdefNamespaces.contains(name.getNamespaceURI());
    }

    SchemaType[] globalTypes()
        { return (SchemaType[])_globalTypes.values().toArray(new SchemaType[_globalTypes.size()]); }

    SchemaType[] redefinedGlobalTypes()
        { return (SchemaType[])_redefinedGlobalTypes.values().toArray(new SchemaType[_redefinedGlobalTypes.size()]); }
    
    /* DOCUMENT TYPES =================================================*/

    SchemaTypeImpl findDocumentType(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl)_documentTypes.get(name);
        if (result == null)
            result = (SchemaTypeImpl)_importingLoader.findDocumentType(name);
        return result;
    }

    void addDocumentType(SchemaTypeImpl type, QName name)
    {
        if (_documentTypes.containsKey(name))
        {
            if (!ignoreMdef(name))
                error("Duplicate global element: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_ELEMENT, null);
        }
        else
            _documentTypes.put(name, type);
    }

    SchemaType[] documentTypes()
        { return (SchemaType[])_documentTypes.values().toArray(new SchemaType[_documentTypes.size()]); }

    /* ATTRIBUTE TYPES =================================================*/

    SchemaTypeImpl findAttributeType(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl)_attributeTypes.get(name);
        if (result == null)
            result = (SchemaTypeImpl)_importingLoader.findAttributeType(name);
        return result;
    }

    void addAttributeType(SchemaTypeImpl type, QName name)
    {
        if (_attributeTypes.containsKey(name))
        {
            if (!ignoreMdef(name))
                error("Duplicate global attribute: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_ATTRIBUTE, null);
        }
        else
            _attributeTypes.put(name, type);
    }

    SchemaType[] attributeTypes()
        { return (SchemaType[])_attributeTypes.values().toArray(new SchemaType[_attributeTypes.size()]); }

    /* ATTRIBUTES =====================================================*/

    SchemaGlobalAttributeImpl findGlobalAttribute(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaGlobalAttributeImpl result = (SchemaGlobalAttributeImpl)_globalAttributes.get(name);
        if (result == null)
            result = (SchemaGlobalAttributeImpl)_importingLoader.findAttribute(name);
        return result;
    }

    void addGlobalAttribute(SchemaGlobalAttributeImpl attribute)
    {
        if (attribute != null)
        {
            QName name = attribute.getName();
            _globalAttributes.put(name, attribute);
            addSpelling(name, attribute);
        }
    }

    SchemaGlobalAttribute[] globalAttributes()
        { return (SchemaGlobalAttribute[])_globalAttributes.values().toArray(new SchemaGlobalAttribute[_globalAttributes.size()]); }

    /* ELEMENTS =======================================================*/

    SchemaGlobalElementImpl findGlobalElement(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaGlobalElementImpl result = (SchemaGlobalElementImpl)_globalElements.get(name);
        if (result == null)
            result = (SchemaGlobalElementImpl)_importingLoader.findElement(name);
        return result;
    }

    void addGlobalElement(SchemaGlobalElementImpl element)
    {
        if (element != null)
        {
            QName name = element.getName();
            _globalElements.put(name, element);
            addSpelling(name, element);
        }
    }

    SchemaGlobalElement[] globalElements()
        { return (SchemaGlobalElement[])_globalElements.values().toArray(new SchemaGlobalElement[_globalElements.size()]); }

    /* ATTRIBUTE GROUPS ===============================================*/

    SchemaAttributeGroupImpl findAttributeGroup(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl)_attributeGroups.get(name);
        if (result == null)
            result = (SchemaAttributeGroupImpl)_importingLoader.findAttributeGroup(name);
        return result;
    }

    SchemaAttributeGroupImpl findRedefinedAttributeGroup(QName name, String chameleonNamespace, QName redefinitionFor)
    {
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinitionFor))
        {
            return (SchemaAttributeGroupImpl)_redefinedAttributeGroups.get(name);
            // BUGBUG: should also link against _importingLoader.findRedefinedAttributeGroup
        }
        SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl)_attributeGroups.get(name);
        if (result == null)
            result = (SchemaAttributeGroupImpl)_importingLoader.findAttributeGroup(name);
        return result;
    }

    void addAttributeGroup(SchemaAttributeGroupImpl attributeGroup, boolean redefined)
    {
        if (attributeGroup != null)
        {
            QName name = attributeGroup.getName();
            if (redefined)
            {
                if (_redefinedAttributeGroups.containsKey(name))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate attribute group: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                    _redefinedAttributeGroups.put(name, attributeGroup);
                
            }
            else
            {
                if (_attributeGroups.containsKey( name ))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate attribute group: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                {
                    _attributeGroups.put(attributeGroup.getName(), attributeGroup);
                    addSpelling(attributeGroup.getName(), attributeGroup);
                }
            }
        }
    }

    SchemaAttributeGroup[] attributeGroups()
        { return (SchemaAttributeGroup[])_attributeGroups.values().toArray(new SchemaAttributeGroup[_attributeGroups.size()]); }

    SchemaAttributeGroup[] redefinedAttributeGroups()
        { return (SchemaAttributeGroup[])_redefinedAttributeGroups.values().toArray(new SchemaAttributeGroup[_redefinedAttributeGroups.size()]); }

    /* MODEL GROUPS ===================================================*/

    SchemaModelGroupImpl findModelGroup(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        SchemaModelGroupImpl result = (SchemaModelGroupImpl)_modelGroups.get(name);
        if (result == null)
            result = (SchemaModelGroupImpl)_importingLoader.findModelGroup(name);
        return result;
    }

    SchemaModelGroupImpl findRedefinedModelGroup(QName name, String chameleonNamespace, QName redefinitionFor)
    {
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinitionFor))
        {
            return (SchemaModelGroupImpl)_redefinedModelGroups.get(name);
            // BUGBUG: should also link against _importingLoader.findRedefinedModelGroup
        }
        SchemaModelGroupImpl result = (SchemaModelGroupImpl)_modelGroups.get(name);
        if (result == null)
            result = (SchemaModelGroupImpl)_importingLoader.findModelGroup(name);
        return result;
    }

    void addModelGroup(SchemaModelGroupImpl modelGroup, boolean redefined)
    {
        if (modelGroup != null)
        {
            QName name = modelGroup.getName();
            if (redefined)
            {
                if (_redefinedModelGroups.containsKey(name))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate model group: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                    _redefinedModelGroups.put(name, modelGroup);
            }
            else
            {
                if (_modelGroups.containsKey(name))
                {
                    if (!ignoreMdef(name))
                        error("Duplicate model group: " + QNameHelper.pretty(name), XmlErrorContext.DUPLICATE_GLOBAL_TYPE, null);
                }
                else
                {
                    _modelGroups.put(modelGroup.getName(), modelGroup);
                    addSpelling(modelGroup.getName(), modelGroup);
                }
            }
        }
    }

    SchemaModelGroup[] modelGroups()
        { return (SchemaModelGroup[])_modelGroups.values().toArray(new SchemaModelGroup[_modelGroups.size()]); }
    
    SchemaModelGroup[] redefinedModelGroups()
        { return (SchemaModelGroup[])_redefinedModelGroups.values().toArray(new SchemaModelGroup[_redefinedModelGroups.size()]); }

    /* IDENTITY CONSTRAINTS ===========================================*/

    SchemaIdentityConstraintImpl findIdConstraint(QName name, String chameleonNamespace)
    {
        name = compatName(name, chameleonNamespace);
        return (SchemaIdentityConstraintImpl)_idConstraints.get(name);
    }

    void addIdConstraint(SchemaIdentityConstraintImpl idc)
    {
        if (idc != null)
        {
            _idConstraints.put(idc.getName(), idc);
            addSpelling(idc.getName(), idc);
        }
    }

    SchemaIdentityConstraintImpl[] idConstraints()
        { return (SchemaIdentityConstraintImpl[])_idConstraints.values().toArray(new SchemaIdentityConstraintImpl[_idConstraints.size()]); }

    /* RECURSION AVOIDANCE ============================================*/
    boolean isProcessing(Object obj)
    {
        return _processingGroups.contains(obj);
    }

    void startProcessing(Object obj)
    {
        assert(!_processingGroups.contains(obj));
        _processingGroups.add(obj);
    }

    void finishProcessing(Object obj)
    {
        assert(_processingGroups.contains(obj));
        _processingGroups.remove(obj);
    }

    /* JAVAIZATION ====================================================*/

    Map typesByClassname()
        { return Collections.unmodifiableMap(_typesByClassname); }

    void addClassname(String classname, SchemaType type)
        { _typesByClassname.put(classname, type); }



    /**
     * Stack management if (heaven help us) we ever need to do
     * nested compilation of schema type system.
     */
    private static final class StscStack
    {
        StscState current;
        ArrayList stack = new ArrayList();
        final StscState push()
        {
            stack.add(current);
            current = new StscState();
            return current;
        }
        final void pop()
        {
            current = (StscState)stack.get(stack.size() - 1);
            stack.remove(stack.size() - 1);
        }
    }

    private static ThreadLocal stscStack = new ThreadLocal()
    {
        protected Object initialValue() { return new StscStack(); }
    };

    public static StscState start()
    {
        return ((StscStack)stscStack.get()).push();
    }

    public static StscState get()
    {
        return ((StscStack)stscStack.get()).current;
    }

    public static void end()
    {
        ((StscStack)stscStack.get()).pop();
    }

    private final static XmlValueRef XMLSTR_PRESERVE = buildString("preserve");
    private final static XmlValueRef XMLSTR_REPLACE = buildString("preserve");
    private final static XmlValueRef XMLSTR_COLLAPSE = buildString("preserve");

    static final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];
    static final SchemaType.Ref[] EMPTY_STREF_ARRAY = new SchemaType.Ref[0];

    private final static XmlValueRef[] FACETS_NONE = new XmlValueRef[]
        { null, null, null, null, null, null, null, null, null,
          null, null, null };

    private final static boolean[] FIXED_FACETS_NONE = new boolean[]
        { false, false, false, false, false, false, false, false, false,
          false, false, false };

    private final static XmlValueRef[] FACETS_WS_COLLAPSE = new XmlValueRef[]
        { null, null, null, null, null, null, null, null, null,
          build_wsstring(SchemaType.WS_COLLAPSE), null, null };

    private final static boolean[] FIXED_FACETS_WS = new boolean[]
        { false, false, false, false, false, false, false, false, false,
          true, false, false };

    final static XmlValueRef[] FACETS_UNION = FACETS_NONE;
    final static boolean[] FIXED_FACETS_UNION = FIXED_FACETS_NONE;
    final static XmlValueRef[] FACETS_LIST = FACETS_WS_COLLAPSE;
    final static boolean[] FIXED_FACETS_LIST = FIXED_FACETS_WS;

    static XmlValueRef build_wsstring(int wsr)
    {
        switch (wsr)
        {
            case SchemaType.WS_PRESERVE:
                return XMLSTR_PRESERVE;
            case SchemaType.WS_REPLACE:
                return XMLSTR_REPLACE;
            case SchemaType.WS_COLLAPSE:
                return XMLSTR_COLLAPSE;
        }
        return null;
    }

    static XmlValueRef buildString(String str)
    {
        if (str == null)
            return null;

        try
        {
            XmlStringImpl i = new XmlStringImpl();
            i.set(str);
            i.setImmutable();
            return new XmlValueRef(i);
        }
        catch (XmlValueOutOfRangeException e)
        {
            return null;
        }
    }

    public void notFoundError(QName itemName, int code, XmlObject loc)
    {
        String basicMessage;

        switch (code)
        {
            case XmlErrorContext.TYPE_NOT_FOUND:
                basicMessage = "Type " + QNameHelper.pretty(itemName) + " not found.";
                break;
            case XmlErrorContext.ELEMENT_REF_NOT_FOUND:
                basicMessage = "Element " + QNameHelper.pretty(itemName) + " not found.";
                break;
            case XmlErrorContext.ATTRIBUTE_REF_NOT_FOUND:
                basicMessage = "Attribute " + QNameHelper.pretty(itemName) + " not found.";
                break;
            case XmlErrorContext.MODEL_GROUP_NOT_FOUND:
                basicMessage = "Model group " + QNameHelper.pretty(itemName) + " not found.";
                break;
            case XmlErrorContext.ATTRIBUTE_GROUP_NOT_FOUND:
                basicMessage = "Attribute group " + QNameHelper.pretty(itemName) + " not found.";
                break;
            case XmlErrorContext.IDC_NOT_FOUND:
                basicMessage = "Identity constraint '" + QNameHelper.pretty(itemName) + "' not found.";
                break;
            default:
                assert(false);
                basicMessage = "Definition " + QNameHelper.pretty(itemName) + " not found.";
                break;
        }

        String helpfulMessage = "";
        SchemaComponent foundComponent = findSpelling(itemName);
        QName name;
        if (foundComponent != null)
        {
            name = foundComponent.getName();
            if (name != null)
            {
                String sourceName = null;
                switch (foundComponent.getComponentType())
                {
                    case SchemaComponent.TYPE:
                        sourceName = ((SchemaType)foundComponent).getSourceName();
                        break;
                    case SchemaComponent.ELEMENT:
                        sourceName = ((SchemaGlobalElement)foundComponent).getSourceName();
                        break;
                    case SchemaComponent.ATTRIBUTE:
                        sourceName = ((SchemaGlobalAttribute)foundComponent).getSourceName();
                        break;
                }
                String source = "";
                if (sourceName != null)
                {
                    source = " (in " +  sourceName.substring(sourceName.lastIndexOf('/') + 1) + ")";
                }
                
                if (name.equals(itemName))
                {
                    switch (foundComponent.getComponentType())
                    {
                        case SchemaComponent.TYPE:
                            helpfulMessage = "  Do you mean to refer to the type with that name" + source + "?";
                            break;
                        case SchemaComponent.ELEMENT:
                            helpfulMessage = "  Do you mean to refer to the element with that name" + source + "?";
                            break;
                        case SchemaComponent.ATTRIBUTE:
                            helpfulMessage = "  Do you mean to refer to the attribute with that name" + source + "?";
                            break;
                        case SchemaComponent.ATTRIBUTE_GROUP:
                            helpfulMessage = "  Do you mean to refer to the attribute group with that name" + source + "?";
                            break;
                        case SchemaComponent.MODEL_GROUP:
                            helpfulMessage = "  Do you mean to refer to the model group with that name" + source + "?";
                            break;
                    }
                }
                else
                {
                    switch (foundComponent.getComponentType())
                    {
                        case SchemaComponent.TYPE:
                            helpfulMessage = "  Do you mean to refer to the type named " + QNameHelper.pretty(name) + source + "?";
                            break;
                        case SchemaComponent.ELEMENT:
                            helpfulMessage = "  Do you mean to refer to the element named " + QNameHelper.pretty(name) + source + "?";
                            break;
                        case SchemaComponent.ATTRIBUTE:
                            helpfulMessage = "  Do you mean to refer to the attribute named " + QNameHelper.pretty(name) + source + "?";
                            break;
                        case SchemaComponent.ATTRIBUTE_GROUP:
                            helpfulMessage = "  Do you mean to refer to the attribute group named " + QNameHelper.pretty(name) + source + "?";
                            break;
                        case SchemaComponent.MODEL_GROUP:
                            helpfulMessage = "  Do you mean to refer to the model group named " + QNameHelper.pretty(name) + source + "?";
                            break;
                    }
                }
            }
        }

        error(basicMessage + helpfulMessage, code, loc);
    }

    /**
     * Produces the "sourceName" (to be used within the schema project
     * source file copies) from the URI of the original source.
     *
     * Returns null if none.
     */
    public String sourceNameForUri(String uri)
    {
        return (String)_sourceForUri.get(uri);
    }

    /**
     * Returns the whole sourceCopyMap, mapping URI's that have
     * been read to "sourceName" local names that have been used
     * to tag the types.
     */
    public Map sourceCopyMap()
    {
        return Collections.unmodifiableMap(_sourceForUri);
    }

    /**
     * The base URI to use for nice filenames when saving sources.
     */
    public void setBaseUri(URI uri)
    {
        _baseURI = uri;
    }

    private final static String PROJECT_URL_PREFIX = "project://local";
    
    public String relativize(String uri)
    {
        return relativize(uri, false);
    }
    
    public String computeSavedFilename(String uri)
    {
        return relativize(uri, true);
    }
    
    private String relativize(String uri, boolean forSavedFilename)
    {
        if (uri == null)
            return null;

        // deal with things that do not look like absolute uris
        if (uri.startsWith("/"))
        {
            uri = PROJECT_URL_PREFIX + uri.replace('\\', '/');
        }
        else
        {
            // looks like a URL?
            int colon = uri.indexOf(':');
            if (colon <= 1 || !uri.substring(0, colon).matches("^\\w+$"))
                uri = PROJECT_URL_PREFIX + "/" + uri.replace('\\', '/');
        }

        // now relativize against that...
        if (_baseURI != null)
        {
            try
            {
                URI relative = _baseURI.relativize(new URI(uri));
                if (!relative.isAbsolute())
                    return relative.toString();
                else
                    uri = relative.toString();
            }
            catch (URISyntaxException e)
            {
            }
        }
        
        if (!forSavedFilename)
            return uri;

        int lastslash = uri.lastIndexOf('/');
        String dir = QNameHelper.hexsafe(lastslash == -1 ? "" : uri.substring(0, lastslash));
        return dir + "/" + uri.substring(lastslash + 1);
    }

    /**
     * Notes another URI that has been consumed during compilation
     * (this is the URI that is in the document .NAME property)
     */
    public void addSourceUri(String uri, String nameToUse)
    {
        if (uri == null)
            return;

        if (nameToUse == null)
            nameToUse = computeSavedFilename(uri);

        _sourceForUri.put(uri, nameToUse);
    }

    /**
     * Returns the error listener being filled in during this compilation
     */
    public Collection getErrorListener()
    {
        return _errorListener;
    }

    /**
     * Returns the schema type loader to use for processing s4s
     */
    public SchemaTypeLoader getS4SLoader()
    {
        return _s4sloader;
    }

    Map _sourceForUri = new HashMap();
    URI _baseURI = URI.create(PROJECT_URL_PREFIX + "/");
    SchemaTypeLoader _s4sloader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader());
}
