/**
 *******************************************************************************
 * Copyright (C) 2001-2002, International Business Machines Corporation.       *
 * All Rights Reserved.                                                        *
 *******************************************************************************
 */

#ifndef ICUSERV_H
#define ICUSERV_H

#include "unicode/utypes.h"

#if UCONFIG_NO_SERVICE

U_NAMESPACE_BEGIN

/*
 * Allow the declaration of APIs with pointers to ICUService
 * even when service is removed from the build.
 */
class ICUService;

U_NAMESPACE_END

#else

#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "unicode/chariter.h"
#include "unicode/locid.h"
#include "unicode/ubrk.h"

#include "hash.h"
#include "uvector.h"
#include "icunotif.h"

U_NAMESPACE_BEGIN

class ICUServiceKey;
class ICUServiceFactory;
class SimpleFactory;
class ServiceListener;
class ICUServiceEnumeration;
class ICUService;
class ICUServiceTest;

class DNCache;

/*******************************************************************
 * ICUServiceKey
 */

/**
 * <p>ICUServiceKeys are used to communicate with factories to
 * generate an instance of the service.  ICUServiceKeys define how
 * ids are canonicalized, provide both a current id and a current
 * descriptor to use in querying the cache and factories, and
 * determine the fallback strategy.</p>
 *
 * <p>ICUServiceKeys provide both a currentDescriptor and a currentID.
 * The descriptor contains an optional prefix, followed by '/'
 * and the currentID.  Factories that handle complex keys,
 * for example number format factories that generate multiple
 * kinds of formatters for the same locale, use the descriptor 
 * to provide a fully unique identifier for the service object, 
 * while using the currentID (in this case, the locale string),
 * as the visible IDs that can be localized.</p>
 *
 * <p>The default implementation of ICUServiceKey has no fallbacks and
 * has no custom descriptors.</p> 
 */
class U_COMMON_API ICUServiceKey : public UObject {
 private: 
  const UnicodeString _id;

 protected:
  static const UChar PREFIX_DELIMITER;

 public:

  /**
   * <p>Construct a key from an id.</p>
   *
   * @param id the ID from which to construct the key.
   */
  ICUServiceKey(const UnicodeString& id);

  /**
   * <p>Virtual destructor.</p>
   */
  virtual ~ICUServiceKey();

 /**
  * <p>Return the original ID used to construct this key.</p>
  *
  * @return the ID used to construct this key.
  */
  virtual const UnicodeString& getID() const;

 /**
  * <p>Return the canonical version of the original ID.  This implementation
  * appends the original ID to result.  Result is returned as a convenience.</p>
  *
  * @param result the output parameter to which the id will be appended.
  * @return the modified result.
  */
  virtual UnicodeString& canonicalID(UnicodeString& result) const;

 /**
  * <p>Return the (canonical) current ID.  This implementation appends
  * the canonical ID to result.  Result is returned as a convenience.</p>
  *
  * @param result the output parameter to which the current id will be appended.
  * @return the modified result.  
  */
  virtual UnicodeString& currentID(UnicodeString& result) const;

 /**
  * <p>Return the current descriptor.  This implementation appends
  * the current descriptor to result.  Result is returned as a convenience.</p>
  *
  * <p>The current descriptor is used to fully
  * identify an instance of the service in the cache.  A
  * factory may handle all descriptors for an ID, or just a
  * particular descriptor.  The factory can either parse the
  * descriptor or use custom API on the key in order to
  * instantiate the service.</p>
  *
  * @param result the output parameter to which the current id will be appended.
  * @return the modified result.  
  */
  virtual UnicodeString& currentDescriptor(UnicodeString& result) const;

 /**
  * <p>If the key has a fallback, modify the key and return true,
  * otherwise return false.  The current ID will change if there
  * is a fallback.  No currentIDs should be repeated, and fallback
  * must eventually return false.  This implementation has no fallbacks
  * and always returns false.</p>
  *
  * @return TRUE if the ICUServiceKey changed to a valid fallback value.
  */
  virtual UBool fallback();

 /**
  * <p>Return TRUE if a key created from id matches, or would eventually
  * fallback to match, the canonical ID of this ICUServiceKey.</p>
  *
  * @param id the id to test.
  * @return TRUE if this ICUServiceKey's canonical ID is a fallback of id.
  */
  virtual UBool isFallbackOf(const UnicodeString& id) const;

 /**
  * <p>Return the prefix.  This implementation leaves result unchanged.
  * Result is returned as a convenience.</p>
  *
  * @param result the output parameter to which the prefix will be appended.
  * @return the modified result.
  */
  virtual UnicodeString& prefix(UnicodeString& result) const;

 /**
  * <p>A utility to parse the prefix out of a descriptor string.  Only
  * the (undelimited) prefix, if any, remains in result.  Result is returned as a 
  * convenience.</p>
  *
  * @param result an input/output parameter that on entry is a descriptor, and 
  * on exit is the prefix of that descriptor.
  * @return the modified result.
  */
  static UnicodeString& parsePrefix(UnicodeString& result);

  /**
  * <p>A utility to parse the suffix out of a descriptor string.  Only
  * the (undelimited) suffix, if any, remains in result.  Result is returned as a 
  * convenience.</p>
  *
  * @param result an input/output parameter that on entry is a descriptor, and 
  * on exit is the suffix of that descriptor.
  * @return the modified result.
  */
  static UnicodeString& parseSuffix(UnicodeString& result);

 public:
  /**
   * UObject RTTI boilerplate.
   */
  virtual UClassID getDynamicClassID() const {
    return getStaticClassID();
  }

  /**
   * UObject RTTI boilerplate.
   */
  static UClassID getStaticClassID() { 
    return (UClassID)&fgClassID;
  }

#ifdef SERVICE_DEBUG
 public:
  virtual UnicodeString& debug(UnicodeString& result) const;
  virtual UnicodeString& debugClass(UnicodeString& result) const;
#endif

 private:
    static const char fgClassID;
};

 /*******************************************************************
  * ICUServiceFactory
  */

 /**
  * <p>ICUServiceFactories generate the service objects maintained by the
  * service.  A factory generates a service object from a key,
  * updates id->factory mappings, and returns the display name for
  * a supported id.</p>
  */
class U_COMMON_API ICUServiceFactory : public UObject {
 public:

    /**
     * <p>Create a service object from the key, if this factory
     * supports the key.  Otherwise, return NULL.</p>
     *
     * <p>If the factory supports the key, then it can call
     * the service's getKey(ICUServiceKey, String[], ICUServiceFactory) method
     * passing itself as the factory to get the object that
     * the service would have created prior to the factory's
     * registration with the service.  This can change the
     * key, so any information required from the key should
     * be extracted before making such a callback.</p>
     *
     * @param key the service key.
     * @param service the service with which this factory is registered.
     * @param status the error code status.
     * @return the service object, or NULL if the factory does not support the key.
     */
    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const = 0;

    /**
     * <p>Update result to reflect the IDs (not descriptors) that this
     * factory publicly handles.  Result contains mappings from ID to
     * factory.  On entry it will contain all (visible) mappings from
     * previously-registered factories.</p>
     *
     * <p>This function, together with getDisplayName, are used to
     * support ICUService::getDisplayNames.  The factory determines
     * which IDs (of those it supports) it will make visible, and of
     * those, which it will provide localized display names for.  In
     * most cases it will register mappings from all IDs it supports
     * to itself.</p>
     *
     * @param result the mapping table to update.
     * @param status the error code status.
     */
    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const = 0;

    /**
     * <p>Return, in result, the display name of the id in the provided locale.
     * This is an id, not a descriptor.  If the id is 
     * not visible or not defined by the factory, sets result to bogus.  If the
     * incoming result is bogus, it remains bogus.  Result is returned as a
     * convenience.</p>
     *
     * @param id a visible id supported by this factory.
     * @param locale the locale for which to generate the corresponding localized display name.
     * @param result output parameter to hold the display name.
     * @return result.
     */
    virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const = 0;
};

/*
 ******************************************************************
 */

 /**
  * <p>A default implementation of factory.  This provides default
  * implementations for subclasses, and implements a singleton
  * factory that matches a single ID and returns a single
  * (possibly deferred-initialized) instance.  This implements
  * updateVisibleIDs to add a mapping from its ID to itself
  * if visible is true, or to remove any existing mapping
  * for its ID if visible is false.  No localization of display
  * names is performed.</p>
  */
class U_COMMON_API SimpleFactory : public ICUServiceFactory {
 protected:
  UObject* _instance;
  const UnicodeString _id;
  const UBool _visible;

 public:
  /**
   * <p>Construct a SimpleFactory that maps a single ID to a single 
   * service instance.  If visible is TRUE, the ID will be visible.
   * The instance must not be NULL.  The SimpleFactory will adopt
   * the instance, which must not be changed subsequent to this call.</p>
   *
   * @param instanceToAdopt the service instance to adopt.
   * @param id the ID to assign to this service instance.
   * @param visible if TRUE, the ID will be visible.
   */
  SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible = TRUE);

  /**
   * <p>Destructor.</p>
   */
  virtual ~SimpleFactory();

  /**
   * <p>This implementation returns a clone of the service instance if the factory's ID is equal to
   * the key's currentID.  Service and prefix are ignored.</p>
   *
   * @param key the service key.
   * @param service the service with which this factory is registered.
   * @param status the error code status.
   * @return the service object, or NULL if the factory does not support the key.
   */
  UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;

  /**
   * <p>This implementation adds a mapping from ID -> this to result if visible is TRUE, 
   * otherwise it removes ID from result.</p>
   *
   * @param result the mapping table to update.
   * @param status the error code status.
   */
  void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;

  /**
   * <p>This implementation returns the factory ID if it equals id and visible is TRUE,
   * otherwise it returns the empty string.  (This implementation provides
   * no localized id information.)</p>
   *
   * @param id a visible id supported by this factory.
   * @param locale the locale for which to generate the corresponding localized display name.
   * @param result output parameter to hold the display name.
   * @return result.
   */
  UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;

 public:
 /**
  * UObject RTTI boilerplate.
  */
  virtual UClassID getDynamicClassID() const {
	  return getStaticClassID();
  }

 /**
  * UObject RTTI boilerplate.
  */
  static UClassID getStaticClassID() { 
	  return (UClassID)&fgClassID;
  }

#ifdef SERVICE_DEBUG
 public:
  virtual UnicodeString& debug(UnicodeString& toAppendTo) const;
  virtual UnicodeString& debugClass(UnicodeString& toAppendTo) const;
#endif

 private:
  static const char fgClassID;
};

/*
 ******************************************************************
 */

/**
 * <p>ServiceListener is the listener that ICUService provides by default.
 * ICUService will notifiy this listener when factories are added to
 * or removed from the service.  Subclasses can provide
 * different listener interfaces that extend EventListener, and modify
 * acceptsListener and notifyListener as appropriate.</p>
 */
class U_COMMON_API ServiceListener : public EventListener {
 public:
  /**
   * <p>This method is called when the service changes. At the time of the
   * call this listener is registered with the service.  It must
   * not modify the notifier in the context of this call.</p>
   * 
   * @param service the service that changed.
   */
  virtual void serviceChanged(const ICUService& service) const = 0;

 public:
 /**
  * UObject RTTI boilerplate.
  */
  virtual UClassID getDynamicClassID() const {
    return getStaticClassID();
  }

 /**
  * UObject RTTI boilerplate.
  */
  static UClassID getStaticClassID() {
    return (UClassID)&fgClassID;
  }

 private:
  static const char fgClassID;
};

/*
 ******************************************************************
 */

/**
 * <p>A StringPair holds a displayName/ID pair.  ICUService uses it
 * as the array elements returned by getDisplayNames.
 */
class U_COMMON_API StringPair : public UMemory {
public:
  /**
   * <p>The display name of the pair.</p>
   */
  const UnicodeString displayName;

  /**
   * <p>The ID of the pair.</p>
   */
  const UnicodeString id;

  /**
   * <p>Creates a string pair from a displayName and an ID.</p>
   *
   * @param displayName the displayName.
   * @param id the ID.
   * @param status the error code status.
   * @return a StringPair if the creation was successful, otherwise NULL.
   */
  static StringPair* create(const UnicodeString& displayName, 
                            const UnicodeString& id,
                            UErrorCode& status);

  /**
   * <p>Return TRUE if either string of the pair is bogus.</p>
   * @return TRUE if either string of the pair is bogus.
   */
  UBool isBogus() const;

private:
  StringPair(const UnicodeString& displayName, const UnicodeString& id);
};

/**
 * Deleter for StringPairs
 */
U_CAPI void U_EXPORT2
deleteStringPair(void *obj);

/**
 * Opaque type returned by registerInstance and registerFactory.
 */
typedef const void* URegistryKey;

/*******************************************************************
 * ICUService
 */

 /**
 * <p>A Service provides access to service objects that implement a
 * particular service, e.g. transliterators.  Users provide a String
 * id (for example, a locale string) to the service, and get back an
 * object for that id.  Service objects can be any kind of object.  A
 * new service object is returned for each query. The caller is
 * responsible for deleting it.</p>
 *
 * <p>Services 'canonicalize' the query ID and use the canonical ID to
 * query for the service.  The service also defines a mechanism to
 * 'fallback' the ID multiple times.  Clients can optionally request
 * the actual ID that was matched by a query when they use an ID to
 * retrieve a service object.</p>
 *
 * <p>Service objects are instantiated by ICUServiceFactory objects
 * registered with the service.  The service queries each
 * ICUServiceFactory in turn, from most recently registered to
 * earliest registered, until one returns a service object.  If none
 * responds with a service object, a fallback ID is generated, and the
 * process repeats until a service object is returned or until the ID
 * has no further fallbacks.</p>
 *
 * <p>In ICU 2.4, UObject (the base class of service instances) does
 * not define a polymorphic clone function.  ICUService uses clones to
 * manage ownership.  Thus, for now, ICUService defines an abstract
 * method, cloneInstance, that clients must implement to create clones
 * of the service instances.  This may change in future releases of
 * ICU.</p>
 *
 * <p>ICUServiceFactories can be dynamically registered and
 * unregistered with the service.  When registered, an
 * ICUServiceFactory is installed at the head of the factory list, and
 * so gets 'first crack' at any keys or fallback keys.  When
 * unregistered, it is removed from the service and can no longer be
 * located through it.  Service objects generated by this factory and
 * held by the client are unaffected.</p>
 *
 * <p>If a service has variants (e.g., the different variants of
 * BreakIterator) an ICUServiceFactory can use the prefix of the
 * ICUServiceKey to determine the variant of a service to generate.
 * If it does not support all variants, it can request
 * previously-registered factories to handle the ones it does not
 * support.</p>
 *
 * <p>ICUService uses ICUServiceKeys to query factories and perform
 * fallback.  The ICUServiceKey defines the canonical form of the ID,
 * and implements the fallback strategy.  Custom ICUServiceKeys can be
 * defined that parse complex IDs into components that
 * ICUServiceFactories can more easily use.  The ICUServiceKey can
 * cache the results of this parsing to save repeated effort.
 * ICUService provides convenience APIs that take UnicodeStrings and
 * generate default ICUServiceKeys for use in querying.</p>
 *
 * <p>ICUService provides API to get the list of IDs publicly
 * supported by the service (although queries aren't restricted to
 * this list).  This list contains only 'simple' IDs, and not fully
 * unique IDs.  ICUServiceFactories are associated with each simple ID
 * and the responsible factory can also return a human-readable
 * localized version of the simple ID, for use in user interfaces.
 * ICUService can also provide an array of the all the localized
 * visible IDs and their corresponding internal IDs.</p>
 *
 * <p>ICUService implements ICUNotifier, so that clients can register
 * to receive notification when factories are added or removed from
 * the service.  ICUService provides a default EventListener
 * subinterface, ServiceListener, which can be registered with the
 * service.  When the service changes, the ServiceListener's
 * serviceChanged method is called with the service as the
 * argument.</p>
 *
 * <p>The ICUService API is both rich and generic, and it is expected
 * that most implementations will statically 'wrap' ICUService to
 * present a more appropriate API-- for example, to declare the type
 * of the objects returned from get, to limit the factories that can
 * be registered with the service, or to define their own listener
 * interface with a custom callback method.  They might also customize
 * ICUService by overriding it, for example, to customize the
 * ICUServiceKey and fallback strategy.  ICULocaleService is a
 * subclass of ICUService that uses Locale names as IDs and uses
 * ICUServiceKeys that implement the standard resource bundle fallback
 * strategy.  Most clients will wish to subclass it instead of
 * ICUService.</p> 
 */
class U_COMMON_API ICUService : public ICUNotifier {
 protected: 
    /**
     * Name useful for debugging.
     */
    const UnicodeString name;

 private:

    /**
     * single lock used by this service.
     */
    UMTX lock;

    /**
     * Timestamp so iterators can be fail-fast.
     */
    uint32_t timestamp;

    /**
     * All the factories registered with this service.
     */
    UVector* factories;

    /**
     * The service cache.
     */
    Hashtable* serviceCache;

    /**
     * The ID cache.
     */
    Hashtable* idCache;

    /**
     * The name cache.
     */
    DNCache* dnCache;

    /**
     * Constructor.
     */
 public:
    /**
     * <p>Construct a new ICUService.</p>
     */
    ICUService();

    /**
     * <p>Construct with a name (useful for debugging).</p>
     *
     * @param name a name to use in debugging.
     */
    ICUService(const UnicodeString& name);

    /**
     * <p>Destructor.</p>
     */
    virtual ~ICUService();

    /**
     * <p>Return the name of this service. This will be the empty string if none was assigned.
     * Returns result as a convenience.</p>
     *
     * @param result an output parameter to contain the name of this service.
     * @return the name of this service.
     */
    UnicodeString& getName(UnicodeString& result) const;

    /**
     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*). This uses
     * createKey to create a key for the provided descriptor.</p>
     *
     * @param descriptor the descriptor.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    UObject* get(const UnicodeString& descriptor, UErrorCode& status) const;

    /**
     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).  This uses
     * createKey to create a key from the provided descriptor.</p>
     *
     * @param descriptor the descriptor.
     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const;

    /**
     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).</p>
     *
     * @param key the key.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    UObject* getKey(ICUServiceKey& key, UErrorCode& status) const;

    /**
     * <p>Given a key, return a service object, and, if actualReturn
     * is not NULL, the descriptor with which it was found in the
     * first element of actualReturn.  If no service object matches
     * this key, returns NULL and leaves actualReturn unchanged.</p>
     *
     * <p>This queries the cache using the key's descriptor, and if no
     * object in the cache matches, tries the key on each
     * registered factory, in order.  If none generates a service
     * object for the key, repeats the process with each fallback of
     * the key, until either a factory returns a service object, or the key
     * has no fallback.  If no object is found, the result of handleDefault
     * is returned.</p> 
     *
     * @param key the key.
     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;

    /**
     * <p>This version of getKey is only called by ICUServiceFactories within the scope
     * of a previous getKey call, to determine what previously-registered factories would
     * have returned.  For details, see getKey(ICUServiceKey&, UErrorCode&).</p>
     * 
     * @param key the key.
     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
     * @param factory the factory making the recursive call.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const;

    /**
     * <p>Convenience override for getVisibleIDs(String) that passes null
     * as the fallback, thus returning all visible IDs.</p>
     *
     * @param result a vector to hold the returned IDs.
     * @param status the error code status.
     * @return the result vector.
     */
    UVector& getVisibleIDs(UVector& result, UErrorCode& status) const;

    /**
     * <p>Return a snapshot of the visible IDs for this service.  This
     * list will not change as ICUServiceFactories are added or removed, but the
     * supported IDs will, so there is no guarantee that all and only
     * the IDs in the returned list will be visible and supported by the
     * service in subsequent calls.</p>
     *
     * <p>The IDs are returned as pointers to UnicodeStrings.  The
     * caller owns the IDs.  Previous contents of result are discarded before
     * new elements, if any, are added.</p>
     *
     * <p>matchID is passed to createKey to create a key.  If the key
     * is not NULL, its isFallbackOf method is used to filter out IDs
     * that don't match the key or have it as a fallback.</p>
     *
     * @param result a vector to hold the returned IDs.
     * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
     * @param status the error code status.
     * @return the result vector.
     */
    UVector& getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const;

    /**
     * <p>Convenience override for getDisplayName(const UnicodeString&, const Locale&, UnicodeString&) that
     * uses the current default locale.</p>
     *
     * @param id the ID for which to retrieve the localized displayName.
     * @param result an output parameter to hold the display name.
     * @return the modified result.
     */
    UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result) const;

    /**
     * <p>Given a visible ID, return the display name in the requested locale.
     * If there is no directly supported ID corresponding to this ID, result is
     * set to bogus.</p>
     *
     * @param id the ID for which to retrieve the localized displayName.
     * @param result an output parameter to hold the display name.
     * @param locale the locale in which to localize the ID.
     * @return the modified result.
     */
    UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const;

    /**
     * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that 
     * uses the current default Locale as the locale and NULL for
     * the matchID.</p>
     *
     * @param result a vector to hold the returned displayName/id StringPairs.
     * @param status the error code status.
     * @return the modified result vector.
     */
    UVector& getDisplayNames(UVector& result, UErrorCode& status) const;

    /**
     * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that 
     * uses NULL for the matchID.</p>
     *
     * @param result a vector to hold the returned displayName/id StringPairs.
     * @param locale the locale in which to localize the ID.
     * @param status the error code status.
     * @return the modified result vector.
     */
    UVector& getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const;

    /**
     * <p>Return a snapshot of the mapping from display names to visible
     * IDs for this service.  This set will not change as factories
     * are added or removed, but the supported IDs will, so there is
     * no guarantee that all and only the IDs in the returned map will
     * be visible and supported by the service in subsequent calls,
     * nor is there any guarantee that the current display names match
     * those in the result.</p>
     *
     * <p>The names are returned as pointers to StringPairs, which
     * contain both the displayName and the corresponding ID.  The
     * caller owns the StringPairs.  Previous contents of result are
     * discarded before new elements, if any, are added.</p>
     *
     * <p>matchID is passed to createKey to create a key.  If the key
     * is not NULL, its isFallbackOf method is used to filter out IDs
     * that don't match the key or have it as a fallback.</p>
     *
     * @param result a vector to hold the returned displayName/id StringPairs.
     * @param locale the locale in which to localize the ID.
     * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
     * @param status the error code status.
     * @return the result vector.  */
    UVector& getDisplayNames(UVector& result,
                             const Locale& locale, 
                             const UnicodeString* matchID, 
                             UErrorCode& status) const;

    /**
     * <p>A convenience override of registerInstance(UObject*, const UnicodeString&, UBool)
     * that defaults visible to TRUE.</p>
     *
     * @param objToAdopt the object to register and adopt.
     * @param id the ID to assign to this object.
     * @param status the error code status.
     * @return a registry key that can be passed to unregister to unregister
     * (and discard) this instance.
     */
    URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status);

    /**
     * <p>Register a service instance with the provided ID.  The ID will be 
     * canonicalized.  The canonicalized ID will be returned by
     * getVisibleIDs if visible is TRUE.  The service instance will be adopted and
     * must not be modified subsequent to this call.</p>
     *
     * <p>This issues a serviceChanged notification to registered listeners.</p>
     *
     * <p>This implementation wraps the object using
     * createSimpleFactory, and calls registerFactory.</p>
     *
     * @param objToAdopt the object to register and adopt.
     * @param id the ID to assign to this object.
     * @param visible TRUE if getVisibleIDs is to return this ID.
     * @param status the error code status.
     * @return a registry key that can be passed to unregister() to unregister
     * (and discard) this instance.
     */
    virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);

    /**
     * <p>Register an ICUServiceFactory.  Returns a registry key that
     * can be used to unregister the factory.  The factory
     * must not be modified subsequent to this call.  The service owns
     * all registered factories. In case of an error, the factory is
     * deleted.</p>
     *
     * <p>This issues a serviceChanged notification to registered listeners.</p>
     *
     * <p>The default implementation accepts all factories.</p>
     *
     * @param factoryToAdopt the factory to register and adopt.
     * @param status the error code status.
     * @return a registry key that can be passed to unregister to unregister
     * (and discard) this factory.
     */
    virtual URegistryKey registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status);

    /**
     * <p>Unregister a factory using a registry key returned by
     * registerInstance or registerFactory.  After a successful call,
     * the factory will be removed from the service factory list and
     * deleted, and the key becomes invalid.</p>
     *
     * <p>This issues a serviceChanged notification to registered
     * listeners.</p>
     *
     * @param rkey the registry key.
     * @param status the error code status.  
     * @return TRUE if the call successfully unregistered the factory.
     */
    virtual UBool unregister(URegistryKey rkey, UErrorCode& status);

    /**
     * </p>Reset the service to the default factories.  The factory
     * lock is acquired and then reInitializeFactories is called.</p>
     *
     * <p>This issues a serviceChanged notification to registered listeners.</p>
     */
    virtual void reset(void);

    /**
     * <p>Return TRUE if the service is in its default state.</p>
     *
     * <p>The default implementation returns TRUE if there are no 
     * factories registered.</p>
     */
    virtual UBool isDefault(void) const;

    /**
     * <p>Create a key from an ID.  If ID is NULL, returns NULL.</p>
     *
     * <p>The default implementation creates an ICUServiceKey instance.
     * Subclasses can override to define more useful keys appropriate
     * to the factories they accept.</p>
     *
     * @param a pointer to the ID for which to create a default ICUServiceKey.
     * @param status the error code status.
     * @return the ICUServiceKey corresponding to ID, or NULL.
     */
    virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;

    /**
     * <p>Clone object so that caller can own the copy.  In ICU2.4, UObject doesn't define
     * clone, so we need an instance-aware method that knows how to do this.
     * This is public so factories can call it, but should really be protected.</p>
     *
     * @param instance the service instance to clone.
     * @return a clone of the passed-in instance, or NULL if cloning was unsuccessful.
     */
    virtual UObject* cloneInstance(UObject* instance) const = 0;


    /************************************************************************
     * Subclassing API
     */

 protected:

    /**
     * <p>Create a factory that wraps a single service object.  Called by registerInstance.</p>
     *
     * <p>The default implementation returns an instance of SimpleFactory.</p>
     *
     * @param instanceToAdopt the service instance to adopt.
     * @param id the ID to assign to this service instance.
     * @param visible if TRUE, the ID will be visible.
     * @param status the error code status.
     * @return an instance of ICUServiceFactory that maps this instance to the provided ID.
     */
    virtual ICUServiceFactory* createSimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);

    /**
     * <p>Reinitialize the factory list to its default state.  After this call, isDefault()
     * must return TRUE.</p>
     *
     * <p>This issues a serviceChanged notification to registered listeners.</p>
     *
     * <p>The default implementation clears the factory list.
     * Subclasses can override to provide other default initialization
     * of the factory list.  Subclasses must not call this method
     * directly, since it must only be called while holding write
     * access to the factory list.</p>
     */
    virtual void reInitializeFactories(void);

    /**
     * <p>Default handler for this service if no factory in the factory list
     * handled the key passed to getKey.</p>
     *
     * <p>The default implementation returns NULL.</p>
     *
     * @param key the key.
     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
     * @param status the error code status.
     * @return the service instance, or NULL.
     */
    virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;

    /**
     * <p>Clear caches maintained by this service.</p>
     *
     * <p>Subclasses can override if they implement additional caches
     * that need to be cleared when the service changes.  Subclasses
     * should generally not call this method directly, as it must only
     * be called while synchronized on the factory lock.</p>
     */
    virtual void clearCaches(void);

    /**
     * <p>Return true if the listener is accepted.</p>
     *
     * <p>The default implementation accepts the listener if it is
     * a ServiceListener.  Subclasses can override this to accept
     * different listeners.</p>
     *
     * @param l the listener to test.
     * @return TRUE if the service accepts the listener.
     */
    virtual UBool acceptsListener(const EventListener& l) const;

    /**
     * <p>Notify the listener of a service change.</p>
     *
     * <p>The default implementation assumes a ServiceListener.
     * If acceptsListener has been overridden to accept different
     * listeners, this should be overridden as well.</p>
     *
     * @param l the listener to notify.
     */
    virtual void notifyListener(EventListener& l) const;

    /************************************************************************
     * Utilities for subclasses.
     */

    /**
     * <p>Clear only the service cache.</p>
     *
     * <p>This can be called by subclasses when a change affects the service
     * cache but not the ID caches, e.g., when the default locale changes
     * the resolution of IDs also changes, requiring the cache to be
     * flushed, but not the visible IDs themselves.</p>
     */
    void clearServiceCache(void);

    /**
     * <p>Return a map from visible IDs to factories.
     * This must only be called when the mutex is held.</p>
     *
     * @param status the error code status.
     * @return a Hashtable containing mappings from visible
     * IDs to factories.
     */
    const Hashtable* getVisibleIDMap(UErrorCode& status) const;

    /**
     * <p>Allow subclasses to read the time stamp.</p>
     *
     * @return the timestamp.
     */
    int32_t getTimestamp(void) const;

    /**
     * <p>Return the number of registered factories.</p>
     *
     * @return the number of factories registered at the time of the call.
     */
    int32_t countFactories(void) const;

private:

    friend class ICUServiceTest; // give tests access to countFactories.
};

U_NAMESPACE_END

    /* UCONFIG_NO_SERVICE */
#endif

    /* ICUSERV_H */
#endif

