/*
 *******************************************************************************
 * Copyright (C) 2011-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.ibm.icu.impl.TextTrieMap.ResultHandler;
import com.ibm.icu.text.LocaleDisplayNames;
import com.ibm.icu.text.TimeZoneFormat.TimeType;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.text.TimeZoneNames.MatchInfo;
import com.ibm.icu.text.TimeZoneNames.NameType;
import com.ibm.icu.util.BasicTimeZone;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.TimeZone.SystemTimeZoneType;
import com.ibm.icu.util.TimeZoneTransition;
import com.ibm.icu.util.ULocale;

/**
 * This class interact with TimeZoneNames and LocaleDisplayNames
 * to format and parse time zone's generic display names.
 * It is not recommended to use this class directly, instead
 * use com.ibm.icu.text.TimeZoneFormat.
 */
public class TimeZoneGenericNames implements Serializable, Freezable<TimeZoneGenericNames> {

    // Note: This class implements Serializable, but we no longer serialize instance of
    // TimeZoneGenericNames in ICU 49. ICU 4.8 com.ibm.icu.text.TimeZoneFormat used to
    // serialize TimeZoneGenericNames field. TimeZoneFormat no longer read TimeZoneGenericNames
    // field, we have to keep TimeZoneGenericNames Serializable. Otherwise it fails to read
    // (unused) TimeZoneGenericNames serialized data.

    private static final long serialVersionUID = 2729910342063468417L;

    /**
     * Generic name type enum
     */
    public enum GenericNameType {
        LOCATION ("LONG", "SHORT"),
        LONG (),
        SHORT ();

        String[] _fallbackTypeOf;
        GenericNameType(String... fallbackTypeOf) {
            _fallbackTypeOf = fallbackTypeOf;
        }

        public boolean isFallbackTypeOf(GenericNameType type) {
            String typeStr = type.toString();
            for (String t : _fallbackTypeOf) {
                if (t.equals(typeStr)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * Format pattern enum used for composing location and partial location names
     */
    public enum Pattern {
        // The format pattern such as "{0} Time", where {0} is the country or city. 
        REGION_FORMAT("regionFormat", "({0})"),

        // Note: FALLBACK_REGION_FORMAT is no longer used since ICU 50/CLDR 22.1
        // The format pattern such as "{1} Time ({0})", where {1} is the country and {0} is a city.
        //FALLBACK_REGION_FORMAT("fallbackRegionFormat", "{1} ({0})"),

        // The format pattern such as "{1} ({0})", where {1} is the metazone, and {0} is the country or city.
        FALLBACK_FORMAT("fallbackFormat", "{1} ({0})");

        String _key;
        String _defaultVal;

        Pattern(String key, String defaultVal) {
            _key = key;
            _defaultVal = defaultVal;
        }

        String key() {
            return _key;
        }

        String defaultValue() {
            return _defaultVal;
        }
    }

    private ULocale _locale;
    private TimeZoneNames _tznames;

    private transient boolean _frozen;
    private transient String _region;
    private transient WeakReference<LocaleDisplayNames> _localeDisplayNamesRef;
    private transient MessageFormat[] _patternFormatters;

    private transient ConcurrentHashMap<String, String> _genericLocationNamesMap;
    private transient ConcurrentHashMap<String, String> _genericPartialLocationNamesMap;
    private transient TextTrieMap<NameInfo> _gnamesTrie;
    private transient boolean _gnamesTrieFullyLoaded;

    private static Cache GENERIC_NAMES_CACHE = new Cache();

    // Window size used for DST check for a zone in a metazone (about a half year)
    private static final long DST_CHECK_RANGE = 184L*(24*60*60*1000);

    private static final NameType[] GENERIC_NON_LOCATION_TYPES =
                                {NameType.LONG_GENERIC, NameType.SHORT_GENERIC};


    /**
     * Constructs a <code>TimeZoneGenericNames</code> with the given locale
     * and the <code>TimeZoneNames</code>.
     * @param locale the locale
     * @param tznames the TimeZoneNames
     */
    public TimeZoneGenericNames(ULocale locale, TimeZoneNames tznames) {
        _locale = locale;
        _tznames = tznames;
        init();
    }

    /**
     * Private method initializing the instance of <code>TimeZoneGenericName</code>.
     * This method should be called from a constructor and readObject.
     */
    private void init() {
        if (_tznames == null) {
            _tznames = TimeZoneNames.getInstance(_locale);
        }
        _genericLocationNamesMap = new ConcurrentHashMap<String, String>();
        _genericPartialLocationNamesMap = new ConcurrentHashMap<String, String>();

        _gnamesTrie = new TextTrieMap<NameInfo>(true);
        _gnamesTrieFullyLoaded = false;

        // Preload zone strings for the default time zone
        TimeZone tz = TimeZone.getDefault();
        String tzCanonicalID = ZoneMeta.getCanonicalCLDRID(tz);
        if (tzCanonicalID != null) {
            loadStrings(tzCanonicalID);
        }
    }

    /**
     * Constructs a <code>TimeZoneGenericNames</code> with the given locale.
     * This constructor is private and called from {@link #getInstance(ULocale)}.
     * @param locale the locale
     */
    private TimeZoneGenericNames(ULocale locale) {
        this(locale, null);
    }

    /**
     * The factory method of <code>TimeZoneGenericNames</code>. This static method
     * returns a frozen instance of cached <code>TimeZoneGenericNames</code>.
     * @param locale the locale
     * @return A frozen <code>TimeZoneGenericNames</code>.
     */
    public static TimeZoneGenericNames getInstance(ULocale locale) {
        String key = locale.getBaseName();
        return GENERIC_NAMES_CACHE.getInstance(key, locale);
    }

    /**
     * Returns the display name of the time zone for the given name type
     * at the given date, or null if the display name is not available.
     * 
     * @param tz the time zone
     * @param type the generic name type - see {@link GenericNameType}
     * @param date the date
     * @return the display name of the time zone for the given name type
     * at the given date, or null.
     */
    public String getDisplayName(TimeZone tz, GenericNameType type, long date) {
        String name = null;
        String tzCanonicalID = null;
        switch (type) {
        case LOCATION:
            tzCanonicalID = ZoneMeta.getCanonicalCLDRID(tz);
            if (tzCanonicalID != null) {
                name = getGenericLocationName(tzCanonicalID);
            }
            break;
        case LONG:
        case SHORT:
            name = formatGenericNonLocationName(tz, type, date);
            if (name == null) {
                tzCanonicalID = ZoneMeta.getCanonicalCLDRID(tz);
                if (tzCanonicalID != null) {
                    name = getGenericLocationName(tzCanonicalID);
                }
            }
            break;
        }
        return name;
    }

    /**
     * Returns the generic location name for the given canonical time zone ID.
     * 
     * @param canonicalTzID the canonical time zone ID
     * @return the generic location name for the given canonical time zone ID.
     */
    public String getGenericLocationName(String canonicalTzID) {
        if (canonicalTzID == null || canonicalTzID.length() == 0) {
            return null;
        }
        String name = _genericLocationNamesMap.get(canonicalTzID);
        if (name != null) {
            if (name.length() == 0) {
                // empty string to indicate the name is not available
                return null;
            }
            return name;
        }

        String countryCode = ZoneMeta.getCanonicalCountry(canonicalTzID);
        if (countryCode != null) {
            String country = getLocaleDisplayNames().regionDisplayName(countryCode);
            if (ZoneMeta.getSingleCountry(canonicalTzID) != null) {
                // If this is only the single zone in the country, use the country name
                name = formatPattern(Pattern.REGION_FORMAT, country);
            } else {
                // If there are multiple zones including this in the country,
                // use the exemplar city name

                // getExemplarLocationName should return non-empty String
                // if the time zone is associated with a location
                String city = _tznames.getExemplarLocationName(canonicalTzID);
                name = formatPattern(Pattern.REGION_FORMAT, city);
            }
        }

        if (name == null) {
            _genericLocationNamesMap.putIfAbsent(canonicalTzID.intern(), "");
        } else {
            synchronized (this) {   // we have to sync the name map and the trie
                canonicalTzID = canonicalTzID.intern();
                String tmp = _genericLocationNamesMap.putIfAbsent(canonicalTzID, name.intern());
                if (tmp == null) {
                    // Also put the name info the to trie
                    NameInfo info = new NameInfo();
                    info.tzID = canonicalTzID;
                    info.type = GenericNameType.LOCATION;
                    _gnamesTrie.put(name, info);
                } else {
                    name = tmp;
                }
            }
        }
        return name;
    }

    /**
     * Sets the pattern string for the pattern type.
     * Note: This method is designed for CLDR ST - not for common use.
     * @param patType the pattern type
     * @param patStr the pattern string
     * @return this object.
     */
    public TimeZoneGenericNames setFormatPattern(Pattern patType, String patStr) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify frozen object");
        }

        // Changing pattern will invalidates cached names
        if (!_genericLocationNamesMap.isEmpty()) {
            _genericLocationNamesMap = new ConcurrentHashMap<String, String>();
        }
        if (!_genericPartialLocationNamesMap.isEmpty()) {
            _genericPartialLocationNamesMap = new ConcurrentHashMap<String, String>();
        }
        _gnamesTrie = null;
        _gnamesTrieFullyLoaded = false;

        if (_patternFormatters == null) {
            _patternFormatters = new MessageFormat[Pattern.values().length];
        }
        _patternFormatters[patType.ordinal()] = new MessageFormat(patStr);
        return this;
    }

    /**
     * Private method to get a generic string, with fallback logics involved,
     * that is,
     * 
     * 1. If a generic non-location string is available for the zone, return it.
     * 2. If a generic non-location string is associated with a meta zone and 
     *    the zone never use daylight time around the given date, use the standard
     *    string (if available).
     * 3. If a generic non-location string is associated with a meta zone and
     *    the offset at the given time is different from the preferred zone for the
     *    current locale, then return the generic partial location string (if available)
     * 4. If a generic non-location string is not available, use generic location
     *    string.
     * 
     * @param tz the requested time zone
     * @param date the date
     * @param type the generic name type, either LONG or SHORT
     * @return the name used for a generic name type, which could be the
     * generic name, or the standard name (if the zone does not observes DST
     * around the date), or the partial location name.
     */
    private String formatGenericNonLocationName(TimeZone tz, GenericNameType type, long date) {
        assert(type == GenericNameType.LONG || type == GenericNameType.SHORT);
        String tzID = ZoneMeta.getCanonicalCLDRID(tz);

        if (tzID == null) {
            return null;
        }

        // Try to get a name from time zone first
        NameType nameType = (type == GenericNameType.LONG) ? NameType.LONG_GENERIC : NameType.SHORT_GENERIC;
        String name = _tznames.getTimeZoneDisplayName(tzID, nameType);

        if (name != null) {
            return name;
        }

        // Try meta zone
        String mzID = _tznames.getMetaZoneID(tzID, date);
        if (mzID != null) {
            boolean useStandard = false;
            int[] offsets = {0, 0};
            tz.getOffset(date, false, offsets);

            if (offsets[1] == 0) {
                useStandard = true;
                // Check if the zone actually uses daylight saving time around the time
                if (tz instanceof BasicTimeZone) {
                    BasicTimeZone btz = (BasicTimeZone)tz;
                    TimeZoneTransition before = btz.getPreviousTransition(date, true);
                    if (before != null
                            && (date - before.getTime() < DST_CHECK_RANGE)
                            && before.getFrom().getDSTSavings() != 0) {
                        useStandard = false;
                    } else {
                        TimeZoneTransition after = btz.getNextTransition(date, false);
                        if (after != null
                                && (after.getTime() - date < DST_CHECK_RANGE)
                                && after.getTo().getDSTSavings() != 0) {
                            useStandard = false;
                        }
                    }
                } else {
                    // If not BasicTimeZone... only if the instance is not an ICU's implementation.
                    // We may get a wrong answer in edge case, but it should practically work OK.
                    int[] tmpOffsets = new int[2];
                    tz.getOffset(date - DST_CHECK_RANGE, false, tmpOffsets);
                    if (tmpOffsets[1] != 0) {
                        useStandard = false;
                    } else {
                        tz.getOffset(date + DST_CHECK_RANGE, false, tmpOffsets);
                        if (tmpOffsets[1] != 0){
                            useStandard = false;
                        }
                    }
                }
            }
            if (useStandard) {
                NameType stdNameType = (nameType == NameType.LONG_GENERIC) ?
                        NameType.LONG_STANDARD : NameType.SHORT_STANDARD;
                String stdName = _tznames.getDisplayName(tzID, stdNameType, date);
                if (stdName != null) {
                    name = stdName;

                    // TODO: revisit this issue later
                    // In CLDR, a same display name is used for both generic and standard
                    // for some meta zones in some locales.  This looks like a data bugs.
                    // For now, we check if the standard name is different from its generic
                    // name below.
                    String mzGenericName = _tznames.getMetaZoneDisplayName(mzID, nameType);
                    if (stdName.equalsIgnoreCase(mzGenericName)) {
                        name = null;
                    }
                }
            }

            if (name == null) {
                // Get a name from meta zone
                String mzName = _tznames.getMetaZoneDisplayName(mzID, nameType);
                if (mzName != null) {
                    // Check if we need to use a partial location format.
                    // This check is done by comparing offset with the meta zone's
                    // golden zone at the given date.
                    String goldenID = _tznames.getReferenceZoneID(mzID, getTargetRegion());
                    if (goldenID != null && !goldenID.equals(tzID)) {
                        TimeZone goldenZone = TimeZone.getFrozenTimeZone(goldenID);
                        int[] offsets1 = {0, 0};

                        // Check offset in the golden zone with wall time.
                        // With getOffset(date, false, offsets1),
                        // you may get incorrect results because of time overlap at DST->STD
                        // transition.
                        goldenZone.getOffset(date + offsets[0] + offsets[1], true, offsets1);

                        if (offsets[0] != offsets1[0] || offsets[1] != offsets1[1]) {
                            // Now we need to use a partial location format.
                            name = getPartialLocationName(tzID, mzID, (nameType == NameType.LONG_GENERIC), mzName);
                        } else {
                            name = mzName;
                        }
                    } else {
                        name = mzName;
                    }
                }
            }
        }
        return name;
    }

    /**
     * Private simple pattern formatter used for formatting generic location names
     * and partial location names. We intentionally use JDK MessageFormat
     * for performance reason.
     * 
     * @param pat the message pattern enum
     * @param args the format argument(s)
     * @return the formatted string
     */
    private synchronized String formatPattern(Pattern pat, String... args) {
        if (_patternFormatters == null) {
            _patternFormatters = new MessageFormat[Pattern.values().length];
        }

        int idx = pat.ordinal();
        if (_patternFormatters[idx] == null) {
            String patText;
            try {
                ICUResourceBundle bundle = (ICUResourceBundle) ICUResourceBundle.getBundleInstance(
                    ICUResourceBundle.ICU_ZONE_BASE_NAME, _locale);
                patText = bundle.getStringWithFallback("zoneStrings/" + pat.key());
            } catch (MissingResourceException e) {
                patText = pat.defaultValue();
            }

            _patternFormatters[idx] = new MessageFormat(patText);
        }
        return _patternFormatters[idx].format(args);
    }

    /**
     * Private method returning LocaleDisplayNames instance for the locale of this
     * instance. Because LocaleDisplayNames is only used for generic
     * location formant and partial location format, the LocaleDisplayNames
     * is instantiated lazily.
     * 
     * @return the instance of LocaleDisplayNames for the locale of this object.
     */
    private synchronized LocaleDisplayNames getLocaleDisplayNames() {
        LocaleDisplayNames locNames = null;
        if (_localeDisplayNamesRef != null) {
            locNames = _localeDisplayNamesRef.get();
        }
        if (locNames == null) {
            locNames = LocaleDisplayNames.getInstance(_locale);
            _localeDisplayNamesRef = new WeakReference<LocaleDisplayNames>(locNames);
        }
        return locNames;
    }

    private synchronized void loadStrings(String tzCanonicalID) {
        if (tzCanonicalID == null || tzCanonicalID.length() == 0) {
            return;
        }
        // getGenericLocationName() formats a name and put it into the trie
        getGenericLocationName(tzCanonicalID); 

        // Generic partial location format
        Set<String> mzIDs = _tznames.getAvailableMetaZoneIDs(tzCanonicalID);
        for (String mzID : mzIDs) {
            // if this time zone is not the golden zone of the meta zone,
            // partial location name (such as "PT (Los Angeles)") might be
            // available.
            String goldenID = _tznames.getReferenceZoneID(mzID, getTargetRegion());
            if (!tzCanonicalID.equals(goldenID)) {
                for (NameType genNonLocType : GENERIC_NON_LOCATION_TYPES) {
                    String mzGenName = _tznames.getMetaZoneDisplayName(mzID, genNonLocType);
                    if (mzGenName != null) {
                        // getPartialLocationName() formats a name and put it into the trie
                        getPartialLocationName(tzCanonicalID, mzID, (genNonLocType == NameType.LONG_GENERIC), mzGenName);
                    }
                }
            }
        }
    }

    /**
     * Private method returning the target region. The target regions is determined by
     * the locale of this instance. When a generic name is coming from
     * a meta zone, this region is used for checking if the time zone
     * is a reference zone of the meta zone.
     * 
     * @return the target region
     */
    private synchronized String getTargetRegion() {
        if (_region == null) {
            _region = _locale.getCountry();
            if (_region.length() == 0) {
                ULocale tmp = ULocale.addLikelySubtags(_locale);
                _region = tmp.getCountry();
                if (_region.length() == 0) {
                    _region = "001";
                }
            }
        }
        return _region;
    }

    /**
     * Private method for formatting partial location names. This format
     * is used when a generic name of a meta zone is available, but the given
     * time zone is not a reference zone (golden zone) of the meta zone.
     * 
     * @param tzID the canonical time zone ID
     * @param mzID the meta zone ID
     * @param isLong true when long generic name
     * @param mzDisplayName the meta zone generic display name
     * @return the partial location format string
     */
    private String getPartialLocationName(String tzID, String mzID, boolean isLong, String mzDisplayName) {
        String letter = isLong ? "L" : "S";
        String key = tzID + "&" + mzID + "#" + letter;
        String name = _genericPartialLocationNamesMap.get(key);
        if (name != null) {
            return name;
        }
        String location = null;
        String countryCode = ZoneMeta.getCanonicalCountry(tzID);
        if (countryCode != null) {
            // Is this the golden zone for the region?
            String regionalGolden = _tznames.getReferenceZoneID(mzID, countryCode);
            if (tzID.equals(regionalGolden)) {
                // Use country name
                location = getLocaleDisplayNames().regionDisplayName(countryCode);
            } else {
                // Otherwise, use exemplar city name
                location = _tznames.getExemplarLocationName(tzID);
            }
        } else {
            location = _tznames.getExemplarLocationName(tzID);
            if (location == null) {
                // This could happen when the time zone is not associated with a country,
                // and its ID is not hierarchical, for example, CST6CDT.
                // We use the canonical ID itself as the location for this case.
                location = tzID;
            }
        }
        name = formatPattern(Pattern.FALLBACK_FORMAT, location, mzDisplayName);
        synchronized (this) {   // we have to sync the name map and the trie
            String tmp = _genericPartialLocationNamesMap.putIfAbsent(key.intern(), name.intern());
            if (tmp == null) {
                NameInfo info = new NameInfo();
                info.tzID = tzID.intern();
                info.type = isLong ? GenericNameType.LONG : GenericNameType.SHORT;
                _gnamesTrie.put(name, info);
            } else {
                name = tmp;
            }
        }
        return name;
    }

    /**
     * A private class used for storing the name information in the local trie.
     */
    private static class NameInfo {
        String tzID;
        GenericNameType type;
    }

    /**
     * A class used for returning the name search result used by
     * {@link TimeZoneGenericNames#find(String, int, EnumSet)}.
     */
    public static class GenericMatchInfo {
        GenericNameType nameType;
        String tzID;
        int matchLength;
        TimeType timeType = TimeType.UNKNOWN;

        public GenericNameType nameType() {
            return nameType;
        }

        public String tzID() {
            return tzID;
        }

        public TimeType timeType() {
            return timeType;
        }

        public int matchLength() {
            return matchLength;
        }
    }

    /**
     * A private class implementing the search callback interface in
     * <code>TextTrieMap</code> for collecting match results.
     */
    private static class GenericNameSearchHandler implements ResultHandler<NameInfo> {
        private EnumSet<GenericNameType> _types;
        private Collection<GenericMatchInfo> _matches;
        private int _maxMatchLen;

        GenericNameSearchHandler(EnumSet<GenericNameType> types) {
            _types = types;
        }

        /* (non-Javadoc)
         * @see com.ibm.icu.impl.TextTrieMap.ResultHandler#handlePrefixMatch(int, java.util.Iterator)
         */
        public boolean handlePrefixMatch(int matchLength, Iterator<NameInfo> values) {
            while (values.hasNext()) {
                NameInfo info = values.next();
                if (_types != null && !_types.contains(info.type)) {
                    continue;
                }
                GenericMatchInfo matchInfo = new GenericMatchInfo();
                matchInfo.tzID = info.tzID;
                matchInfo.nameType = info.type;
                matchInfo.matchLength = matchLength;
                //matchInfo.timeType = TimeType.UNKNOWN;
                if (_matches == null) {
                    _matches = new LinkedList<GenericMatchInfo>();
                }
                _matches.add(matchInfo);
                if (matchLength > _maxMatchLen) {
                    _maxMatchLen = matchLength;
                }
            }
            return true;
        }

        /**
         * Returns the match results
         * @return the match results
         */
        public Collection<GenericMatchInfo> getMatches() {
            return _matches;
        }

        /**
         * Returns the maximum match length, or 0 if no match was found
         * @return the maximum match length
         */
        public int getMaxMatchLen() {
            return _maxMatchLen;
        }

        /**
         * Resets the match results
         */
        public void resetResults() {
            _matches = null;
            _maxMatchLen = 0;
        }
    }

    /**
     * Returns the best match of time zone display name for the specified types in the
     * given text at the given offset.
     * @param text the text
     * @param start the start offset in the text
     * @param genericTypes the set of name types.
     * @return the best matching name info.
     */
    public GenericMatchInfo findBestMatch(String text, int start, EnumSet<GenericNameType> genericTypes) {
        if (text == null || text.length() == 0 || start < 0 || start >= text.length()) {
            throw new IllegalArgumentException("bad input text or range");
        }
        GenericMatchInfo bestMatch = null;

        // Find matches in the TimeZoneNames first
        Collection<MatchInfo> tznamesMatches = findTimeZoneNames(text, start, genericTypes);
        if (tznamesMatches != null) {
            MatchInfo longestMatch = null;
            for (MatchInfo match : tznamesMatches) {
                if (longestMatch == null || match.matchLength() > longestMatch.matchLength()) {
                    longestMatch = match;
                }
            }
            if (longestMatch != null) {
                bestMatch = createGenericMatchInfo(longestMatch);
                if (bestMatch.matchLength() == (text.length() - start)) {
                    // Full match
                    //return bestMatch;

                    // TODO Some time zone uses a same name for the long standard name
                    // and the location name. When the match is a long standard name,
                    // then we need to check if the name is same with the location name.
                    // This is probably a data error or a design bug.
//                    if (bestMatch.nameType != GenericNameType.LONG || bestMatch.timeType != TimeType.STANDARD) {
//                        return bestMatch;
//                    }

                    // TODO The deprecation of commonlyUsed flag introduced the name
                    // conflict not only for long standard names, but short standard names too.
                    // These short names (found in zh_Hant) should be gone once we clean
                    // up CLDR time zone display name data. Once the short name conflict
                    // problem (with location name) is resolved, we should change the condition
                    // below back to the original one above. -Yoshito (2011-09-14)
                    if (bestMatch.timeType != TimeType.STANDARD) {
                        return bestMatch;
                    }
                }
            }
        }

        // Find matches in the local trie
        Collection<GenericMatchInfo> localMatches = findLocal(text, start, genericTypes);
        if (localMatches != null) {
            for (GenericMatchInfo match : localMatches) {
                // TODO See the above TODO. We use match.matchLength() >= bestMatch.matcheLength()
                // for the reason described above.
                //if (bestMatch == null || match.matchLength() > bestMatch.matchLength()) {
                if (bestMatch == null || match.matchLength() >= bestMatch.matchLength()) {
                    bestMatch = match;
                }
            }
        }

        return bestMatch;
    }

    /**
     * Returns a collection of time zone display name matches for the specified types in the
     * given text at the given offset.
     * @param text the text
     * @param start the start offset in the text
     * @param genericTypes the set of name types.
     * @return A collection of match info.
     */
    public Collection<GenericMatchInfo> find(String text, int start, EnumSet<GenericNameType> genericTypes) {
        if (text == null || text.length() == 0 || start < 0 || start >= text.length()) {
            throw new IllegalArgumentException("bad input text or range");
        }
        // Find matches in the local trie
        Collection<GenericMatchInfo> results = findLocal(text, start, genericTypes);

        // Also find matches in the TimeZoneNames
        Collection<MatchInfo> tznamesMatches = findTimeZoneNames(text, start, genericTypes);
        if (tznamesMatches != null) {
            // transform matches and append them to local matches
            for (MatchInfo match : tznamesMatches) {
                if (results == null) {
                    results = new LinkedList<GenericMatchInfo>();
                }
                results.add(createGenericMatchInfo(match));
            }
        }
        return results;
    }

    /**
     * Returns a <code>GenericMatchInfo</code> for the given <code>MatchInfo</code>.
     * @param matchInfo the MatchInfo
     * @return A GenericMatchInfo
     */
    private GenericMatchInfo createGenericMatchInfo(MatchInfo matchInfo) {
        GenericNameType nameType = null;
        TimeType timeType = TimeType.UNKNOWN;
        switch (matchInfo.nameType()) {
        case LONG_STANDARD:
            nameType = GenericNameType.LONG;
            timeType = TimeType.STANDARD;
            break;
        case LONG_GENERIC:
            nameType = GenericNameType.LONG;
            break;
        case SHORT_STANDARD:
            nameType = GenericNameType.SHORT;
            timeType = TimeType.STANDARD;
            break;
        case SHORT_GENERIC:
            nameType = GenericNameType.SHORT;
            break;
        }
        assert(nameType != null);

        String tzID = matchInfo.tzID();
        if (tzID == null) {
            String mzID = matchInfo.mzID();
            assert(mzID != null);
            tzID = _tznames.getReferenceZoneID(mzID, getTargetRegion());
        }
        assert(tzID != null);

        GenericMatchInfo gmatch = new GenericMatchInfo();
        gmatch.nameType = nameType;
        gmatch.tzID = tzID;
        gmatch.matchLength = matchInfo.matchLength();
        gmatch.timeType = timeType;

        return gmatch;
    }

    /**
     * Returns a collection of time zone display name matches for the specified types in the
     * given text at the given offset. This method only finds matches from the TimeZoneNames
     * used by this object.
     * @param text the text
     * @param start the start offset in the text
     * @param types the set of name types.
     * @return A collection of match info.
     */
    private Collection<MatchInfo> findTimeZoneNames(String text, int start, EnumSet<GenericNameType> types) {
        Collection<MatchInfo> tznamesMatches = null;

        // Check if the target name type is really in the TimeZoneNames
        EnumSet<NameType> nameTypes = EnumSet.noneOf(NameType.class);
        if (types.contains(GenericNameType.LONG)) {
            nameTypes.add(NameType.LONG_GENERIC);
            nameTypes.add(NameType.LONG_STANDARD);
        }
        if (types.contains(GenericNameType.SHORT)) {
            nameTypes.add(NameType.SHORT_GENERIC);
            nameTypes.add(NameType.SHORT_STANDARD);
        }
        
        if (!nameTypes.isEmpty()) {
            // Find matches in the TimeZoneNames
            tznamesMatches = _tznames.find(text, start, nameTypes);
        }
        return tznamesMatches;
    }

    /**
     * Returns a collection of time zone display name matches for the specified types in the
     * given text at the given offset. This method only finds matches from the local trie,
     * that contains 1) generic location names and 2) long/short generic partial location names,
     * used by this object.
     * @param text the text
     * @param start the start offset in the text
     * @param types the set of name types.
     * @return A collection of match info.
     */
    private synchronized Collection<GenericMatchInfo> findLocal(String text, int start, EnumSet<GenericNameType> types) {
        GenericNameSearchHandler handler = new GenericNameSearchHandler(types);
        _gnamesTrie.find(text, start, handler);
        if (handler.getMaxMatchLen() == (text.length() - start) || _gnamesTrieFullyLoaded) {
            // perfect match
            return handler.getMatches();
        }

        // All names are not yet loaded into the local trie.
        // Load all available names into the trie. This could be very heavy.

        Set<String> tzIDs = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, null, null);
        for (String tzID : tzIDs) {
            loadStrings(tzID);
        }
        _gnamesTrieFullyLoaded = true;

        // now, try it again
        handler.resetResults();
        _gnamesTrie.find(text, start, handler);
        return handler.getMatches();
    }

    /**
     * <code>TimeZoneGenericNames</code> cache implementation.
     */
    private static class Cache extends SoftCache<String, TimeZoneGenericNames, ULocale> {

        /* (non-Javadoc)
         * @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object)
         */
        @Override
        protected TimeZoneGenericNames createInstance(String key, ULocale data) {
            return new TimeZoneGenericNames(data).freeze();
        }
        
    }

    /*
     * The custom deserialization method.
     * This implementation only read locale used by the object.
     */
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        init();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isFrozen() {
        return _frozen;
    }

    /**
     * {@inheritDoc}
     */
    public TimeZoneGenericNames freeze() {
        _frozen = true;
        return this;
    }

    /**
     * {@inheritDoc}
     */
    public TimeZoneGenericNames cloneAsThawed() {
        TimeZoneGenericNames copy = null;
        try {
            copy = (TimeZoneGenericNames)super.clone();
            copy._frozen = false;
        } catch (Throwable t) {
            // This should never happen
        }
        return copy;
    }
}
