/*
******************************************************************************
* Copyright (C) 2004, International Business Machines Corporation and        *
* others. All Rights Reserved.                                               *
******************************************************************************
*/

package com.ibm.icu.impl;

import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.Vector;

import com.ibm.icu.util.StringTokenizer;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceTypeMismatchException;
import com.ibm.icu.util.VersionInfo;

public abstract class ICUResourceBundle extends UResourceBundle{ 
    /**
     * The data path to be used with getBundleInstance API
     * @draft ICU 3.0
     */
    protected static final String ICU_DATA_PATH = "com/ibm/icu/impl/";
    /**
     * The data path to be used with getBundleInstance API
     * @draft ICU 3.0
     */
    public static final String ICU_BUNDLE = "data/icudt"+VersionInfo.ICU_DATA_VERSION;    
    
    /**
     * The base name of ICU data to be used with getBundleInstance API
     * @draft ICU 3.0
     */
    public static final String ICU_BASE_NAME= ICU_DATA_PATH+ICU_BUNDLE;
    
    /**
     * The base name of collation data to be used with getBundleInstance API
     * @draft ICU 3.0
     */
    public static final String ICU_COLLATION_BASE_NAME = ICU_BASE_NAME + "/coll";
    
    /**
     * The class loader constant to be used with getBundleInstance API
     * @draft ICU 3.0
     */
    public static final ClassLoader ICU_DATA_CLASS_LOADER = ICUData.class.getClassLoader();
    
    /**
     * The name of the resource containing the installed locales
     * @draft ICU 3.0
     */
    protected static final String INSTALLED_LOCALES = "InstalledLocales";
    

    /** 
     * Resource type constant for "no resource". 
     * @draft ICU 3.0 
     */
    public static final int NONE=-1;

    /** 
     * Resource type constant for strings. 
     * @draft ICU 3.0 
     */
    public static final int STRING=0;

    /** 
     * Resource type constant for binary data. 
     * @draft ICU 3.0 
     */
    public static final int BINARY=1;

    /** 
     * Resource type constant for tables of key-value pairs. 
     * @draft ICU 3.0 
     */
    public static final int TABLE=2;

    /**
     * Resource type constant for aliases;
     * internally stores a string which identifies the actual resource
     * storing the data (can be in a different resource bundle).
     * Resolved internally before delivering the actual resource through the API.
     * @draft ICU 3.0
     * @internal
     */
    protected static final int ALIAS=3;

    /**
     * Internal use only.
     * Alternative resource type constant for tables of key-value pairs.
     * Never returned by getType().
     * @internal
     * @draft ICU 3.0
     */
    protected static final int TABLE32=4;

    /**
     * Resource type constant for a single 28-bit integer, interpreted as
     * signed or unsigned by the getInt() function.
     * @see #getInt
     * @draft ICU 3.0
     */
    public static final int INT=7;

    /** 
     * Resource type constant for arrays of resources. 
     * @draft ICU 3.0 
     */
    public static final int ARRAY=8;

    /**
     * Resource type constant for vectors of 32-bit integers.
     * @see #getIntVector
     * @draft ICU 3.0
     */
    public static final int INT_VECTOR=14;
    
    /**
     * Return the version number associated with this UResourceBundle as an 
     * VersionInfo object.
     * @return VersionInfo object containing the version of the bundle
     * @draft ICU 3.0
     */
    public VersionInfo getVersion(){
        return null;
    }
    
    /**
     * Returns a string from a string resource type
     *
     * @return a string
     * @see #getBinary
     * @see #getIntVector
     * @see #getInt
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @draft ICU 3.0
     */
    public String getString(){
        throw new UResourceTypeMismatchException("");
    }
    
    /**
     * @internal ICU 3.0
     */ 
    public String[] getStringArray(){
        throw new UResourceTypeMismatchException("");
    }
    
    /**
     * Returns a string from a string resource type
     * @param key The key whose values needs to be fetched
     * @return a string
     * @see #getBinary
     * @see #getIntVector
     * @see #getInt
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @draft ICU 3.0
     */  
  //  public String getString(String key) {
  //      throw new UResourceTypeMismatchException("");
  //  }

    
    /**
     * Returns a binary data from a binary resource. 
     *
     * @return a pointer to a chuck of unsigned bytes which live in a memory mapped/DLL file.
     * @see #getString
     * @see #getIntVector
     * @see #getInt
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @draft ICU 3.0
     */
    public ByteBuffer getBinary(){
        throw new UResourceTypeMismatchException("");   
    }
        
    /**
     * Returns a 32 bit integer array from a resource. 
     *
     * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file.
     * @see #getBinary
     * @see #getString
     * @see #getInt
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @draft ICU 3.0
     */
    public int[] getIntVector(){
        throw new UResourceTypeMismatchException("");
    }
    
    /**
     * Returns a signed integer from a resource.
     * 
     * @return an integer value
     * @see #getIntVector
     * @see #getBinary
     * @see #getString
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @stable ICU 2.0
     */
    public int getInt() {
        throw new UResourceTypeMismatchException("");
    }
    
    /**
     * Returns a unsigned integer from a resource. 
     * This integer is originally 28 bit and the sign gets propagated.
     *
     * @return an integer value
     * @see #getIntVector
     * @see #getBinary
     * @see #getString
     * @throws MissingResourceException
     * @throws UResourceTypeMismatchException
     * @stable ICU 2.0
     */
    public int getUInt() {
        throw new UResourceTypeMismatchException("");
    }
    /**
     * Returns the size of a resource. Size for scalar types is always 1, 
     * and for vector/table types is the number of child resources.
     * <br><b><font color='red'>Warning: </font></b> Integer array is treated as a scalar type. There are no 
     *          APIs to access individual members of an integer array. It
     *          is always returned as a whole.
     * @return number of resources in a given resource.
     * @draft ICU 3.0
     */
    public int getSize(){
        return size;
    }
    
    /**
     * Returns the type of a resource. 
     * Available types are {@link #INT INT}, {@link #ARRAY ARRAY}, 
     * {@link #BINARY BINARY}, {@link #INT_VECTOR INT_VECTOR}, 
     * {@link #STRING STRING}, {@link #TABLE TABLE}.
     *
     * @return type of the given resource.
     * @draft ICU 3.0
     */
    public int getType(){
        return type;
    }
    
    /**
     * Returns the key associated with a given resource. Not all the resources have a key - only 
     * those that are members of a table.
     * @return a key associated to this resource, or NULL if it doesn't have a key
     * @draft ICU 3.0
     */
    public String getKey(){
        return key;
    }

        
    /**
     * Returns the iterator which iterates over this
     * resource bundle
     * @draft ICU 3.0
     */
    public ICUResourceBundleIterator getIterator(){
        return new ICUResourceBundleIterator(this);   
    }

    
    /**
     * Returns the resource in a given resource at the specified index.
     *
     * @param index             an index to the wanted resource.
     * @return                  the sub resource UResourceBundle object
     * @throws IndexOutOfBoundsException
     * @draft ICU 3.0
     */
    public ICUResourceBundle get(int index){
        ICUResourceBundle obj =  handleGet(index);
        if (obj == null) {
            obj = (ICUResourceBundle)getParent();
            if ( obj!= null) {
                obj = obj.get(index);
            }
            if (obj == null)
                throw new MissingResourceException("Can't find resource for bundle "
                                                   +this.getClass().getName()
                                                   +", key "+getKey(),
                                                   this.getClass().getName(),
                                                   getKey());
        }
        return obj;
    }
    // abstract UResourceBundle handleGetInt(int index);
    
    /**
     * Returns a resource in a given resource that has a given key.
     *
     * @param key               a key associated with the wanted resource
     * @return                  a resource bundle object representing rhe resource
     * @throws MissingResourceException
     * @draft ICU 3.0
     */
    public ICUResourceBundle get(String key){
        ICUResourceBundle obj =  handleGet(key);
        if (obj == null) {
            obj = (ICUResourceBundle)getParent();
            if ( obj!= null) {
                obj = obj.get(key);
            }
            if (obj == null){
                String fullName = ICUResourceBundleReader.getFullName(getBaseName(), getLocaleID());
                throw new MissingResourceException("Can't find resource for bundle "
                                                   +fullName
                                                   +", key "+key,
                                                   this.getClass().getName(),
                                                   key);
            }
        }
        return obj;
        
   }
    
    /**
     * Returns the string in a given resource at the specified index.
     *
     * @param indexS            an index to the wanted string.
     * @return                  a string which lives in the resource.
     * @throws IndexOutOfBoundsException
     * @throws UResourceTypeMismatchException
     * @draft ICU 3.0
     */
    public String getString(int index){
        ICUResourceBundle temp = get(index);
        if(temp.getType()==STRING){
            return temp.getString();   
        }
        throw new UResourceTypeMismatchException("");
    }
    
    /**
     * Returns the parent bundle of this bundle
     * @return UResourceBundle the parent of this bundle. Returns null if none
     * @draft ICU 3.0
     */
    public abstract UResourceBundle getParent();
    
    /**
     * Returns a functionally equivalent locale, considering keywords as well, for the specified keyword.
     * @param BASE resource specifier
     * @param resName top level resource to consider (such as "collations")
     * @param keyword a particular keyword to consider (such as "collation" )
     * @param locid The requested locale 
     * @param fillinIsAvailable If non-null, 1-element array of fillin parameter that indicates whether the 
     * requested locale was available. The locale is defined as 'available' if it physically 
     * exists within the specified tree.
     * @return the locale
     * @internal ICU 3.0
     */
    public static final ULocale  getFunctionalEquivalent(String baseName, String resName, String keyword, 
            ULocale locID, boolean fillinIsAvailable[]){
        String kwVal = locID.getKeywordValue(keyword);
        String baseLoc = locID.getBaseName();
        String defStr = null;
        ULocale parent = new ULocale(baseLoc);
        ULocale found = locID;
        ULocale defLoc = null; // locale where default (found) resource is
        boolean lookForDefault = false; // true if kwVal needs to be set 
        ULocale fullBase = null; // base locale of found (target) resource
        int defDepth = 0; // depth of 'default' marker
        int resDepth = 0; // depth of found resource;
        if(fillinIsAvailable != null) {
            fillinIsAvailable[0] = true;
        }
        
        if((kwVal == null) || (kwVal.length()==0) || kwVal.equals(DEFAULT_TAG)) {
            kwVal = "";  // default tag is treated as no keyword
            lookForDefault = true;
        }

        // Check top level locale first
        ICUResourceBundle  r = null;
        
        r = (ICUResourceBundle)UResourceBundle.getBundleInstance(baseName,parent);
        found = r.getULocale();
        if(fillinIsAvailable != null) {
            if (!found.equals(parent)) {
                fillinIsAvailable[0] = false;
            }
        }
        // determine in which locale (if any) the currently relevant 'default' is       
        do {
            try {
                    ICUResourceBundle irb = r.get(resName);
                    defStr = irb.getString(DEFAULT_TAG); 
                    if(lookForDefault == true) {
                        kwVal = defStr;
                        lookForDefault = false;
                    }
                    defLoc = r.getULocale();            
            } catch (MissingResourceException t) {
                // Ignore error and continue search. 
            }
            r = (ICUResourceBundle)r.getParent();
            defDepth ++;
        } while ((r != null) && (defLoc == null));
        
        
        // Now, search for the named resource
        parent = new ULocale(baseLoc);
        r = (ICUResourceBundle)UResourceBundle.getBundleInstance(baseName,parent);
        // determine in which locale (if any) the named resource is located        
        do {
            try {
                    ICUResourceBundle irb = r.get(resName);
                    UResourceBundle urb = irb.get(kwVal); 
                    fullBase = r.getULocale(); // If the get() completed, we have the full base locale
            } catch (MissingResourceException t) {
                // Ignore error, 
            }
            r = (ICUResourceBundle)r.getParent();
            resDepth ++;
        } while ((r != null) && (fullBase == null));
        
        if(fullBase == null && // Could not find resource 'kwVal'
                (defStr != null) && // default was defined
                !defStr.equals(kwVal)) { // kwVal is not default
            // couldn't find requested resource. Fall back to default.
            kwVal = defStr; // Fall back to default.
            parent = new ULocale(baseLoc);
            r = (ICUResourceBundle)UResourceBundle.getBundleInstance(baseName,parent);
            resDepth = 0;
            // determine in which locale (if any) the named resource is located        
            do {
                try {
                        ICUResourceBundle irb = r.get(resName);
                        UResourceBundle urb = irb.get(kwVal); 
                        // if we didn't fail before this..
                        fullBase = r.getULocale();
                } catch (MissingResourceException t) {
                    // Ignore error, continue search.
                }
                r = (ICUResourceBundle)r.getParent();
                resDepth ++;
            } while ((r != null) && (fullBase == null));
        }

        if(fullBase == null ) {
            throw new MissingResourceException("Could not find locale containing requested or default keyword.",
                    baseName, keyword + "=" + kwVal);
        }
        
        if(defStr.equals(kwVal) && // if default was requested and
               (resDepth <= defDepth)){  // default was set in same locale or child 
            return fullBase; // Keyword value is default - no keyword needed in locale
        } else {
            return new ULocale(fullBase.toString() + "@" + keyword + "=" + kwVal);
        }
    }

    /**
     * Given a tree path and keyword, return a string enumeration of all possible values for that keyword.
     * @param BASE resource specifier
     * @param keyword a particular keyword to consider, must match a top level resource name 
     * within the tree. (i.e. "collations")
     * @internal ICU 3.0
     */
    public static final String[] getKeywordValues(String baseName, String keyword){
        Set keywords = new HashSet();
		ULocale locales[] = createULocaleList(baseName,ICU_DATA_CLASS_LOADER);
		int i;
		
		for(i=0;i<locales.length;i++) {
			try {
				UResourceBundle b = UResourceBundle.getBundleInstance(baseName, locales[i]);
				// downcast to ICUResourceBundle?
				ICUResourceBundle irb = (ICUResourceBundle)(b.getObject(keyword));
				Enumeration e = irb.getKeys();
				Object s;
				while(e.hasMoreElements()) {
					s= e.nextElement();
					if ((s instanceof String) && !DEFAULT_TAG.equals(s)) { // don't add 'default' items
						keywords.add(s);
					}
				}
			} catch (Throwable t){
				//System.err.println("Error in  - " + new Integer(i).toString() + " - " + t.toString());
				// ignore the err - just skip that resource
			}
		}
		return (String[])keywords.toArray(new String[0]);
    }


    /**
     * This method performs multilevel fallback for fetching items from the bundle
     * e.g:
     * If resource is in the form
     * de__PHONEBOOK{
     *      collations{
     *              default{ "phonebook"}
     *      }
     * }
     * If the value of "default" key needs to be accessed, then do:
     * <code>
     *  UResourceBundle bundle = UResourceBundle.getBundleInstance("de__PHONEBOOK");
     *  ICUResourceBundle result = null;
     *  if(bundle instanceof ICUListResourceBundle){
     *      result = ((ICUListResourceBundle) bundle).getWithFallback("collations/default");
     *  }
     * </code>
     * @param path  The path to the required resource key
     * @return resource represented by the key
     * @exception MissingResourceException
     */
    public ICUResourceBundle getWithFallback(String path) throws MissingResourceException {
        ICUResourceBundle result = null;      
        ICUResourceBundle actualBundle = this;

        // now recuse to pick up sub levels of the items
        result = findResourceWithFallback(path, actualBundle);
                    
        if(result == null){
            throw new MissingResourceException("Can't find resource for bundle "
                    +this.getClass().getName()
                    +", key "+getType(),
                    path,
                    getKey());
        }
        return result;
    }

    // will throw type mismatch exception if the resource is not a string
    public String getStringWithFallback(String path) throws MissingResourceException {
	   return getWithFallback(path).getString();
    }

 
    /**
     * Gets a resource bundle using the specified base name, locale, and class root.
     *
     * @param baseName the base name of the resource bundle, a fully qualified class name
     * @param locale the locale for which a resource bundle is desired
     * @param root the class object from which to load the resource bundle
     * @param disableFallback Option to disable locale inheritence. 
     *                          If true the fallback chain will not be built.
     * @exception MissingResourceException
     *     if no resource bundle for the specified base name can be found
     * @return a resource bundle for the given base name and locale
     * @draft ICU 3.0
     * 
     */    
    public static UResourceBundle getBundleInstance(String baseName, String localeName, boolean disableFallback){
        return instantiateBundle(baseName, localeName, ICU_DATA_CLASS_LOADER, disableFallback);   
    }

    
    /**
     * Return a set of the locale names supported by a collection of resource bundles.
     * @param bundlePrefix the prefix of the resource bundles to use.
     */
    public static Set getAvailableLocaleNameSet(String bundlePrefix) {
        return getAvailEntry(bundlePrefix).getLocaleNameSet();
    }

    /**
     * Return a set of the locale names supported by a collection of resource bundles.
     * @param bundlePrefix the prefix of the resource bundles to use.
     */
    public static Set getAvailableLocaleNameSet() {
        return getAvailableLocaleNameSet(ICU_BASE_NAME);
    }
    

    /**
     * Get the set of Locales installed in the specified bundles.
     * @return the list of available locales
     * @draft ICU 3.0
     */
    public static final ULocale[] getAvailableULocales(String baseName){
        return getAvailEntry(baseName).getULocaleList();
    }
    /**
     * Get the set of ULocales installed the base bundle.
     * @return the list of available locales
     * @draft ICU 3.0
     */
    public static final ULocale[] getAvailableULocales(){
        return getAvailableULocales(ICU_BASE_NAME);
    }

    /**
     * Get the set of Locales installed in the specified bundles.
     * @return the list of available locales
     * @draft ICU 3.0
     */
    public static final Locale[] getAvailableLocales(String baseName){
        return getAvailEntry(baseName).getLocaleList();
    }
    /**
     * Get the set of Locales installed the base bundle.
     * @return the list of available locales
     * @draft ICU 3.0
     */
    public static final Locale[] getAvailableLocales(){
        return getAvailEntry(ICU_BASE_NAME).getLocaleList();
    }
    
    /**
     * 
     * @param ulocales
     * @return
     * @draft ICU 3.0
     */
    public static final Locale[] getLocaleList(ULocale[] ulocales){
         ArrayList list = new ArrayList();
         for(int i=0; i< ulocales.length; i++){
            // if the ULocale does not contain a script code
            // only then convert it to a Locale object
            if(ulocales[i].getScript().length()==0){
                list.add(new Locale(ulocales[i].getLanguage(), 
                                    ulocales[i].getCountry(), 
                                    ulocales[i].getVariant()));
            }
         }
         Locale[] locales = new Locale[list.size()];
         for(int i=0; i<locales.length; i++){
            locales[i] = (Locale)list.get(i);  
         }
         return locales;
    }

    public Enumeration getKeys(){
        Vector keys = new Vector();
        ICUResourceBundle item =null;
        for(int i=0; i<size; i++){
            item = get(i);
            keys.add(item.getKey());
        }
        return keys.elements();
    }
    
    public static ICUResourceBundle createBundle(String baseName, String localeID, ClassLoader root) {
        return ICUResourceBundleImpl.createBundle(baseName, localeID, root);
    }
    //====== protected members ==============
    protected int type = NONE;
    protected String key;
    protected int size = 1;
    protected String resPath;
    protected long resource = RES_BOGUS;
    protected boolean isTopLevel = false;
    
    protected static final long UNSIGNED_INT_MASK = 0xffffffffL;

    protected static final long RES_BOGUS = 0xffffffff;

    protected  ICUResourceBundle handleGet(String key, HashMap table){
        throw new UResourceTypeMismatchException("");   
    }
    protected  ICUResourceBundle handleGet(int index, HashMap table){
        throw new UResourceTypeMismatchException("");   
    }

    /**
     * Returns the locale of this resource bundle. This method can be used after a
     * call to getBundle() to determine whether the resource bundle returned really
     * corresponds to the requested locale or is a fallback.
     *
     * @return the locale of this resource bundle
     */
    public Locale getLocale() {
        return getULocale().toLocale();
    }
    
    protected Object handleGetObject(String key){
        Object obj = handleGetObjectImpl(key);
        if (obj == null) {
            UResourceBundle parent = getParent();
            if ( parent!= null) {
                obj = parent.getObject(key);
            }
            if (obj == null)
                throw new MissingResourceException("Can't find resource for bundle "
                                                   +this.getClass().getName()
                                                   +", key "+key,
                                                   this.getClass().getName(),
                                                   key);
        }
        return obj;
    }
    private Object handleGetObjectImpl(String key){
        if(getType()==STRING){
            return getString();   
        }
        ICUResourceBundle obj =  handleGet(key);
        if(obj!=null){
            if(obj.getType()==STRING){
                return obj.getString();   
            }
            try{
                if(obj.getType()==ARRAY){
                    return obj.handleGetStringArray();   
                }
            }catch(UResourceTypeMismatchException ex){
                return obj;   
            }
        }
        return obj;        
    }

    protected ICUResourceBundle handleGet(int index){
        return null;
    }
    protected ICUResourceBundle handleGet(String key){
        return null;   
    }
    protected String[] handleGetStringArray(){
        return null;   
    }

    // ========== privates ==========
    private static final String ICU_RESOURCE_INDEX = "res_index";
    
    private static final String DEFAULT_TAG = "default";
    
    // Flag for enabling/disabling debugging code
    private static final boolean DEBUG = ICUDebug.enabled("localedata");

    // Cache for getAvailableLocales
    private static SoftReference GET_AVAILABLE_CACHE;
    private static final ULocale[] createULocaleList(String baseName, ClassLoader root){
        ICUResourceBundle bundle = (ICUResourceBundle) instantiateBundle(baseName, ICU_RESOURCE_INDEX, root, true);
        bundle = bundle.get(INSTALLED_LOCALES);
        int length = bundle.getSize();
        int i = 0;
        ULocale[] locales = new ULocale[length];
        ICUResourceBundleIterator iter = bundle.getIterator();
        iter.reset();
        while(iter.hasNext()){
            locales[i++] = new ULocale(iter.next().getKey());   
        } 
        bundle = null;
        return locales;
    }
    
    private static final Locale[] createLocaleList(String baseName){
        ULocale[] ulocales = getAvailEntry(baseName).getULocaleList();
        return getLocaleList(ulocales);
    }
    private static final String[] createLocaleNameArray(String baseName, ClassLoader root){
        ICUResourceBundle bundle = (ICUResourceBundle) instantiateBundle(baseName, ICU_RESOURCE_INDEX, root, true);
        bundle = bundle.get(INSTALLED_LOCALES);
        int length = bundle.getSize();
        int i = 0;
        String[] locales = new String[length];
        ICUResourceBundleIterator iter = bundle.getIterator();
        iter.reset();
        while(iter.hasNext()){
            locales[i++] = iter.next().getKey();   
        } 
        bundle = null;
        return locales;
    }
    private static Set createLocaleNameSet(String baseName) {
        try {
            String[] locales = createLocaleNameArray(baseName,ICU_DATA_CLASS_LOADER);

            HashSet set = new HashSet();
            set.addAll(Arrays.asList(locales));
            return Collections.unmodifiableSet(set);
        }
        catch (MissingResourceException e) {
            if (DEBUG) System.out.println("couldn't find index for bundleName: " + baseName);
            Thread.dumpStack();
        }
        return Collections.EMPTY_SET;
    }
    
    /**
     * Holds the prefix, and lazily creates the Locale[] list or the locale name Set as needed.
     */
    private static final class AvailEntry {
        private String prefix;
        private ULocale[] ulocales;
        private Locale[] locales;
        private Set nameSet;

        AvailEntry(String prefix) {
            this.prefix = prefix;
        }

        ULocale[] getULocaleList() {
            if (ulocales == null) {
                ulocales = createULocaleList(prefix, ICU_DATA_CLASS_LOADER);
            }
            return ulocales;
        }
        Locale[] getLocaleList(){
            if(locales == null){
                locales = createLocaleList(prefix);
            }
            return locales;
        }
        Set getLocaleNameSet() {
            if (nameSet == null) {
                nameSet = createLocaleNameSet(prefix);
            }
            return nameSet;
        }
    }

    /**
     * Stores the locale information in a cache accessed by key (bundle prefix).  The
     * cached objects are AvailEntries.  The cache is held by a SoftReference
     * so it can be GC'd.
     */
    private static AvailEntry getAvailEntry(String key) {
        AvailEntry ae = null;
        Map lcache = null;
        if (GET_AVAILABLE_CACHE != null) {
            lcache = (Map)GET_AVAILABLE_CACHE.get();
            if (lcache != null) {
                ae = (AvailEntry)lcache.get(key);
            }
        }

        if (ae == null) {
            ae = new AvailEntry(key);
            if (lcache == null) {
                lcache = new HashMap();
                lcache.put(key, ae);
                GET_AVAILABLE_CACHE = new SoftReference(lcache);
            } else {
                lcache.put(key, ae);
            }
        }

        return ae;
    }  
    
    private ICUResourceBundle findResourceWithFallback(String path, ICUResourceBundle actualBundle) {
        ICUResourceBundle sub = null;
        while (actualBundle != null) {
            StringTokenizer st = new StringTokenizer(path, "/");
            ICUResourceBundle current = actualBundle;
            while (st.hasMoreTokens()) {
                String subKey = st.nextToken();
                sub = current.handleGet(subKey, null);
                if(sub==null){
                   break;   
                }
                current = sub;
            }
            if(sub!=null){
                //we found it
                break;
            }
            if(actualBundle.resPath.length()!=0){
                path = resPath+"/"+path;
            }
            // if not try the parent bundle
            actualBundle = (ICUResourceBundle) actualBundle.getParent();
            
        }
        return sub;
    }     

}
