/**
 *******************************************************************************
 * Copyright (C) 2001-2003, 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"

class ICUServiceTest;

U_NAMESPACE_BEGIN

class ICUServiceKey;
class ICUServiceFactory;
class SimpleFactory;
class ServiceListener;
class ICUService;

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.
   */
  static UClassID getStaticClassID();

  /**
   * UObject RTTI boilerplate.
   */
  virtual UClassID getDynamicClassID() const;

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

};

 /*******************************************************************
  * 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.
  */
  static UClassID getStaticClassID();

 /**
  * UObject RTTI boilerplate.
  */
  virtual UClassID getDynamicClassID() const;

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

};

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

/**
 * <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.
     */
    static UClassID getStaticClassID();
    
    /**
     * UObject RTTI boilerplate.
     */
    virtual UClassID getDynamicClassID() const;
    
};

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

/**
 * <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>
	 *
	 * <p>Subclasses can override this method to further customize the 
	 * result before returning it.
     *
     * @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* 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&).  Subclasses
	 * should not call it directly, but call through one of the other get functions.</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

