// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
 *******************************************************************************
 * Copyright (C) 2001-2013, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.util;

import java.text.Collator;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.EventListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.ICULocaleService;
import com.ibm.icu.impl.ICULocaleService.ICUResourceBundleFactory;
import com.ibm.icu.impl.ICULocaleService.LocaleKey;
import com.ibm.icu.impl.ICULocaleService.LocaleKeyFactory;
import com.ibm.icu.impl.ICUNotifier;
import com.ibm.icu.impl.ICURWLock;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.ICUService;
import com.ibm.icu.impl.ICUService.Factory;
import com.ibm.icu.impl.ICUService.Key;
import com.ibm.icu.impl.ICUService.ServiceListener;
import com.ibm.icu.impl.ICUService.SimpleFactory;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.util.ULocale;

@RunWith(JUnit4.class)
public class ICUServiceTest extends TestFmwk
{
    private String lrmsg(String message, Object lhs, Object rhs) {
    return message + " lhs: " + lhs + " rhs: " + rhs;
    }

    public void confirmBoolean(String message, boolean val) {
    msg(message, val ? LOG : ERR, !val, true);
    }

    public void confirmEqual(String message, Object lhs, Object rhs) {
        msg(lrmsg(message, lhs, rhs), (lhs == null ? rhs == null : lhs.equals(rhs)) ? LOG : ERR, true, true);
    }

    public void confirmIdentical(String message, Object lhs, Object rhs) {
    msg(lrmsg(message, lhs, rhs), lhs == rhs ? LOG : ERR, true, true);
    }

    public void confirmIdentical(String message, int lhs, int rhs) {
    msg(message + " lhs: " + lhs + " rhs: " + rhs, lhs == rhs ? LOG : ERR, true, true);
    }

    /**
     * Convenience override of getDisplayNames(ULocale, Comparator, String) that
     * uses the current default ULocale as the locale, the default collator for
     * the locale as the comparator to sort the display names, and null for
     * the matchID.
     */
    public SortedMap getDisplayNames(ICUService service) {
        ULocale locale = ULocale.getDefault();
        Collator col = Collator.getInstance(locale.toLocale());
        return service.getDisplayNames(locale, col, null);
    }

    /**
     * Convenience override of getDisplayNames(ULocale, Comparator, String) that
     * uses the default collator for the locale as the comparator to
     * sort the display names, and null for the matchID.
     */
    public SortedMap getDisplayNames(ICUService service, ULocale locale) {
        Collator col = Collator.getInstance(locale.toLocale());
        return service.getDisplayNames(locale, col, null);
    }
    /**
     * Convenience override of getDisplayNames(ULocale, Comparator, String) that
     * uses the default collator for the locale as the comparator to
     * sort the display names.
     */
    public SortedMap getDisplayNames(ICUService service, ULocale locale, String matchID) {
        Collator col = Collator.getInstance(locale.toLocale());
        return service.getDisplayNames(locale, col, matchID);
    }

    // use locale keys
    static final class TestService extends ICUService {
        public TestService() {
            super("Test Service");
        }

    @Override
    public Key createKey(String id) {
        return LocaleKey.createWithCanonicalFallback(id, null); // no fallback locale
    }
    }

    @Test
    public void TestAPI() {
    // create a service using locale keys,
    ICUService service = new TestService();

        logln("service name:" + service.getName());

    // register an object with one locale,
    // search for an object with a more specific locale
    // should return the original object
    Integer singleton0 = new Integer(0);
    service.registerObject(singleton0, "en_US");
    Object result = service.get("en_US_FOO");
    confirmIdentical("1) en_US_FOO -> en_US", result, singleton0);

    // register a new object with the more specific locale
    // search for an object with that locale
    // should return the new object
    Integer singleton1 = new Integer(1);
    service.registerObject(singleton1, "en_US_FOO");
    result = service.get("en_US_FOO");
    confirmIdentical("2) en_US_FOO -> en_US_FOO", result, singleton1);

    // search for an object that falls back to the first registered locale
    result = service.get("en_US_BAR");
    confirmIdentical("3) en_US_BAR -> en_US", result, singleton0);

    // get a list of the factories, should be two
    List factories = service.factories();
    confirmIdentical("4) factory size", factories.size(), 2);

    // register a new object with yet another locale
    // original factory list is unchanged
    Integer singleton2 = new Integer(2);
    service.registerObject(singleton2, "en");
    confirmIdentical("5) factory size", factories.size(), 2);

    // search for an object with the new locale
    // stack of factories is now en, en_US_FOO, en_US
    // search for en_US should still find en_US object
    result = service.get("en_US_BAR");
    confirmIdentical("6) en_US_BAR -> en_US", result, singleton0);

    // register a new object with an old id, should hide earlier factory using this id, but leave it there
    Integer singleton3 = new Integer(3);
    service.registerObject(singleton3, "en_US");
    factories = service.factories();
    confirmIdentical("9) factory size", factories.size(), 4);

    // should get data from that new factory
    result = service.get("en_US_BAR");
    confirmIdentical("10) en_US_BAR -> (3)", result, singleton3);

    // remove new factory
    // should have fewer factories again
    service.unregisterFactory((Factory)factories.get(0));
    factories = service.factories();
    confirmIdentical("11) factory size", factories.size(), 3);

    // should get original data again after remove factory
    result = service.get("en_US_BAR");
    confirmIdentical("12) en_US_BAR -> 0", result, singleton0);

    // shouldn't find unregistered ids
    result = service.get("foo");
    confirmIdentical("13) foo -> null", result, null);

    // should find non-canonical strings
    String[] resultID = new String[1];
    result = service.get("EN_us_fOo", resultID);
    confirmEqual("14) find non-canonical", resultID[0], "en_US_FOO");

    // should be able to register non-canonical strings and get them canonicalized
    service.registerObject(singleton3, "eN_ca_dUde");
    result = service.get("En_Ca_DuDe", resultID);
    confirmEqual("15) register non-canonical", resultID[0], "en_CA_DUDE");

    // should be able to register invisible factories, these will not
    // be visible by default, but if you know the secret password you
    // can still access these services...
    Integer singleton4 = new Integer(4);
    service.registerObject(singleton4, "en_US_BAR", false);
    result = service.get("en_US_BAR");
    confirmIdentical("17) get invisible", result, singleton4);

    // should not be able to locate invisible services
    Set ids = service.getVisibleIDs();
    confirmBoolean("18) find invisible", !ids.contains("en_US_BAR"));

    service.reset();
    // an anonymous factory than handles all ids
    {
        Factory factory = new Factory() {
            @Override
            public Object create(Key key, ICUService unusedService) {
                return new ULocale(key.currentID());
            }

            @Override
            public void updateVisibleIDs(Map unusedResult) {
            }

            @Override
            public String getDisplayName(String id, ULocale l) {
                return null;
            }
        };
        service.registerFactory(factory);

        // anonymous factory will still handle the id
        result = service.get(ULocale.US.toString());
        confirmEqual("21) locale", result, ULocale.US);

        // still normalizes id
        result = service.get("EN_US_BAR");
        confirmEqual("22) locale", result, new ULocale("en_US_BAR"));

        // we can override for particular ids
        service.registerObject(singleton3, "en_US_BAR");
        result = service.get("en_US_BAR");
        confirmIdentical("23) override super", result, singleton3);

    }

    // empty service should not recognize anything
    service.reset();
    result = service.get("en_US");
    confirmIdentical("24) empty", result, null);

    // create a custom multiple key factory
    {
        String[] xids = { "en_US_VALLEY_GIRL",
                  "en_US_VALLEY_BOY",
                  "en_US_SURFER_GAL",
                  "en_US_SURFER_DUDE"
        };
        service.registerFactory(new TestLocaleKeyFactory(xids, "Later"));
    }

    // iterate over the visual ids returned by the multiple factory
    {
        Set vids = service.getVisibleIDs();
        Iterator iter = vids.iterator();
        int count = 0;
        while (iter.hasNext()) {
        ++count;
                String id = (String)iter.next();
        logln("  " + id + " --> " + service.get(id));
        }
        // four visible ids
        confirmIdentical("25) visible ids", count, 4);
    }

    // iterate over the display names
    {
        Map dids = getDisplayNames(service, ULocale.GERMANY);
        Iterator iter = dids.entrySet().iterator();
        int count = 0;
        while (iter.hasNext()) {
        ++count;
        Entry e = (Entry)iter.next();
        logln("  " + e.getKey() + " -- > " + e.getValue());
        }
        // four display names, in german
        confirmIdentical("26) display names", count, 4);
    }

    // no valid display name
    confirmIdentical("27) get display name", service.getDisplayName("en_US_VALLEY_GEEK"), null);

    {
        String name = service.getDisplayName("en_US_SURFER_DUDE", ULocale.US);
        confirmEqual("28) get display name", name, "English (United States, SURFER_DUDE)");
    }

    // register another multiple factory
    {
        String[] xids = {
        "en_US_SURFER", "en_US_SURFER_GAL", "en_US_SILICON", "en_US_SILICON_GEEK"
        };
        service.registerFactory(new TestLocaleKeyFactory(xids, "Rad dude"));
    }

    // this time, we have seven display names
        // Rad dude's surfer gal 'replaces' later's surfer gal
    {
        Map dids = getDisplayNames(service);
        Iterator iter = dids.entrySet().iterator();
        int count = 0;
        while (iter.hasNext()) {
        ++count;
        Entry e = (Entry)iter.next();
        logln("  " + e.getKey() + " --> " + e.getValue());
        }
        // seven display names, in spanish
        confirmIdentical("29) display names", count, 7);
    }

    // we should get the display name corresponding to the actual id
    // returned by the id we used.
    {
        String[] actualID = new String[1];
        String id = "en_us_surfer_gal";
        String gal = (String)service.get(id, actualID);
        if (gal != null) {
                logln("actual id: " + actualID[0]);
        String displayName = service.getDisplayName(actualID[0], ULocale.US);
        logln("found actual: " + gal + " with display name: " + displayName);
        confirmBoolean("30) found display name for actual", displayName != null);

        displayName = service.getDisplayName(id, ULocale.US);
        logln("found query: " + gal + " with display name: " + displayName);
        // this is no longer a bug, we want to return display names for anything
        // that a factory handles.  since we handle it, we should return a display
        // name.  see jb3549
        // confirmBoolean("31) found display name for query", displayName == null);
        } else {
        errln("30) service could not find entry for " + id);
        }

            // this should be handled by the 'dude' factory, since it overrides en_US_SURFER.
        id = "en_US_SURFER_BOZO";
        String bozo = (String)service.get(id, actualID);
        if (bozo != null) {
        String displayName = service.getDisplayName(actualID[0], ULocale.US);
        logln("found actual: " + bozo + " with display name: " + displayName);
        confirmBoolean("32) found display name for actual", displayName != null);

        displayName = service.getDisplayName(id, ULocale.US);
        logln("found actual: " + bozo + " with display name: " + displayName);
        // see above and jb3549
        // confirmBoolean("33) found display name for query", displayName == null);
        } else {
        errln("32) service could not find entry for " + id);
        }

            confirmBoolean("34) is default ", !service.isDefault());
    }

        /*
      // disallow hiding for now

      // hiding factory should obscure 'sublocales'
      {
      String[] xids = {
      "en_US_VALLEY", "en_US_SILICON"
      };
      service.registerFactory(new TestHidingFactory(xids, "hiding"));
      }

      {
      Map dids = service.getDisplayNames();
      Iterator iter = dids.entrySet().iterator();
      int count = 0;
      while (iter.hasNext()) {
      ++count;
      Entry e = (Entry)iter.next();
      logln("  " + e.getKey() + " -- > " + e.getValue());
      }
      confirmIdentical("35) hiding factory", count, 5);
      }
        */

    {
        Set xids = service.getVisibleIDs();
        Iterator iter = xids.iterator();
        while (iter.hasNext()) {
        String xid = (String)iter.next();
        logln(xid + "?  " + service.get(xid));
        }

        logln("valleygirl?  " + service.get("en_US_VALLEY_GIRL"));
        logln("valleyboy?   " + service.get("en_US_VALLEY_BOY"));
        logln("valleydude?  " + service.get("en_US_VALLEY_DUDE"));
        logln("surfergirl?  " + service.get("en_US_SURFER_GIRL"));
    }

    // resource bundle factory.
    service.reset();
    service.registerFactory(new ICUResourceBundleFactory());

    // list all of the resources
    {
            logln("all visible ids: " + service.getVisibleIDs());
            /*
          Set xids = service.getVisibleIDs();
          StringBuffer buf = new StringBuffer("{");
          boolean notfirst = false;
          Iterator iter = xids.iterator();
          while (iter.hasNext()) {
          String xid = (String)iter.next();
          if (notfirst) {
          buf.append(", ");
          } else {
          notfirst = true;
          }
          buf.append(xid);
          }
          buf.append("}");
          logln(buf.toString());
            */
    }

        // list only the resources for es, default locale
        // since we're using the default Key, only "es" is matched
        {
            logln("visible ids for es locale: " + service.getVisibleIDs("es"));
        }

        // list only the spanish display names for es, spanish collation order
        // since we're using the default Key, only "es" is matched
        {
            logln("display names: " + getDisplayNames(service, new ULocale("es"), "es"));
        }

        // list the display names in reverse order
        {
            logln("display names in reverse order: " +
                  service.getDisplayNames(ULocale.US, new Comparator() {
                          @Override
                        public int compare(Object lhs, Object rhs) {
                              return -String.CASE_INSENSITIVE_ORDER.compare((String)lhs, (String)rhs);
                          }
                      }));
        }

    // get all the display names of these resources
    // this should be fast since the display names were cached.
    {
            logln("service display names for de_DE");
        Map names = getDisplayNames(service, new ULocale("de_DE"));
        StringBuffer buf = new StringBuffer("{");
        Iterator iter = names.entrySet().iterator();
        while (iter.hasNext()) {
        Entry e = (Entry)iter.next();
        String name = (String)e.getKey();
        String id = (String)e.getValue();
        buf.append("\n   " + name + " --> " + id);
        }
        buf.append("\n}");
        logln(buf.toString());
    }

        CalifornioLanguageFactory califactory = new CalifornioLanguageFactory();
        service.registerFactory(califactory);
    // get all the display names of these resources
    {
            logln("californio language factory");
        StringBuffer buf = new StringBuffer("{");
            String[] idNames = {
                CalifornioLanguageFactory.californio,
        CalifornioLanguageFactory.valley,
        CalifornioLanguageFactory.surfer,
        CalifornioLanguageFactory.geek
            };
            for (int i = 0; i < idNames.length; ++i) {
                String idName = idNames[i];
                buf.append("\n  --- " + idName + " ---");
                Map names = getDisplayNames(service, new ULocale(idName));
                Iterator iter = names.entrySet().iterator();
                while (iter.hasNext()) {
                    Entry e = (Entry)iter.next();
                    String name = (String)e.getKey();
                    String id = (String)e.getValue();
                    buf.append("\n    " + name + " --> " + id);
                }
        }
        buf.append("\n}");
        logln(buf.toString());
    }

    // test notification
    // simple registration
    {
            logln("simple registration notification");
        ICULocaleService ls = new ICULocaleService();
        ServiceListener l1 = new ServiceListener() {
            private int n;
            @Override
            public void serviceChanged(ICUService s) {
            logln("listener 1 report " + n++ + " service changed: " + s);
            }
        };
        ls.addListener(l1);
        ServiceListener l2 = new ServiceListener() {
            private int n;
            @Override
            public void serviceChanged(ICUService s) {
            logln("listener 2 report " + n++ + " service changed: " + s);
            }
        };
        ls.addListener(l2);
        logln("registering foo... ");
        ls.registerObject("Foo", "en_FOO");
        logln("registering bar... ");
        ls.registerObject("Bar", "en_BAR");
        logln("getting foo...");
        logln((String)ls.get("en_FOO"));
        logln("removing listener 2...");
        ls.removeListener(l2);
        logln("registering baz...");
        ls.registerObject("Baz", "en_BAZ");
        logln("removing listener 1");
        ls.removeListener(l1);
        logln("registering burp...");
        ls.registerObject("Burp", "en_BURP");

        // should only get one notification even if register multiple times
        logln("... trying multiple registration");
        ls.addListener(l1);
        ls.addListener(l1);
        ls.addListener(l1);
        ls.addListener(l2);
        ls.registerObject("Foo", "en_FOO");
        logln("... registered foo");

        // since in a separate thread, we can callback and not deadlock
        ServiceListener l3 = new ServiceListener() {
            private int n;
            @Override
            public void serviceChanged(ICUService s) {
            logln("listener 3 report " + n++ + " service changed...");
            if (s.get("en_BOINK") == null) { // don't recurse on ourselves!!!
                logln("registering boink...");
                s.registerObject("boink", "en_BOINK");
            }
            }
        };
        ls.addListener(l3);
        logln("registering boo...");
        ls.registerObject("Boo", "en_BOO");
        logln("...done");

        try {
        Thread.sleep(100);
        }
        catch (InterruptedException e) {
        }
    }
    }

    static class TestLocaleKeyFactory extends LocaleKeyFactory {
    protected final Set ids;
    protected final String factoryID;

    public TestLocaleKeyFactory(String[] ids, String factoryID) {
            super(VISIBLE, factoryID);

        this.ids = Collections.unmodifiableSet(new HashSet(Arrays.asList(ids)));
            this.factoryID = factoryID + ": ";
    }

    @Override
    protected Object handleCreate(ULocale loc, int kind, ICUService service) {
            return factoryID + loc.toString();
    }

    @Override
    protected Set getSupportedIDs() {
            return ids;
    }
    }

    /*
      // Disallow hiding for now since it causes gnarly problems, like
      // how do you localize the hidden (but still exported) names.

      static class TestHidingFactory implements ICUService.Factory {
      protected final String[] ids;
      protected final String factoryID;

      public TestHidingFactory(String[] ids) {
      this(ids, "Hiding");
      }

      public TestHidingFactory(String[] ids, String factoryID) {
      this.ids = (String[])ids.clone();

      if (factoryID == null || factoryID.length() == 0) {
      this.factoryID = "";
      } else {
      this.factoryID = factoryID + ": ";
      }
      }

      public Object create(Key key, ICUService service) {
      for (int i = 0; i < ids.length; ++i) {
      if (LocaleUtility.isFallbackOf(ids[i], key.currentID())) {
      return factoryID + key.canonicalID();
      }
      }
      return null;
      }

      public void updateVisibleIDs(Map result) {
      for (int i = 0; i < ids.length; ++i) {
      String id = ids[i];
      Iterator iter = result.keySet().iterator();
      while (iter.hasNext()) {
      if (LocaleUtility.isFallbackOf(id, (String)iter.next())) {
      iter.remove();
      }
      }
      result.put(id, this);
      }
      }

      public String getDisplayName(String id, ULocale locale) {
      return factoryID + new ULocale(id).getDisplayName(locale);
      }
      }
    */

    static class CalifornioLanguageFactory extends ICUResourceBundleFactory {
    public static String californio = "en_US_CA";
    public static String valley = californio + "_VALLEY";
    public static String surfer = californio + "_SURFER";
    public static String geek = californio + "_GEEK";
        public static Set supportedIDs;
        static {
            HashSet result = new HashSet();
            result.addAll(ICUResourceBundle.getAvailableLocaleNameSet());
        result.add(californio);
        result.add(valley);
        result.add(surfer);
        result.add(geek);
            supportedIDs = Collections.unmodifiableSet(result);
        }

    @Override
    public Set getSupportedIDs() {
            return supportedIDs;
    }

    @Override
    public String getDisplayName(String id, ULocale locale) {
        String prefix = "";
        String suffix = "";
        String ls = locale.toString();
        if (LocaleUtility.isFallbackOf(californio, ls)) {
        if (ls.equalsIgnoreCase(valley)) {
            prefix = "Like, you know, it's so totally ";
        } else if (ls.equalsIgnoreCase(surfer)) {
            prefix = "Dude, its ";
        } else if (ls.equalsIgnoreCase(geek)) {
            prefix = "I'd estimate it's approximately ";
        } else {
            prefix = "Huh?  Maybe ";
        }
        }
        if (LocaleUtility.isFallbackOf(californio, id)) {
        if (id.equalsIgnoreCase(valley)) {
            suffix = "like the Valley, you know?  Let's go to the mall!";
        } else if (id.equalsIgnoreCase(surfer)) {
            suffix = "time to hit those gnarly waves, Dude!!!";
        } else if (id.equalsIgnoreCase(geek)) {
            suffix = "all systems go.  T-Minus 9, 8, 7...";
        } else {
            suffix = "No Habla Englais";
        }
        } else {
        suffix = super.getDisplayName(id, locale);
        }

        return prefix + suffix;
    }
    }

    @Test
    public void TestLocale() {
    ICULocaleService service = new ICULocaleService("test locale");
    service.registerObject("root", ULocale.ROOT);
    service.registerObject("german", "de");
    service.registerObject("german_Germany", ULocale.GERMANY);
    service.registerObject("japanese", "ja");
    service.registerObject("japanese_Japan", ULocale.JAPAN);

    Object target = service.get("de_US");
    confirmEqual("test de_US", "german", target);

        ULocale de = new ULocale("de");
        ULocale de_US = new ULocale("de_US");

        target = service.get(de_US);
    confirmEqual("test de_US 2", "german", target);

        target = service.get(de_US, LocaleKey.KIND_ANY);
    confirmEqual("test de_US 3", "german", target);

        target = service.get(de_US, 1234);
    confirmEqual("test de_US 4", "german", target);

        ULocale[] actualReturn = new ULocale[1];
        target = service.get(de_US, actualReturn);
        confirmEqual("test de_US 5", "german", target);
        confirmEqual("test de_US 6", actualReturn[0], de);

        actualReturn[0] = null;
        target = service.get(de_US, LocaleKey.KIND_ANY, actualReturn);
        confirmEqual("test de_US 7", actualReturn[0], de);

        actualReturn[0] = null;
        target = service.get(de_US, 1234, actualReturn);
    confirmEqual("test de_US 8", "german", target);
        confirmEqual("test de_US 9", actualReturn[0], de);

        service.registerObject("one/de_US", de_US, 1);
        service.registerObject("two/de_US", de_US, 2);

        target = service.get(de_US, 1);
        confirmEqual("test de_US kind 1", "one/de_US", target);

        target = service.get(de_US, 2);
        confirmEqual("test de_US kind 2", "two/de_US", target);

        target = service.get(de_US);
        confirmEqual("test de_US kind 3", "german", target);

        LocaleKey lkey = LocaleKey.createWithCanonicalFallback("en", null, 1234);
        logln("lkey prefix: " + lkey.prefix());
        logln("lkey descriptor: " + lkey.currentDescriptor());
        logln("lkey current locale: " + lkey.currentLocale());

        lkey.fallback();
        logln("lkey descriptor 2: " + lkey.currentDescriptor());

        lkey.fallback();
        logln("lkey descriptor 3: " + lkey.currentDescriptor());

    target = service.get("za_PPP");
    confirmEqual("test zappp", "root", target);

    ULocale loc = ULocale.getDefault();
    ULocale.setDefault(ULocale.JAPANESE);
    target = service.get("za_PPP");
    confirmEqual("test with ja locale", "japanese", target);

    Set ids = service.getVisibleIDs();
    for (Iterator iter = ids.iterator(); iter.hasNext();) {
        logln("id: " + iter.next());
    }

    ULocale.setDefault(loc);
    ids = service.getVisibleIDs();
    for (Iterator iter = ids.iterator(); iter.hasNext();) {
        logln("id: " + iter.next());
    }

    target = service.get("za_PPP");
    confirmEqual("test with en locale", "root", target);

        ULocale[] locales = service.getAvailableULocales();
        confirmIdentical("test available locales", locales.length, 6);
        logln("locales: ");
        for (int i = 0; i < locales.length; ++i) {
            log("\n  [" + i + "] " + locales[i]);
        }
        logln(" ");

        service.registerFactory(new ICUResourceBundleFactory());
        target = service.get(ULocale.JAPAN);

        {
            int n = 0;
            List factories = service.factories();
            Iterator iter = factories.iterator();
            while (iter.hasNext()) {
                logln("[" + n++ + "] " + iter.next());
            }
        }

        // list only the english display names for es, in reverse order
        // since we're using locale keys, we should get all and only the es locales
        // hmmm, the default toString function doesn't print in sorted order for TreeMap
        {
            SortedMap map = service.getDisplayNames(ULocale.US,
                            new Comparator() {
                                @Override
                                public int compare(Object lhs, Object rhs) {
                                return -String.CASE_INSENSITIVE_ORDER.compare((String)lhs, (String)rhs);
                                }
                            },
                            "es");

            logln("es display names in reverse order " + map);
        }
    }

    @Test
    public void TestWrapFactory() {
        final String greeting = "Hello There";
        final String greetingID = "greeting";

        ICUService service = new ICUService("wrap");
        service.registerObject(greeting, greetingID);

        logln("test one: " + service.get(greetingID));

        class WrapFactory implements Factory {
            @Override
            public Object create(Key key, ICUService serviceArg) {
                if (key.currentID().equals(greetingID)) {
                    Object previous = serviceArg.getKey(key, null, this);
                    return "A different greeting: \"" + previous + "\"";
                }
                return null;
            }

            @Override
            public void updateVisibleIDs(Map result) {
                result.put("greeting", this);
            }

            @Override
            public String getDisplayName(String id, ULocale locale) {
                return "wrap '" + id + "'";
            }
        }
        service.registerFactory(new WrapFactory());

        confirmEqual("wrap test: ", service.get(greetingID), "A different greeting: \"" + greeting + "\"");
    }

    // misc coverage tests
    @Test
    public void TestCoverage() {
    // Key
    Key key = new Key("foobar");
    logln("ID: " + key.id());
    logln("canonicalID: " + key.canonicalID());
    logln("currentID: " + key.currentID());
    logln("has fallback: " + key.fallback());

    // SimpleFactory
    Object obj = new Object();
    SimpleFactory sf = new SimpleFactory(obj, "object");
    try {
        sf = new SimpleFactory(null, null);
        errln("didn't throw exception");
    }
    catch (IllegalArgumentException e) {
        logln("OK: " + e.getMessage());
    }
    catch (Exception e) {
        errln("threw wrong exception" + e);
    }
    logln(sf.getDisplayName("object", null));

    // ICUService
    ICUService service = new ICUService();
    service.registerFactory(sf);

    try {
        service.get(null, null);
        errln("didn't throw exception");
    }
    catch (NullPointerException e) {
        logln("OK: " + e.getMessage());
    }
        /*
      catch (Exception e) {
      errln("threw wrong exception" + e);
      }
        */
    try {
        service.registerFactory(null);
        errln("didn't throw exception");
    }
    catch (NullPointerException e) {
        logln("OK: " + e.getMessage());
    }
    catch (Exception e) {
        errln("threw wrong exception" + e);
    }

    try {
        service.unregisterFactory(null);
        errln("didn't throw exception");
    }
    catch (NullPointerException e) {
        logln("OK: " + e.getMessage());
    }
    catch (Exception e) {
        errln("threw wrong exception" + e);
    }

    logln("object is: " + service.get("object"));

    logln("stats: " + service.stats());

    // ICURWLock

    ICURWLock rwlock = new ICURWLock();
    rwlock.resetStats();

    rwlock.acquireRead();
    rwlock.releaseRead();

    rwlock.acquireWrite();
    rwlock.releaseWrite();
    logln("stats: " + rwlock.getStats());
    logln("stats: " + rwlock.clearStats());
    rwlock.acquireRead();
    rwlock.releaseRead();
    rwlock.acquireWrite();
    rwlock.releaseWrite();
    logln("stats: " + rwlock.getStats());

    try {
        rwlock.releaseRead();
        errln("no error thrown");
    }
    catch (Exception e) {
        logln("OK: " + e.getMessage());
    }

    try {
        rwlock.releaseWrite();
        errln("no error thrown");
    }
    catch (Exception e) {
        logln("OK: " + e.getMessage());
    }

        // ICULocaleService

    // LocaleKey

    // LocaleKey lkey = LocaleKey.create("en_US", "ja_JP");
    // lkey = LocaleKey.create(null, null);
    LocaleKey lkey = LocaleKey.createWithCanonicalFallback("en_US", "ja_JP");
        logln("lkey: " + lkey);

        lkey = LocaleKey.createWithCanonicalFallback(null, null);
        logln("lkey from null,null: " + lkey);

    // LocaleKeyFactory
    LocaleKeyFactory lkf = new LKFSubclass(false);
        logln("lkf: " + lkf);
    logln("obj: " + lkf.create(lkey, null));
    logln(lkf.getDisplayName("foo", null));
    logln(lkf.getDisplayName("bar", null));
    lkf.updateVisibleIDs(new HashMap());

    LocaleKeyFactory invisibleLKF = new LKFSubclass(false);
    logln("obj: " + invisibleLKF.create(lkey, null));
    logln(invisibleLKF.getDisplayName("foo", null));
    logln(invisibleLKF.getDisplayName("bar", null));
    invisibleLKF.updateVisibleIDs(new HashMap());

    // ResourceBundleFactory
    ICUResourceBundleFactory rbf = new ICUResourceBundleFactory();
    logln("RB: " + rbf.create(lkey, null));

    // ICUNotifier
    ICUNotifier nf = new ICUNSubclass();
    try {
        nf.addListener(null);
        errln("added null listener");
    }
    catch (NullPointerException e) {
        logln(e.getMessage());
    }
    catch (Exception e) {
        errln("got wrong exception");
    }

    try {
        nf.addListener(new WrongListener());
        errln("added wrong listener");
    }
    catch (IllegalStateException e) {
        logln(e.getMessage());
    }
    catch (Exception e) {
        errln("got wrong exception");
    }

    try {
        nf.removeListener(null);
        errln("removed null listener");
    }
    catch (NullPointerException e) {
        logln(e.getMessage());
    }
    catch (Exception e) {
        errln("got wrong exception");
    }

    nf.removeListener(new MyListener());
    nf.notifyChanged();
    nf.addListener(new MyListener());
    nf.removeListener(new MyListener());
    }

    static class MyListener implements EventListener {
    }

    static class WrongListener implements EventListener {
    }

    static class ICUNSubclass extends ICUNotifier {
        @Override
        public boolean acceptsListener(EventListener l) {
            return l instanceof MyListener;
        }

        // not used, just needed to implement abstract base
        @Override
        public void notifyListener(EventListener l) {
        }
    }

    static class LKFSubclass extends LocaleKeyFactory {
    LKFSubclass(boolean visible) {
        super(visible ? VISIBLE : INVISIBLE);
    }

    @Override
    protected Set getSupportedIDs() {
            return Collections.EMPTY_SET;
    }
    }
}
