/*
**********************************************************************
*   Copyright (c) 2001-2009, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   08/19/2001  aliu        Creation.
**********************************************************************
*/

package com.ibm.icu.text;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;

import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.RuleBasedTransliterator.Data;
import com.ibm.icu.util.CaseInsensitiveString;
import com.ibm.icu.util.UResourceBundle;

class TransliteratorRegistry {

    // char constants
    private static final char LOCALE_SEP  = '_';

    // String constants
    private static final String NO_VARIANT = ""; // empty string
    private static final String ANY = "Any";

    /**
     * Dynamic registry mapping full IDs to Entry objects.  This
     * contains both public and internal entities.  The visibility is
     * controlled by whether an entry is listed in availableIDs and
     * specDAG or not.
     *
     * Keys are CaseInsensitiveString objects.
     * Values are objects of class Class (subclass of Transliterator),
     * RuleBasedTransliterator.Data, Transliterator.Factory, or one
     * of the entry classes defined here (AliasEntry or ResourceEntry).
     */
    private Hashtable<CaseInsensitiveString, Object[]> registry;

    /**
     * DAG of visible IDs by spec.  Hashtable: source => (Hashtable:
     * target => (Vector: variant)) The Vector of variants is never
     * empty.  For a source-target with no variant, the special
     * variant NO_VARIANT (the empty string) is stored in slot zero of
     * the UVector.
     *
     * Keys are CaseInsensitiveString objects.
     * Values are Hashtable of (CaseInsensitiveString -> Vector of
     * CaseInsensitiveString)
     */
    private Hashtable<CaseInsensitiveString, Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>>> specDAG;

    /**
     * Vector of public full IDs (CaseInsensitiveString objects).
     */
    private Vector<CaseInsensitiveString> availableIDs;

    //----------------------------------------------------------------------
    // class Spec
    //----------------------------------------------------------------------

    /**
     * A Spec is a string specifying either a source or a target.  In more
     * general terms, it may also specify a variant, but we only use the
     * Spec class for sources and targets.
     *
     * A Spec may be a locale or a script.  If it is a locale, it has a
     * fallback chain that goes xx_YY_ZZZ -> xx_YY -> xx -> ssss, where
     * ssss is the script mapping of xx_YY_ZZZ.  The Spec API methods
     * hasFallback(), next(), and reset() iterate over this fallback
     * sequence.
     *
     * The Spec class canonicalizes itself, so the locale is put into
     * canonical form, or the script is transformed from an abbreviation
     * to a full name.
     */
    static class Spec {

        private String top;        // top spec
        private String spec;       // current spec
        private String nextSpec;   // next spec
        private String scriptName; // script name equivalent of top, if != top
        private boolean isSpecLocale; // TRUE if spec is a locale
        private boolean isNextLocale; // TRUE if nextSpec is a locale
        private ICUResourceBundle res;

        public Spec(String theSpec) {
            top = theSpec;
            spec = null;
            scriptName = null;
            try{
                // Canonicalize script name.  If top is a script name then
                // script != UScript.INVALID_CODE.
                int script = UScript.getCodeFromName(top);

                // Canonicalize script name -or- do locale->script mapping
                int[] s = UScript.getCode(top);
                if (s != null) {
                    scriptName = UScript.getName(s[0]);
                    // If the script name is the same as top then it's redundant
                    if (scriptName.equalsIgnoreCase(top)) {
                        scriptName = null;
                    }
                }

                isSpecLocale = false;
                res = null;
                // If 'top' is not a script name, try a locale lookup
                if (script == UScript.INVALID_CODE) {
                    Locale toploc = LocaleUtility.getLocaleFromName(top);
                    res  = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_TRANSLIT_BASE_NAME,toploc);
                    // Make sure we got the bundle we wanted; otherwise, don't use it
                    if (res!=null && LocaleUtility.isFallbackOf(res.getULocale().toString(), top)) {
                        isSpecLocale = true;
                    }
                }
            }catch(MissingResourceException e){
                ///CLOVER:OFF
                // The constructor is called from multiple private methods
                //  that protects an invalid scriptName
                scriptName = null;
                ///CLOVER:ON
            }
            // assert(spec != top);
            reset();
        }

        public boolean hasFallback() {
            return nextSpec != null;
        }

        public void reset() {
            if (spec != top) { // [sic] pointer comparison
                spec = top;
                isSpecLocale = (res != null);
                setupNext();
            }
        }

        private void setupNext() {
            isNextLocale = false;
            if (isSpecLocale) {
                nextSpec = spec;
                int i = nextSpec.lastIndexOf(LOCALE_SEP);
                // If i == 0 then we have _FOO, so we fall through
                // to the scriptName.
                if (i > 0) {
                    nextSpec = spec.substring(0, i);
                    isNextLocale = true;
                } else {
                    nextSpec = scriptName; // scriptName may be null
                }
            } else {
                // Fallback to the script, which may be null
                if (nextSpec != scriptName) {
                    nextSpec = scriptName;
                } else {
                    nextSpec = null;
                }
            }
        }

        // Protocol:
        // for(String& s(spec.get());
        //     spec.hasFallback(); s(spec.next())) { ...

        public String next() {
            spec = nextSpec;
            isSpecLocale = isNextLocale;
            setupNext();
            return spec;
        }

        public String get() {
            return spec;
        }

        public boolean isLocale() {
            return isSpecLocale;
        }

        /**
         * Return the ResourceBundle for this spec, at the current
         * level of iteration.  The level of iteration goes from
         * aa_BB_CCC to aa_BB to aa.  If the bundle does not
         * correspond to the current level of iteration, return null.
         * If isLocale() is false, always return null.
         */
        public ResourceBundle getBundle() {
            if (res != null &&
                res.getULocale().toString().equals(spec)) {
                return res;
            }
            return null;
        }

        public String getTop() {
            return top;
        }
    }

    //----------------------------------------------------------------------
    // Entry classes
    //----------------------------------------------------------------------

    static class ResourceEntry {
        public String resource;
        public String encoding;
        public int direction;
        public ResourceEntry(String n, String enc, int d) {
            resource = n;
            encoding = enc;
            direction = d;
        }
    }

    // An entry representing a rule in a locale resource bundle
    static class LocaleEntry {
        public String rule;
        public int direction;
        public LocaleEntry(String r, int d) {
            rule = r;
            direction = d;
        }
    }

    static class AliasEntry {
        public String alias;
        public AliasEntry(String a) {
            alias = a;
        }
    }

    static class CompoundRBTEntry {
        private String ID;
        private Vector<String> idBlockVector;
        private Vector<Data> dataVector;
        private UnicodeSet compoundFilter;

        public CompoundRBTEntry(String theID, Vector<String> theIDBlockVector,
                                Vector<Data> theDataVector,
                                UnicodeSet theCompoundFilter) {
            ID = theID;
            idBlockVector = theIDBlockVector;
            dataVector = theDataVector;
            compoundFilter = theCompoundFilter;
        }

        public Transliterator getInstance() {
            Vector<Transliterator> transliterators = new Vector<Transliterator>();
            int passNumber = 1;

            int limit = Math.max(idBlockVector.size(), dataVector.size());
            for (int i = 0; i < limit; i++) {
                if (i < idBlockVector.size()) {
                    String idBlock = idBlockVector.get(i);
                    if (idBlock.length() > 0)
                        transliterators.add(Transliterator.getInstance(idBlock));
                }
                if (i < dataVector.size()) {
                    Data data = dataVector.get(i);
                    transliterators.add(new RuleBasedTransliterator("%Pass" + passNumber++, data, null));
                }
            }

            Transliterator t = new CompoundTransliterator(transliterators, passNumber - 1);
            t.setID(ID);
            if (compoundFilter != null) {
                t.setFilter(compoundFilter);
            }
            return t;
        }
    }

    //----------------------------------------------------------------------
    // class TransliteratorRegistry: Basic public API
    //----------------------------------------------------------------------

    public TransliteratorRegistry() {
        registry = new Hashtable<CaseInsensitiveString, Object[]>();
        specDAG = new Hashtable<CaseInsensitiveString, Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>>>();
        availableIDs = new Vector<CaseInsensitiveString>();
    }

    /**
     * Given a simple ID (forward direction, no inline filter, not
     * compound) attempt to instantiate it from the registry.  Return
     * 0 on failure.
     *
     * Return a non-empty aliasReturn value if the ID points to an alias.
     * We cannot instantiate it ourselves because the alias may contain
     * filters or compounds, which we do not understand.  Caller should
     * make aliasReturn empty before calling.
     */
    public Transliterator get(String ID,
                              StringBuffer aliasReturn) {
        Object[] entry = find(ID);
        return (entry == null) ? null
            : instantiateEntry(ID, entry, aliasReturn);
    }

    /**
     * Register a class.  This adds an entry to the
     * dynamic store, or replaces an existing entry.  Any entry in the
     * underlying static locale resource store is masked.
     */
    public void put(String ID,
                    Class<? extends Transliterator> transliteratorSubclass,
                    boolean visible) {
        registerEntry(ID, transliteratorSubclass, visible);
    }

    /**
     * Register an ID and a factory function pointer.  This adds an
     * entry to the dynamic store, or replaces an existing entry.  Any
     * entry in the underlying static locale resource store is masked.
     */
    public void put(String ID,
                    Transliterator.Factory factory,
                    boolean visible) {
        registerEntry(ID, factory, visible);
    }

    /**
     * Register an ID and a resource name.  This adds an entry to the
     * dynamic store, or replaces an existing entry.  Any entry in the
     * underlying static locale resource store is masked.
     */
    public void put(String ID,
                    String resourceName,
                    String encoding,
                    int dir,
                    boolean visible) {
        registerEntry(ID, new ResourceEntry(resourceName, encoding, dir), visible);
    }

    /**
     * Register an ID and an alias ID.  This adds an entry to the
     * dynamic store, or replaces an existing entry.  Any entry in the
     * underlying static locale resource store is masked.
     */
    public void put(String ID,
                    String alias,
                    boolean visible) {
        registerEntry(ID, new AliasEntry(alias), visible);
    }

    /**
     * Register an ID and a Transliterator object.  This adds an entry
     * to the dynamic store, or replaces an existing entry.  Any entry
     * in the underlying static locale resource store is masked.
     */
    public void put(String ID,
                    Transliterator trans,
                    boolean visible) {
        registerEntry(ID, trans, visible);
    }

    /**
     * Unregister an ID.  This removes an entry from the dynamic store
     * if there is one.  The static locale resource store is
     * unaffected.
     */
    public void remove(String ID) {
        String[] stv = TransliteratorIDParser.IDtoSTV(ID);
        // Only need to do this if ID.indexOf('-') < 0
        String id = TransliteratorIDParser.STVtoID(stv[0], stv[1], stv[2]);
        registry.remove(new CaseInsensitiveString(id));
        removeSTV(stv[0], stv[1], stv[2]);
        availableIDs.removeElement(new CaseInsensitiveString(id));
    }

    //----------------------------------------------------------------------
    // class TransliteratorRegistry: Public ID and spec management
    //----------------------------------------------------------------------

    /**
     * An internal class that adapts an enumeration over
     * CaseInsensitiveStrings to an enumeration over Strings.
     */
    private static class IDEnumeration implements Enumeration<String> {
        Enumeration<CaseInsensitiveString> en;

        public IDEnumeration(Enumeration<CaseInsensitiveString> e) {
            en = e;
        }

        public boolean hasMoreElements() {
            return en != null && en.hasMoreElements();
        }

        public String nextElement() {
            return (en.nextElement()).getString();
        }
    }

    /**
     * Returns an enumeration over the programmatic names of visible
     * registered transliterators.
     *
     * @return An <code>Enumeration</code> over <code>String</code> objects
     */
    public Enumeration<String> getAvailableIDs() {
        // Since the cache contains CaseInsensitiveString objects, but
        // the caller expects Strings, we have to use an intermediary.
        return new IDEnumeration(availableIDs.elements());
    }

    /**
     * Returns an enumeration over all visible source names.
     *
     * @return An <code>Enumeration</code> over <code>String</code> objects
     */
    public Enumeration<String> getAvailableSources() {
        return new IDEnumeration(specDAG.keys());
    }

    /**
     * Returns an enumeration over visible target names for the given
     * source.
     *
     * @return An <code>Enumeration</code> over <code>String</code> objects
     */
    public Enumeration<String> getAvailableTargets(String source) {
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>> targets = specDAG.get(cisrc);
        if (targets == null) {
            return new IDEnumeration(null);
        }
        return new IDEnumeration(targets.keys());
    }

    /**
     * Returns an enumeration over visible variant names for the given
     * source and target.
     *
     * @return An <code>Enumeration</code> over <code>String</code> objects
     */
    public Enumeration<String> getAvailableVariants(String source, String target) {
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        CaseInsensitiveString citrg = new CaseInsensitiveString(target);
        Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>> targets = specDAG.get(cisrc);
        if (targets == null) {
            return new IDEnumeration(null);
        }
        Vector<CaseInsensitiveString> variants = targets.get(citrg);
        if (variants == null) {
            return new IDEnumeration(null);
        }
        return new IDEnumeration(variants.elements());
    }

    //----------------------------------------------------------------------
    // class TransliteratorRegistry: internal
    //----------------------------------------------------------------------

    /**
     * Convenience method.  Calls 6-arg registerEntry().
     */
    private void registerEntry(String source,
                               String target,
                               String variant,
                               Object entry,
                               boolean visible) {
        String s = source;
        if (s.length() == 0) {
            s = ANY;
        }
        String ID = TransliteratorIDParser.STVtoID(source, target, variant);
        registerEntry(ID, s, target, variant, entry, visible);
    }

    /**
     * Convenience method.  Calls 6-arg registerEntry().
     */
    private void registerEntry(String ID,
                               Object entry,
                               boolean visible) {
        String[] stv = TransliteratorIDParser.IDtoSTV(ID);
        // Only need to do this if ID.indexOf('-') < 0
        String id = TransliteratorIDParser.STVtoID(stv[0], stv[1], stv[2]);
        registerEntry(id, stv[0], stv[1], stv[2], entry, visible);
    }

    /**
     * Register an entry object (adopted) with the given ID, source,
     * target, and variant strings.
     */
    private void registerEntry(String ID,
                               String source,
                               String target,
                               String variant,
                               Object entry,
                               boolean visible) {
        CaseInsensitiveString ciID = new CaseInsensitiveString(ID);
        Object[] arrayOfObj;

        // Store the entry within an array so it can be modified later
        if (entry instanceof Object[]) {
            arrayOfObj = (Object[])entry;
        } else {
            arrayOfObj = new Object[] { entry };
        }

        registry.put(ciID, arrayOfObj);
        if (visible) {
            registerSTV(source, target, variant);
            if (!availableIDs.contains(ciID)) {
                availableIDs.addElement(ciID);
            }
        } else {
            removeSTV(source, target, variant);
            availableIDs.removeElement(ciID);
        }
    }

    /**
     * Register a source-target/variant in the specDAG.  Variant may be
     * empty, but source and target must not be.  If variant is empty then
     * the special variant NO_VARIANT is stored in slot zero of the
     * UVector of variants.
     */
    private void registerSTV(String source,
                             String target,
                             String variant) {
        // assert(source.length() > 0);
        // assert(target.length() > 0);
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        CaseInsensitiveString citrg = new CaseInsensitiveString(target);
        CaseInsensitiveString civar = new CaseInsensitiveString(variant);
        Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>> targets = specDAG.get(cisrc);
        if (targets == null) {
            targets = new Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>>();
            specDAG.put(cisrc, targets);
        }
        Vector<CaseInsensitiveString> variants = targets.get(citrg);
        if (variants == null) {
            variants = new Vector<CaseInsensitiveString>();
            targets.put(citrg, variants);
        }
        // assert(NO_VARIANT == "");
        // We add the variant string.  If it is the special "no variant"
        // string, that is, the empty string, we add it at position zero.
        if (!variants.contains(civar)) {
            if (variant.length() > 0) {
                variants.addElement(civar);
            } else {
                variants.insertElementAt(civar, 0);
            }
        }
    }

    /**
     * Remove a source-target/variant from the specDAG.
     */
    private void removeSTV(String source,
                           String target,
                           String variant) {
        // assert(source.length() > 0);
        // assert(target.length() > 0);
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        CaseInsensitiveString citrg = new CaseInsensitiveString(target);
        CaseInsensitiveString civar = new CaseInsensitiveString(variant);
        Hashtable<CaseInsensitiveString, Vector<CaseInsensitiveString>> targets = specDAG.get(cisrc);
        if (targets == null) {
            return; // should never happen for valid s-t/v
        }
        Vector<CaseInsensitiveString> variants = targets.get(citrg);
        if (variants == null) {
            return; // should never happen for valid s-t/v
        }
        variants.removeElement(civar);
        if (variants.size() == 0) {
            targets.remove(citrg); // should delete variants
            if (targets.size() == 0) {
                specDAG.remove(cisrc); // should delete targets
            }
        }
    }

    private static final boolean DEBUG = false;

    /**
     * Attempt to find a source-target/variant in the dynamic registry
     * store.  Return 0 on failure.
     */
    private Object[] findInDynamicStore(Spec src,
                                      Spec trg,
                                      String variant) {
        String ID = TransliteratorIDParser.STVtoID(src.get(), trg.get(), variant);
        ///CLOVER:OFF
        if (DEBUG) {
            System.out.println("TransliteratorRegistry.findInDynamicStore:" +
                               ID);
        }
        ///CLOVER:ON
        return (Object[]) registry.get(new CaseInsensitiveString(ID));
    }

    /**
     * Attempt to find a source-target/variant in the static locale
     * resource store.  Do not perform fallback.  Return 0 on failure.
     *
     * On success, create a new entry object, register it in the dynamic
     * store, and return a pointer to it, but do not make it public --
     * just because someone requested something, we do not expand the
     * available ID list (or spec DAG).
     */
    private Object[] findInStaticStore(Spec src,
                                     Spec trg,
                                     String variant) {
        ///CLOVER:OFF
        if (DEBUG) {
            String ID = TransliteratorIDParser.STVtoID(src.get(), trg.get(), variant);
            System.out.println("TransliteratorRegistry.findInStaticStore:" +
                               ID);
        }
        ///CLOVER:ON
        Object[] entry = null;
        if (src.isLocale()) {
            entry = findInBundle(src, trg, variant, Transliterator.FORWARD);
        } else if (trg.isLocale()) {
            entry = findInBundle(trg, src, variant, Transliterator.REVERSE);
        }

        // If we found an entry, store it in the Hashtable for next
        // time.
        if (entry != null) {
            registerEntry(src.getTop(), trg.getTop(), variant, entry, false);
        }

        return entry;
    }

    /**
     * Attempt to find an entry in a single resource bundle.  This is
     * a one-sided lookup.  findInStaticStore() performs up to two such
     * lookups, one for the source, and one for the target.
     *
     * Do not perform fallback.  Return 0 on failure.
     *
     * On success, create a new Entry object, populate it, and return it.
     * The caller owns the returned object.
     */
    private Object[] findInBundle(Spec specToOpen,
                                  Spec specToFind,
                                  String variant,
                                  int direction) {
        // assert(specToOpen.isLocale());
        ResourceBundle res = specToOpen.getBundle();

        if (res == null) {
            // This means that the bundle's locale does not match
            // the current level of iteration for the spec.
            return null;
        }

        for (int pass=0; pass<2; ++pass) {
            StringBuffer tag = new StringBuffer();
            // First try either TransliteratorTo_xxx or
            // TransliterateFrom_xxx, then try the bidirectional
            // Transliterate_xxx.  This precedence order is arbitrary
            // but must be consistent and documented.
            if (pass == 0) {
                tag.append(direction == Transliterator.FORWARD ?
                           "TransliterateTo" : "TransliterateFrom");
            } else {
                tag.append("Transliterate");
            }
            tag.append(specToFind.get().toUpperCase());

            try {
                // The Transliterate*_xxx resource is an array of
                // strings of the format { <v0>, <r0>, ... }.  Each
                // <vi> is a variant name, and each <ri> is a rule.
                String[] subres = res.getStringArray(tag.toString());

                // assert(subres != null);
                // assert(subres.length % 2 == 0);
                int i = 0;
                if (variant.length() != 0) {
                    for (i=0; i<subres.length; i+= 2) {
                        if (subres[i].equalsIgnoreCase(variant)) {
                            break;
                        }
                    }
                }

                if (i < subres.length) {
                    // We have a match, or there is no variant and i == 0.
                    // We have succeeded in loading a string from the
                    // locale resources.  Return the rule string which
                    // will itself become the registry entry.

                    // The direction is always forward for the
                    // TransliterateTo_xxx and TransliterateFrom_xxx
                    // items; those are unidirectional forward rules.
                    // For the bidirectional Transliterate_xxx items,
                    // the direction is the value passed in to this
                    // function.
                    int dir = (pass == 0) ? Transliterator.FORWARD : direction;
                    return new Object[] { new LocaleEntry(subres[i+1], dir) };
                }

            } catch (MissingResourceException e) {
                ///CLOVER:OFF
                if (DEBUG) System.out.println("missing resource: " + e);
                ///CLOVER:ON
            }
        }

        // If we get here we had a missing resource exception or we
        // failed to find a desired variant.
        return null;
    }

    /**
     * Convenience method.  Calls 3-arg find().
     */
    private Object[] find(String ID) {
        String[] stv = TransliteratorIDParser.IDtoSTV(ID);
        return find(stv[0], stv[1], stv[2]);
    }

    /**
     * Top-level find method.  Attempt to find a source-target/variant in
     * either the dynamic or the static (locale resource) store.  Perform
     * fallback.
     *
     * Lookup sequence for ss_SS_SSS-tt_TT_TTT/v:
     *
     *   ss_SS_SSS-tt_TT_TTT/v -- in hashtable
     *   ss_SS_SSS-tt_TT_TTT/v -- in ss_SS_SSS (no fallback)
     *
     *     repeat with t = tt_TT_TTT, tt_TT, tt, and tscript
     *
     *     ss_SS_SSS-t/*
     *     ss_SS-t/*
     *     ss-t/*
     *     sscript-t/*
     *
     * Here * matches the first variant listed.
     *
     * Caller does NOT own returned object.  Return 0 on failure.
     */
    private Object[] find(String source,
                          String target,
                          String variant) {

        Spec src = new Spec(source);
        Spec trg = new Spec(target);
        Object[] entry = null;

        if (variant.length() != 0) {

            // Seek exact match in hashtable
            entry = findInDynamicStore(src, trg, variant);
            if (entry != null) {
                return entry;
            }

            // Seek exact match in locale resources
            entry = findInStaticStore(src, trg, variant);
            if (entry != null) {
                return entry;
            }
        }

        for (;;) {
            src.reset();
            for (;;) {
                // Seek match in hashtable
                entry = findInDynamicStore(src, trg, NO_VARIANT);
                if (entry != null) {
                    return entry;
                }

                // Seek match in locale resources
                entry = findInStaticStore(src, trg, NO_VARIANT);
                if (entry != null) {
                    return entry;
                }
                if (!src.hasFallback()) {
                    break;
                }
                src.next();
            }
            if (!trg.hasFallback()) {
                break;
            }
            trg.next();
        }

        return null;
    }

    /**
     * Given an Entry object, instantiate it.  Caller owns result.  Return
     * 0 on failure.
     *
     * Return a non-empty aliasReturn value if the ID points to an alias.
     * We cannot instantiate it ourselves because the alias may contain
     * filters or compounds, which we do not understand.  Caller should
     * make aliasReturn empty before calling.
     *
     * The entry object is assumed to reside in the dynamic store.  It may be
     * modified.
     */
    @SuppressWarnings("unchecked")
    private Transliterator instantiateEntry(String ID,
                                            Object[] entryWrapper,
                                            StringBuffer aliasReturn) {
        // We actually modify the entry object in some cases.  If it
        // is a string, we may partially parse it and turn it into a
        // more processed precursor.  This makes the next
        // instantiation faster and allows sharing of immutable
        // components like the RuleBasedTransliterator.Data objects.
        // For this reason, the entry object is an Object[] of length
        // 1.

        for (;;) {
            Object entry = entryWrapper[0];

            if (entry instanceof RuleBasedTransliterator.Data) {
                RuleBasedTransliterator.Data data = (RuleBasedTransliterator.Data) entry;
                return new RuleBasedTransliterator(ID, data, null);
            } else if (entry instanceof Class) {
                try {
                    return (Transliterator) ((Class) entry).newInstance();
                } catch (InstantiationException e) {
                } catch (IllegalAccessException e2) {}
                return null;
            } else if (entry instanceof AliasEntry) {
                aliasReturn.append(((AliasEntry) entry).alias);
                return null;
            } else if (entry instanceof Transliterator.Factory) {
                return ((Transliterator.Factory) entry).getInstance(ID);
            } else if (entry instanceof CompoundRBTEntry) {
                return ((CompoundRBTEntry) entry).getInstance();
            } else if (entry instanceof AnyTransliterator) {
                AnyTransliterator temp = (AnyTransliterator) entry;
                return temp.safeClone();
            } else if (entry instanceof RuleBasedTransliterator) {
                RuleBasedTransliterator temp = (RuleBasedTransliterator) entry;
                return temp.safeClone();
            } else if (entry instanceof CompoundTransliterator) {
                CompoundTransliterator temp = (CompoundTransliterator) entry;
                return temp.safeClone();
            } else if (entry instanceof Transliterator) {
                return (Transliterator) entry;
            }

            // At this point entry type must be either RULES_FORWARD or
            // RULES_REVERSE.  We process the rule data into a
            // TransliteratorRuleData object, and possibly also into an
            // .id header and/or footer.  Then we modify the registry with
            // the parsed data and retry.

            TransliteratorParser parser = new TransliteratorParser();

            try {
               
                ResourceEntry re = (ResourceEntry) entry;
                parser.parse(re.resource, re.direction);
                
            } catch (ClassCastException e) {
                // If we pull a rule from a locale resource bundle it will
                // be a LocaleEntry.
                LocaleEntry le = (LocaleEntry) entry;
                parser.parse(le.rule, le.direction);
            }

            // Reset entry to something that we process at the
            // top of the loop, then loop back to the top.  As long as we
            // do this, we only loop through twice at most.
            // NOTE: The logic here matches that in
            // Transliterator.createFromRules().
            if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 0) {
                // No idBlock, no data -- this is just an
                // alias for Null
                entryWrapper[0] = new AliasEntry(NullTransliterator._ID);
            }
            else if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 1) {
                // No idBlock, data != 0 -- this is an
                // ordinary RBT_DATA
                entryWrapper[0] = parser.dataVector.get(0);
            }
            else if (parser.idBlockVector.size() == 1 && parser.dataVector.size() == 0) {
                // idBlock, no data -- this is an alias.  The ID has
                // been munged from reverse into forward mode, if
                // necessary, so instantiate the ID in the forward
                // direction.
                if (parser.compoundFilter != null) {
                    entryWrapper[0] = new AliasEntry(parser.compoundFilter.toPattern(false) + ";"
                            + parser.idBlockVector.get(0));
                } else {
                    entryWrapper[0] = new AliasEntry((String)parser.idBlockVector.get(0));
                }
            }
            else {
                entryWrapper[0] = new CompoundRBTEntry(ID, parser.idBlockVector, parser.dataVector,
                        parser.compoundFilter);
            }
        }
    }
}

//eof
