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

package com.ibm.icu.text;

//import com.ibm.icu.impl.ICULocaleData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.lang.UScript;
import com.ibm.icu.util.CaseInsensitiveString;
import com.ibm.icu.util.UResourceBundle;

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

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 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 specDAG;

    /**
     * Vector of public full IDs (CaseInsensitiveString objects).
     */
    private Vector 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){
                scriptName = null;
            }
            // 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 idBlockVector;
        private Vector dataVector;
        private UnicodeSet compoundFilter;

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

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

            int limit = Math.max(idBlockVector.size(), dataVector.size());
            for (int i = 0; i < limit; i++) {
                if (i < idBlockVector.size()) {
                    String idBlock = (String)idBlockVector.get(i);
                    if (idBlock.length() > 0)
                        transliterators.add(Transliterator.getInstance(idBlock));
                }
                if (i < dataVector.size()) {
                    RuleBasedTransliterator.Data data = (RuleBasedTransliterator.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();
        specDAG = new Hashtable();
        availableIDs = new Vector();
    }

    /**
     * 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 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 {
        Enumeration en;

        public IDEnumeration(Enumeration e) {
            en = e;
        }

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

        public Object nextElement() {
            return ((CaseInsensitiveString) 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 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 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 getAvailableTargets(String source) {
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        Hashtable targets = (Hashtable) 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 getAvailableVariants(String source, String target) {
        CaseInsensitiveString cisrc = new CaseInsensitiveString(source);
        CaseInsensitiveString citrg = new CaseInsensitiveString(target);
        Hashtable targets = (Hashtable) specDAG.get(cisrc);
        if (targets == null) {
            return new IDEnumeration(null);
        }
        Vector variants = (Vector) 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);

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

        registry.put(ciID, entry);
        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 targets = (Hashtable) specDAG.get(cisrc);
        if (targets == null) {
            targets = new Hashtable();
            specDAG.put(cisrc, targets);
        }
        Vector variants = (Vector) targets.get(citrg);
        if (variants == null) {
            variants = new Vector();
            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 targets = (Hashtable) specDAG.get(cisrc);
        if (targets == null) {
            return; // should never happen for valid s-t/v
        }
        Vector variants = (Vector) 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);
        if (DEBUG) {
            System.out.println("TransliteratorRegistry.findInDynamicStore:" +
                               ID);
        }
        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) {
        if (DEBUG) {
            String ID = TransliteratorIDParser.STVtoID(src.get(), trg.get(), variant);
            System.out.println("TransliteratorRegistry.findInStaticStore:" +
                               ID);
        }
        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) {
                if (DEBUG) System.out.println("missing resource: " + e);
            }
        }

        // 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.
     */
    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 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) + ";"
                            + (String)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
