//%2003////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
// Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
// IBM Corp.; EMC Corporation, The Open Group.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//==============================================================================
//
// Author: Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
//
// Modified By:  Carol Ann Krug Graves, Hewlett-Packard Company
//                   (carolann_graves@hp.com)
//               Ben Heilbronn, Hewlett-Packard Company (ben_heilbronn@hp.com)
//               Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
//
//%/////////////////////////////////////////////////////////////////////////////

#ifndef Pegasus_IndicationService_h
#define Pegasus_IndicationService_h

#include <Pegasus/Common/Config.h>
#include <Pegasus/Common/MessageQueueService.h>
#include <Pegasus/Common/CIMMessage.h>
#include <Pegasus/Common/IPC.h>
#include <Pegasus/Repository/CIMRepository.h>
#include <Pegasus/Server/ProviderRegistrationManager/ProviderRegistrationManager.h>
#include <Pegasus/WQL/WQLParser.h>
#include <Pegasus/WQL/WQLSelectStatement.h>
#include <Pegasus/WQL/WQLSimplePropertySource.h>
#include <Pegasus/Server/Linkage.h>
#include <Pegasus/Common/AcceptLanguages.h> // l10n  
#include <Pegasus/Common/ContentLanguages.h> // l10n

#include "ProviderClassList.h"
#include "IndicationOperationAggregate.h"

PEGASUS_NAMESPACE_BEGIN

/**
    Entry for ActiveSubscriptions table
 */
struct ActiveSubscriptionsTableEntry
{
    CIMInstance subscription;
    Array <ProviderClassList> providers;
};

/**
    Table for active subscription information

    The ActiveSubscriptions table is used to keep track of active subscriptions.
    This table contains an entry for each subscription that is enabled 
    (value of SubscriptionState property is enabled).  
    Each entry consists of a Subscription instance, and a list of 
    ProviderClassList structs representing the providers, if any, currently 
    serving each subscription and the relevant indication subclasses served by 
    each provider.
    The Key is generated by concatenating the namespace name of the 
    subscription instance, and the subscription instance key values (filter and
    handler key values).
    Entries are inserted into the table on initialization, when an enabled 
    subscription instance is created, or when a subscription instance is 
    modified to be enabled.
    Entries are removed from the table when an enabled subscription instance is
    deleted, or when a subscription instance is modified to be disabled.
    Entries are updated (remove followed by insert) when a provider serving a 
    subscription is disabled or enabled, or a provider registration change 
    occurs.
    The _handleProcessIndicationRequest() function, when a list of 
    subscriptions is included in request, looks up each subscription in the 
    table.
    The _handleNotifyProviderRegistrationRequest() function, once matching
    subscriptions have been identified, looks up the provider information for 
    each matching subscription in the table.
    The _handleModifyInstanceRequest() and _handleDeleteInstanceRequest() 
    functions, when sending delete requests to providers, look up the providers
    for the subscription in the table.
    The _handleNotifyProviderTerminationRequest() function, when a provider is 
    disabled, iterates through the table to retrieve all active 
    subscriptions being served by the provider.
    The terminate() function, when the CIM Server is being shut down, iterates 
    through the table to retrieve all active subscriptions.
 */
typedef HashTable <String, 
                   ActiveSubscriptionsTableEntry, 
                   EqualFunc <String>, 
                   HashFunc <String> > ActiveSubscriptionsTable;

/**
    Entry for SubscriptionClasses table
 */
struct SubscriptionClassesTableEntry
{
    CIMName indicationClassName;
    CIMNamespaceName sourceNamespaceName;
    Array <CIMInstance> subscriptions;
};

/**
    Table for subscription classes information

    The SubscriptionClasses Table is used to keep track of active subscriptions 
    for each indication subclass-source namespace pair.
    Each entry consists of an indication subclass name, a source namespace name,
    and a list of subscription instances.
    The Key is generated by concatenating the indication subclass name, and the
    source namespace name.
    The _handleProcessIndicationRequest() function, when no list of 
    subscriptions is included in the request, looks up matching subscriptions 
    in the table, using the class name and namespace name of the indication 
    instance.
    The _handleNotifyProviderRegistrationRequest() function, when an indication
    provider registration instance has been created or deleted, looks up 
    matching subscriptions in the table, using the class name and namespace 
    names from the provider registration instance.  
 */
typedef HashTable <String,
                   SubscriptionClassesTableEntry,
                   EqualFunc <String>,
                   HashFunc <String> > SubscriptionClassesTable;

/**

    IndicationService class is the service that serves the
    Indication Subscription, Indication Filter, and Indication Handler
    classes, and processes indications.

    @author  Hewlett-Packard Company

 */

class PEGASUS_SERVER_LINKAGE IndicationService : public MessageQueueService
{
public:

    typedef MessageQueueService Base;

    /**
        Constructs an IndicationSubscription instance and initializes instance
        variables.
     */
    IndicationService (
        CIMRepository * repository,
        ProviderRegistrationManager * providerRegManager);

    virtual ~IndicationService(void);

    void handleEnqueue(Message* message);

    virtual void handleEnqueue(void); 

    virtual void _handle_async_request(AsyncRequest *req);

    AtomicInt dienow;

    /**
        Operation types for the NotifyProviderRegistration message
     */
    enum Operation {OP_CREATE = 1, OP_DELETE = 2, OP_MODIFY = 3};

    static Mutex _mutex;

private:

    void _initialize (void);

    void _terminate (void);

    void _handleGetInstanceRequest(const Message * message);

    void _handleEnumerateInstancesRequest(const Message * message);

    void _handleEnumerateInstanceNamesRequest(const Message * message);

    void _handleCreateInstanceRequest(const Message * message);

    void _handleModifyInstanceRequest(const Message * message);

    void _handleDeleteInstanceRequest(const Message * message);

    void _handleProcessIndicationRequest(const Message * message);

    /**
	Notifies the Indication Service that a change in provider registration
	has occurred.  The Indication Service retrieves the subscriptions
	affected by the registration change, sends the appropriate Create,
        Modify, and/or Delete requests to the provider, and sends an alert to 
        handler instances of subscriptions that are no longer served by the 
        provider.
    */
    void _handleNotifyProviderRegistrationRequest(const Message * message);

    /**
        Determines if the specified provider is in the list of providers 
        serving the subscription.  

        @param   provider              the provider instance
        @param   tableValue            the Active Subscriptions Table entry

        @return  The index of the provider in the list, if found
                 PEG_NOT_FOUND otherwise
    */
    Uint32 _providerInList 
        (const CIMInstance & provider,
         const ActiveSubscriptionsTableEntry & tableValue);

    /**
        Determines if the specified class is in the list of indication 
        subclasses served by the specified provider, serving the subscription.  

        @param   className             the class name
        @param   providerClasses       the list of providers serving the 
                                       subscription, with the classes served

        @return  The index of the class name in the list, if found
                 PEG_NOT_FOUND otherwise
    */
    Uint32 _classInList
        (const CIMName & className,
         const ProviderClassList & providerClasses);

    /**
        Notifies the Indication Service that a provider has been disabled.  
        The Indication Service retrieves the subscriptions served by the
        disabled provider, and logs a message for each subscription that is no 
        longer served by the provider.
     */
    void _handleNotifyProviderTerminationRequest(const Message * message);

    /**
        Notifies the Indication Service that a provider has been enabled.  
        The Indication Service retrieves the subscriptions that can be served 
        by the enabled provider, sends Create Subscription and Enable 
        Indications requests to the provider, and logs a message for each 
        subscription that is now served by the provider.
     */
    void _handleNotifyProviderEnableRequest (const Message * message);

    /**
        Implements the subscription's On Fatal Error Policy.
        This function is called when a fatal error has occurred in the
        indication provider or indication handler, and the subscription can no
        longer be served.
        If the subscription's policy is Disable, the Subscription State is
        set to Disabled.
        If the subscription's policy is Remove, the subscription instance is 
        deleted.

        @param   subscription          the subscription instance

        @return  True if the subscription has been disabled or deleted
                 False otherwise
     */
    Boolean _handleError (
        const CIMInstance subscription);

    /**
        Disables the subscription.
        This function is called when a fatal error has occurred in the
        indication provider or indication handler, the subscription can no
        longer be served, and the subscription's policy is Disable.
        The Subscription State is set to Disabled.

        @param   subscription          the subscription instance
     */
    void _disableSubscription (
        CIMInstance subscription);

    /**
        Deletes the subscription instance.
        This function is called when a fatal error has occurred in the
        indication provider or indication handler, the subscription can no
        longer be served, and the subscription's policy is Remove.
        The subscription instance is deleted.

        @param   subscription          the subscription instance
     */
    void _deleteSubscription (
        const CIMInstance subscription);

    /**
        Determines if it is legal to create an instance. 
        Checks for existence of all key and required properties.  Checks that 
        properties that MUST NOT exist (based on values of other properties), 
        do not exist.  For any property that has a default value, if it does 
        not exist, adds the property with the default value.

        @param   instance              instance to be created
        @param   nameSpace             namespace for instance to be created

        @throw   CIM_ERR_INVALID_PARAMETER  if instance is invalid
        @throw   CIM_ERR_NOT_SUPPORTED      if the specified class is not 
                                            supported

        @return  True if the instance can be created
                 Otherwise throws an exception
     */
    Boolean _canCreate (
        CIMInstance & instance,
        const CIMNamespaceName & nameSpace);

    /**
        Validates the specified required property in the instance.
        If the property does not exist, or has a null value, an exceptiuon is 
        thrown, using the specified message.

        This function is called by the _canCreate function, and is used to 
        validate the  Filter and Handler properties in Subscription instances,
        the Name, CreationClassName, Query and Query Language properties in 
        Filter instances, the Name, CreationClassName, and Destination 
        properties in CIMXML Handler instances, and the Name, CreationClassName,
        Trap Destination, and SNMP Version properties in SNMP Mapper instances.

        @param   instance              instance to be validated
        @param   propertyName          name of property to be validated
        @param   message               message to be used in exception

        @throw   CIM_ERR_INVALID_PARAMETER  if required property is missing or 
                                            null
     */
    void _checkRequiredProperty (
        CIMInstance & instance,
        const CIMName & propertyName,
        const String & message);

    /**
        Validates the specified property and its corresponding Other___
        property in the instance.
        If the property does not exist, it is added with the default value.
        If the property exists, but its value is NULL, its value is set to
        the default value.
        If the value of the property is Other, but the corresponding Other___
        property either does not exist or has a value of NULL, an exception is 
        thrown.  
        If the value of the property is not Other, but the corresponding
        Other___ property exists and has a non-NULL value, an exception is
        thrown.
        This function is called by the _canCreate function, and is used to 
        validate the following pairs of properties in Subscription or Handler 
        instances: Subscription State, Other Subscription State, Repeat 
        Notification Policy, Other Repeat Notification Policy, On Fatal Error 
        Policy, Other On Fatal Error Policy, Persistence Type, Other 
        Persistence Type.

        @param   instance              instance to be validated
        @param   propertyName          name of property to be validated
        @param   otherPropertyName     name of Other___ property to be validated
        @param   defaultValue          default value for property
        @param   otherValue            "Other" value for property
        @param   validValues           set of valid values for property

        @throw   CIM_ERR_INVALID_PARAMETER  if value of property or Other___ 
                                            property is invalid
     */
    void _checkPropertyWithOther (
        CIMInstance & instance,
        const CIMName & propertyName,
        const CIMName & otherPropertyName,
        const Uint16 defaultValue,
        const Uint16 otherValue,
        const Array <Uint16> & validValues);

    /**
        Validates the specified property in the instance.
        If the property does not exist, it is added with the default value.
        If the property exists, but its value is NULL, its value is set to
        the default value.
        This function is called by the _canCreate function, and is used to 
        validate the System Name and System Creation Class Name properties in
        Filter and Handler instances, and the Source Namespace property in 
        Filter instances.

        @param   instance              instance to be validated
        @param   propertyName          name of property to be validated
        @param   defaultValue          default value for property

        @return  the value of the property

     */
    String _checkPropertyWithDefault (
        CIMInstance & instance,
        const CIMName & propertyName,
        const String & defaultValue);

    /**
        Adds an instance in the repository.  Adds or sets properties as 
        necessary.

        @param   request               the create instance request message
        @param   instance              instance to be added
        @param   enabled               indicates instance is a subscription 
                                         instance and is enabled

        @return  the CIMObjectPath for the instance
     */
    CIMObjectPath _createInstance (
        CIMCreateInstanceRequestMessage * request,
        CIMInstance instance,
        Boolean enabled);

    /**
        Determines if the user is authorized to modify the instance, and if the
        specified modification is supported.  Currently, the only modification 
        supported is of the Subscription State property of the Subscription 
        class.

        @param   request               modification request
        @param   instance              instance to be modified
        @param   modifiedInstance      modified instance

        @throw   CIM_ERR_NOT_SUPPORTED      if the specified modification is 
                                            not supported
        @throw   CIM_ERR_ACCESS_DENIED      if the user is not authorized to
                                            modify the instance
        @throw   CIM_ERR_INVALID_PARAMETER  if the modifiedInstance is invalid

        @return  True if the instance can be modified
                 Otherwise throws an exception
     */
    Boolean _canModify (
        const CIMModifyInstanceRequestMessage * request,
        const CIMObjectPath & instanceReference,
        const CIMInstance & instance,
        CIMInstance & modifiedInstance);

    /**
        Determines if the user is authorized to delete the instance, and if it 
        is legal to delete the instance.  If authorized, Subscription instances 
        may always be deleted.  Filter and non-transient Handler instances may 
        only be deleted if they are not being referenced by any Subscription 
        instances. If the instance to be deleted is a transient Handler, any 
        referencing Subscriptions are also deleted.

        @param   instanceReference     reference for instance to be deleted
        @param   nameSpace             namespace for instance to be deleted
        @param   currentUser           current user

        @throw   CIM_ERR_ACCESS_DENIED      if the user is not authorized to
                                            delete the instance
        @throw   CIM_ERR_FAILED             if the instance to be deleted is 
                                            referenced by a subscription

        @return  True if the instance can be deleted
                 Otherwise throws an exception
     */
    Boolean _canDelete (
        const CIMObjectPath & instanceReference,
        const CIMNamespaceName & nameSpace,
        const String & currentUser);

    /**
        Retrieves list of enabled subscription instances in all namespaces from
        the repository.

        @param   activeSubscriptions  the returned subscription instances

        @return  True  if a warning was logged
                 False otherwise
     */
    Boolean _getActiveSubscriptionsFromRepository (
        Array <CIMInstance> & activeSubscriptions) const;

    /**
        Retrieves list of enabled subscription instances in all namespaces from
        the Active Subscriptions table.

        @return   list of CIMInstance subscriptions
     */
    Array <CIMInstance> _getActiveSubscriptions ();

    /**
        Retrieves list of enabled subscription instances in all namespaces,
        where the subscription indication class matches or is a superclass
        of the supported class, and the properties required to process the
        subscription are all contained in the list of supported properties.
        If the checkProvider parameter value is True, a subscription is only 
        included in the list returned if the specified provider accepted the 
        subscription.  If the checkProvider parameter value is False, the 
        provider parameter is not used (ignored).

        @param   supportedClass       the supported class
        @param   nameSpaces           the list of supported namespaces
        @param   supportedProperties  the list of supported properties
        @param   checkProvider        indicates whether provider acceptance is
                                          checked
        @param   provider             the provider (used if checkProvider True)

        @return   list of CIMInstance subscriptions
     */
    Array <CIMInstance> _getMatchingSubscriptions (
        const CIMName & supportedClass,
        const Array <CIMNamespaceName> nameSpaces,
        const CIMPropertyList & supportedProperties,
        const Boolean checkProvider = false,
        const CIMInstance & provider = CIMInstance ());

    /**
        Retrieves lists of enabled subscription instances in all namespaces
        that are either newly supported or previously supported, based on the
        supported class, the supported namespaces before and after modification,
        and the supported properties before and after modification.  For 
        subscriptions based on the supported class, the newSubscriptions list 
        returned contains the subscriptions for which the properties required 
        to process the subscription are all contained in the new list of 
        supported properties, but are not all contained in the old list of 
        supported properties, and/or the filter source namespace is contained in
        the new list if supported namespaces, but is not contained in the old 
        list of supported namespaces.  The formerSubscriptions list returned 
        contains the subscriptions for which the properties required to process
        the subscription are not all contained in the new list of supported 
        properties, but are all contained in the old list of supported 
        properties, and/or the filter source namespace is not contained in the 
        new list if supported namespaces, but is contained in the old list of 
        supported namespaces.

        @param   supportedClass       the supported class
        @param   newNameSpaces        namespaces supported after modification
        @param   oldNameSpaces        namespaces supported before modification
        @param   newProperties        properties supported after modification
        @param   oldProperties        properties supported before modification
        @param   newSubscriptions     the list of newly supported subscriptions
        @param   formerSubscriptions  the list of previously supported
                                          subscriptions
     */
    void _getModifiedSubscriptions (
        const CIMName & supportedClass,
        const Array <CIMNamespaceName> & newNameSpaces,
        const Array <CIMNamespaceName> & oldNameSpaces,
        const CIMPropertyList & newProperties,
        const CIMPropertyList & oldProperties,
        Array <CIMInstance> & newSubscriptions,
        Array <CIMInstance> & formerSubscriptions);

    /**
        Retrieves list of subscriptions in the specified namespace.

        @param   nameSpace             the namespace

        @return   List of subscription instances
     */
    Array <CIMInstance> _getSubscriptions (
        const CIMNamespaceName & nameSpaceName) const;

    /**
        Determines if all of the required properties in the specified list
        are contained in the specified list of supported properties.

        @param   requiredProperties  the required properties
        @param   supportedProperties the supported properties

        @return   true if all required properties are supported
                  false otherwise
     */
    Boolean _inPropertyList (
        const CIMPropertyList & requiredProperties,
        const CIMPropertyList & supportedProperties);

    /**
        Retrieves list of enabled subscription instances in all namespaces,
        that are served by the specified provider.  This function is called 
        when a provider is disabled.  In the Active Subscriptions table, the 
        specified provider is removed from the list of providers serving the 
        subscription.  If there are no remaining providers serving the 
        subscription, the subscription is removed from the Active Subscriptions
        table.

        @param   provider          the provider instance

        @return   list of CIMInstance subscriptions
     */
    Array <CIMInstance> _getProviderSubscriptions (
        const CIMInstance & provider);

    /**
        Determines if the specified provider is currently in use serving one or
        more subscriptions in the Active Subscriptions table.  This function is
        called when a provider is added to or removed from the Active 
        Subscriptions table, to determine if an Enable or Disable Indications 
        request must be sent to the provider.

        NOTE: The caller must acquire a lock on the Active Subscriptions table 
        before calling.

        @param   provider          the provider instance

        @return   True  if the provider is serving one or more active 
                        subscriptions
                  False otherwise
     */
    Boolean _providerInUse
        (const CIMInstance & provider);

    /**
        Retrieves the values of the filter query, source namespace,
        and query language properties for the specified subscription instance.

        @param   subscription      Input subscription instance
        @param   nameSpaceName     Input namespace name
        @param   query             Output query for the filter
        @param   sourceNameSpace   Output source namespace for the filter
                                       subscription
        @param   queryLanguage     Output query language in which the filter
                                       query is expressed
     */
    void _getFilterProperties (
        const CIMInstance & subscription,
        const CIMNamespaceName & nameSpaceName,
        String & query,
        CIMNamespaceName & sourceNameSpace,
        String & queryLanguage);

    /**
        Retrieves the values of the filter query and source namespace
        properties for the specified subscription instance.

        @param   subscription      Input subscription instance
        @param   nameSpaceName     Input namespace name
        @param   query             Output query for the filter
        @param   sourceNameSpace   Output source namespace for the filter
                                       subscription
     */
    void _getFilterProperties (
        const CIMInstance & subscription,
        const CIMNamespaceName & nameSpaceName,
        String & query,
        CIMNamespaceName & sourceNameSpace);

    /**
        Retrieves the value of the filter query property 
        for the specified subscription instance.

        @param   subscription      Input subscription instance
        @param   nameSpaceName     Input namespace name
        @param   query             Output query for the filter
     */
    void _getFilterProperties (
        const CIMInstance & subscription,
        const CIMNamespaceName & nameSpaceName,
        String & query);

    /**
        Parses the filter query string, and returns the corresponding
        WQLSelectStatement object.

        @param   filterQuery           the filter query string

        @return  WQLSelectStatement representing the filter query
     */
    WQLSelectStatement _getSelectStatement (
        const String & filterQuery) const;

    /**
        Extracts the indication class name from the specified WQL select
        statement, and validates that the name represents a subclass of the
        Indication class.

        @param   selectStatement       the WQL select statement
        @param   nameSpaceName         the namespace

        @return  String containing the indication class name
     */
    CIMName _getIndicationClassName (
        const WQLSelectStatement & selectStatement,
        const CIMNamespaceName & nameSpaceName) const;

    /**
        Enumerates the subclass names of the specified indication class.

        @param   nameSpace             the namespace
        @param   indicationClassName   the indication class name

        @return  List of indication subclass names
     */
    Array <CIMName> _getIndicationSubclasses (
        const CIMNamespaceName & nameSpace,
        const CIMName & indicationClassName) const;

    /**
        Retrieves the list of indication providers that serve the specified
        indication subclasses.

        @param   nameSpaceName         the namespace name
        @param   indicationClassName   the indication class name
        @param   indicationSubclasses  the list of indication subclass names
        @param   requiredPropertyList  the properties required

        @return  list of ProviderClassList structs
     */
    Array <ProviderClassList> _getIndicationProviders (
        const CIMNamespaceName & nameSpace,
        const CIMName & indicationClassName,
        const Array <CIMName> & indicationSubclasses,
        const CIMPropertyList & requiredPropertyList) const;

    /**
        Retrieves the list of properties referenced by the specified
        filter query select statement.

        @param   selectStatement       the WQL select statement
        @param   nameSpaceName         the namespace
        @param   indicationClassName   the indciation class name

        @return  CIMPropertyList of properties referenced by the filter query 
                 select statement
     */
    CIMPropertyList _getPropertyList (
        const WQLSelectStatement & selectStatement,
        const CIMNamespaceName & nameSpaceName,
        const CIMName & indicationClassName) const;

    /**
        Checks if the property list includes all properties in the specified 
        class.  If so, a NULL CIMPropertyList is returned.  Otherwise, a
        CIMPropertyList containing the properties is returned.

        @param   propertyList          the list of property names
        @param   nameSpaceName         the namespace
        @param   indicationClassName   the indciation class name

        @return  CIMPropertyList of properties referenced by the filter query 
                 select statement
     */
    CIMPropertyList _checkPropertyList (
        const Array <CIMName> & propertyList,
        const CIMNamespaceName & nameSpaceName,
        const CIMName & indicationClassName) const;

    /**
        Extracts the condition (WHERE Clause) from the specified filter query
        string.

        @param   filterQuery       the filter query

        @return  String containing the filter query condition
     */
    String _getCondition (
        const String & filterQuery) const;

    /**
        Retrieves the Handler CIMInstance representing the handler of the
        specified subscription.

        @param   subscription          the subscription

        @return  a Handler CIMInstance for the subscription's handler
     */
    CIMInstance _getHandler (
        const CIMInstance & subscription) const;

    /**
        Determines if specified handler is Transient.

        @param   nameSpace             the name space
        @param   handler               the handler reference

        @return  True if the Handler is Transient, 
                 False otherwise
     */
    Boolean _isTransient (
        const CIMNamespaceName & nameSpace,
        const CIMObjectPath & handler) const;

    /**
        Deletes subscriptions referencing the specified handler.

        @param   nameSpace             the name space
        @param   referenceProperty     the name of the reference property in the
                                           subscription instance
        @param   handler               the handler reference
     */
    void _deleteReferencingSubscriptions (
        const CIMNamespaceName & nameSpace,
        const CIMName & referenceProperty,
        const CIMObjectPath & handler);

    /**
        Determines if specified Subscription has expired

        NOTE: It is assumed that the instance passed to this function is a
        Subscription instance, and that the Subscription Duration and
        Start Time properties exist

        @param   instance              the subscription instance

        @return  True if the Subscription has expired, 
                 False otherwise
     */
    Boolean _isExpired (
        const CIMInstance & instance) const;

    /**
        Deletes specified subscription 

        @param   subscription          the subscription reference
     */
    void _deleteExpiredSubscription (
        CIMObjectPath & subscription);

    /**
        Gets the Subscription Time Remaining property

        Calculates time remaining from Subscription Start Time, Subscription 
        Duration, and current date time.  If the subscription has a non-null
        Duration, the Time Remaining is set, and True is returned.  If the 
        subscription does not have a non-null Duration, it has no expiration 
        date, and the time remaining is unlimited.  In this case, the Time 
        Remaining is not set and False is returned.
      
        NOTE: It is assumed that the instance passed to this function is a
        Subscription instance, and that the Start Time property exists and 
        has a value

        @param   instance              Input the subscription instance
        @param   timeRemaining         Output the time remaining (seconds)

        @return  True if the subscription has a non-null Duration
                 False otherwise
     */
    Boolean _getTimeRemaining (
        const CIMInstance & instance,
        Uint64 & timeRemaining) const;

    /**
        Sets the Subscription Time Remaining property

        Calculates time remaining from Subscription Start Time, Subscription 
        Duration, and current date time
      
        NOTE: It is assumed that the instance passed to this function is a
        Subscription instance, and that the Subscription Duration and
        Start Time properties exist

        @param   instance              the subscription instance
     */
    void _setTimeRemaining (
        CIMInstance & instance);

    /**
        Gets the parameter values required to Create or Modify the subscription
        request.
        If no indication providers are found, condition and queryLanguage are 
        set to empty string.

        @param   nameSpaceName         Input namespace name (of subscription)
        @param   subscriptionInstance  Input subscription instance
        @param   indicationSubclasses  Output list of subclasses of indication 
                                           class in filter query
        @param   indicationProviders   Output list of providers with associated
                                           classes
        @param   propertyList          Output list of properties required by the
                                           subscription
        @param   sourceNameSpace       Output source namespace for filter query
        @param   condition             Output condition part of the filter query
        @param   queryLanguage         Output query language in which the filter
                                           query is expressed
     */
    void _getCreateParams (
        const CIMNamespaceName & nameSpaceName,
        const CIMInstance & subscriptionInstance,
        Array <CIMName> & indicationSubclasses,
        Array <ProviderClassList> & indicationProviders,
        CIMPropertyList & propertyList,
        CIMNamespaceName & sourceNameSpace,
        String & condition,
        String & queryLanguage);

    /**
        Gets the parameter values required to Create or Modify the subscription
        request.

        @param   nameSpaceName         Input namespace name (of subscription)
        @param   subscriptionInstance  Input subscription instance
        @param   indicationSubclasses  Output list of subclasses of indication 
                                           class in filter query
        @param   propertyList          Output list of properties required by the
                                           subscription
        @param   sourceNameSpace       Output source namespace for filter query
        @param   condition             Output condition part of the filter query
        @param   queryLanguage         Output query language in which the filter
                                           query is expressed
     */
    void _getCreateParams (
        const CIMNamespaceName & nameSpaceName,
        const CIMInstance & subscriptionInstance,
        Array <CIMName> & indicationSubclasses,
        CIMPropertyList & propertyList,
        CIMNamespaceName & sourceNameSpace,
        String & condition,
        String & queryLanguage);

    /**
        Gets the parameter values required to Delete the subscription request.

        @param   nameSpaceName         Input namespace name
        @param   subscriptionInstance  Input subscription instance
        @param   indicationSubclasses  Output list of subclasses of indication 
                                           class in filter query
        @param   sourceNameSpace       Output source namespace for filter query

        @return  List of providers with associated classes to Delete
     */
    Array <ProviderClassList> _getDeleteParams (
        const CIMNamespaceName & nameSpaceName,
        const CIMInstance & subscriptionInstance,
        Array <CIMName> & indicationSubclasses,
        CIMNamespaceName & sourceNameSpace);

    /**
        Sends Create subscription request for the specified subscription
        to each provider in the list.  Create Subscription requests must be 
        sent to the indication providers in the following cases: (1) on 
        initialization, for each enabled subscription retrieved from the 
        repository, (2) on creation of an enabled subscription instance, (3) on
        modification of a subscription instance, when the state changes to 
        enabled, and (4) on notification of a provider registration change 
        newly enabling the provider to serve the subscription.  In cases (2) and
        (3), there is an original Create Instance or Modify Instance request to
        which the Indication Service must respond.  In cases (1) and (4), there
        is an original request (Notify Provider Registration Request), but no 
        response is required.

        @param   indicationProviders   list of providers with associated classes
        @param   nameSpace             the nameSpace name of the resource been monitored.
                                        This value is contained in the SourceNamespace
                                        property of the CIM_IndicationFilter
                                        instance for the specified subscription
        @param   propertyList          the properties referenced by the
                                           subscription
        @param   condition             the condition part of the filter query
        @param   queryLanguage         the query language in which the filter
                                           query is expressed
        @param   subscription          the subscription to be created
        @param   acceptLangs           the language of the response, and
                                           future indications
        @param   contentLangs          the language of the subscription
        @param   origRequest           the original request, if any (e.g. Create
                                           Instance, Modify Instance, Provider 
                                           Registration change)
        @param   indicationSubclasses  the indication subclasses for the 
                                           subscription
        @param   userName              the userName for authentication
        @param   authType              the authentication type

     */
    void _sendCreateRequests (
        const Array <ProviderClassList> & indicationProviders,
        const CIMNamespaceName & nameSpace,
        const CIMPropertyList & propertyList,
        const String & condition,
        const String & queryLanguage,
        const CIMInstance & subscription,
        const AcceptLanguages & acceptLangs,
        const ContentLanguages & contentLangs,
        const CIMRequestMessage * origRequest,
        const Array <CIMName> & indicationSubclasses,
        const String & userName,
        const String & authType = String::EMPTY);

    /**
        Sends Modify subscription request for the specified subscription
        to each provider in the list.  Modify Subscription requests must be
        sent to the indication providers on notification of a provider 
        registration change, when the provider was formerly serving the 
        subscription, and is still serving the subscription, in the following 
        cases: (1) the provider is newly serving an additional indication 
        subclass specified by the subscription, and (2) the provider is
        no longer serving an indication subclass specified by the subscription 
        (but is still serving at least one of the indication subclasses).
        In cases (1) and (2), there is an original request (Notify Provider 
        Registration Request), but no response is required.

        @param   indicationProviders   list of providers with associated classes
        @param   nameSpace             the nameSpace name of the resource been monitored.
                                        This value is contained in the SourceNamespace
                                        property of the CIM_IndicationFilter
                                        instance for the specified subscription 
        @param   propertyList          the properties referenced by the
                                           subscription
        @param   condition             the condition part of the filter query
        @param   queryLanguage         the query language in which the filter
                                           query is expressed
        @param   subscription          the subscription to be modified
        @param   acceptLangs           the language of the response, and
                                           future indications
        @param   contentLangs          the language of the subscription    
        @param   origRequest           the original request (Provider 
                                           Registration change)
        @param   userName              the userName for authentication
        @param   authType              the authentication type
     */
    void _sendModifyRequests (
        const Array <ProviderClassList> & indicationProviders,
        const CIMNamespaceName & nameSpace,
        const CIMPropertyList & propertyList,
        const String & condition,
        const String & queryLanguage,
        const CIMInstance & subscription,
        const AcceptLanguages & acceptLangs,
        const ContentLanguages & contentLangs,  
        const CIMRequestMessage * origRequest,
        const String & userName,
        const String & authType = String::EMPTY);

    /**
        Sends Delete subscription request for the specified subscription
        to each provider in the list.  Delete Subscription requests must be
        sent to the indication providers in the following cases: (1) on deletion
        of an enabled subscription instance, (2) on modification of a 
        subscription instance, when the state changes to disabled, and (3) on 
        notification of a provider registration change newly preventing the 
        provider from serving the subscription.  
        In cases (1) and (2), there is an original Delete Instance or Modify 
        Instance request to which the Indication Service must respond.  In case
        (1), there is an original request (Notify Provider Registration 
        Request), but no response is required.

        @param   indicationProviders   list of providers with associated classes
        @param   nameSpace             the nameSpace name of the resource been monitored.
                                        This value is contained in the SourceNamespace
                                        property of the CIM_IndicationFilter
                                        instance for the specified subscription 
        @param   subscription          the subscription to be modified
        @param   acceptLangs           the language of the response
        @param   contentLangs          the language of the subscription    
        @param   origRequest           the original request (e.g. Delete
                                           Instance, Modify Instance, Provider 
                                           Registration change)
        @param   indicationSubclasses  the indication subclasses for the 
                                           subscription
        @param   userName              the userName for authentication
        @param   authType              the authentication type
     */
    void _sendDeleteRequests (
        const Array <ProviderClassList> & indicationProviders,
        const CIMNamespaceName & nameSpace,
        const CIMInstance & subscription,
        const AcceptLanguages & acceptLangs,
        const ContentLanguages & contentLangs,  
        const CIMRequestMessage * origRequest,
        const Array <CIMName> & indicationSubclasses,
        const String & userName,
        const String & authType = String::EMPTY);

    /**
        Collects responses from providers for aggregation as they are received,
        and stores them in the IndicationOperationAggregate instance.  Calls 
        _handleOperationResponseAggregation to process the responses, once all 
        expected responses have been received.

        @param  operation            shared data structure that controls msg 
                                         processing
        @param  destination          target queue of completion callback
        @param  userParameter        user parameter for callback processing
     */
    static void _aggregationCallBack (
        AsyncOpNode * operation,
        MessageQueue * destination,
        void * userParameter);

    /**
        Calls the appropriate function to processes responses from providers, 
        based on the type of request sent to providers, once all responses have
        been received.  

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleOperationResponseAggregation (
        IndicationOperationAggregate * operationAggregate);

    /**
        Processes create subscription responses from providers, once all have 
        been received.  Takes the appropriate action, based on the type of the 
        original request, if any, and the responses received.  Sends the 
        response to the original request, if required.

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleCreateResponseAggregation (
        IndicationOperationAggregate * operationAggregate);

    /**
        Processes enable indications responses from providers, once all have 
        been received.

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleEnableResponseAggregation (
        IndicationOperationAggregate * operationAggregate);

    /**
        Processes modify subscription responses from providers, once all have 
        been received.  Updates the subscription hash tables.

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleModifyResponseAggregation (
        IndicationOperationAggregate * operationAggregate);

    /**
        Processes delete subscription responses from providers, once all have 
        been received.  Updates the subscription hash tables appropriately, 
        based on the type of the original request, if any.  Sends the response 
        to the original request, if required.

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleDeleteResponseAggregation (
        IndicationOperationAggregate * operationAggregate);

    /**
        Processes disable indications responses from providers, once all have 
        been received.

        @param   operationAggregate    the operation aggregate instance 
     */
    void _handleDisableResponseAggregation 
        (IndicationOperationAggregate * operationAggregate);

    /**
        Generates a unique String key for the Active Subscriptions table from 
        the subscription namespace name and key values.

        @param   subscription          the subscription instance

        @return  the generated key
     */
    String _generateActiveSubscriptionsKey (
        const CIMObjectPath & subscriptionRef);

    /**
        Locks the _subscriptionClassesTableLock for read access and looks
        up an entry in the Active Subscriptions table.

        @param   key                   the hash table key
        @param   tableEntry            the table entry retrieved

        @return  true if the key is found in the table, false otherwise
     */
    Boolean _lockedLookupActiveSubscriptionsEntry (
        const String & key,
        ActiveSubscriptionsTableEntry & tableEntry);

    /**
        Inserts an entry into the Active Subscriptions table.  The caller
        must first lock _activeSubscriptionsTableLock for write access.

        @param   subscription          the subscription instance
        @param   providers             the list of providers 
     */
    void _insertActiveSubscriptionsEntry (
        const CIMInstance & subscription,
        const Array <ProviderClassList> & providers);

    /**
        Removes an entry from the Active Subscriptions table.  The caller
        must first lock _activeSubscriptionsTableLock for write access.

        @param   key                   the key of the entry to remove
     */
    void _removeActiveSubscriptionsEntry (
        const String & key);

    /**
        Generates a unique String key for the Subscription Classes table from
        the indication class name and source namespace name.

        @param   indicationClassName   the indication class name
        @param   sourceNamespaceName   the source namespace name

        @return  the generated key
     */
    String _generateSubscriptionClassesKey (
        const CIMName & indicationClassName,
        const CIMNamespaceName & sourceNamespaceName);

    /**
        Locks the _subscriptionClassesTableLock for read access and looks
        up an entry in the Subscription Classes table.

        @param   key                   the hash table key
        @param   tableEntry            the table entry retrieved

        @return  true if the key is found in the table, false otherwise
     */
    Boolean _lockedLookupSubscriptionClassesEntry (
        const String & key,
        SubscriptionClassesTableEntry & tableEntry);

    /**
        Locks the _subscriptionClassesTableLock for write access and inserts
        an entry into the Subscription Classes table.

        @param   indicationClassName   the indication class name
        @param   sourceNamespaceName   the source namespace name
        @param   subscriptions         the list of subscription instances
     */
    void _lockedInsertSubscriptionClassesEntry (
        const CIMName & indicationClassName,
        const CIMNamespaceName & sourceNamespaceName,
        const Array <CIMInstance> & subscriptions);

    /**
        Locks the _subscriptionClassesTableLock for write access and removes
        an entry from the Subscription Classes table.

        @param   key                   the key of the entry to remove
     */
    void _lockedRemoveSubscriptionClassesEntry (
        const String & key);

    /**
        Inserts entries (or updates existing entries) in the 
        Active Subscriptions and Subscription Classes tables.

        @param   subscription            the subscription instance
        @param   providers               the list of providers
        @param   indicationSubclassNames the list of indication subclass names
        @param   sourceNamespaceName     the source namespace name

        @return  list of (0 or more) providers that must be enabled
     */
    Array <ProviderClassList> _insertToHashTables (
        const CIMInstance & subscription,
        const Array <ProviderClassList> & providers,
        const Array <CIMName> & indicationSubclassNames,
        const CIMNamespaceName & sourceNamespaceName);

    /**
        Updates an entry in the Active Subscriptions table to either add a 
        provider to or remove a provider from the list of providers serving the
        subscription.

        @param   subscriptionPath        the subscription object path
        @param   provider                the provider
        @param   addProvider             indicates if adding or removing 
                                         provider

        @return  list of (0 or 1) provider that must be enabled or disabled
     */
    Array <ProviderClassList> _updateHashTable (
        const CIMObjectPath & subscriptionPath,
        const ProviderClassList & provider,
        Boolean addProvider);

    /**
        Removes entries (or updates entries) in the Active Subscriptions and 
        Subscription Classes tables.

        @param   subscription            the subscription instance
        @param   indicationSubclassNames the list of indication subclass names
        @param   sourceNamespaceName     the source namespace name
        @param   providers               the list of providers that had been 
                                         serving the subscription

        @return  list of (0 or more) providers that must be disabled
     */
    Array <ProviderClassList> _removeFromHashTables (
        const CIMInstance & subscription,
        const Array <CIMName> & indicationSubclassNames,
        const CIMNamespaceName & sourceNamespaceName,
        const Array <ProviderClassList> & providers);

    /**
        Creates an alert instance of the specified class.

        @param   alertClassName        the alert class name
        @param   subscriptions         subscriptions for which alert is to be
                                           created

        @return  the created alert instance
     */
    CIMInstance _createAlertInstance (
        const CIMName & alertClassName,
        const Array <CIMInstance> & subscriptions);

#if 0
     /** 
	  Asynchronous completion routine for _sendAlerts
      */

      static void _sendAlertsCallBack(AsyncOpNode *operation, 
				      MessageQueue *callback_destination, 
				      void *parameter);

    /**
        Sends specified alert to each unique handler instance for the
        specified subscriptions in the list.

        @param   subscriptions         subscriptions for which alert is to be
                                           sent
        @param   alertInstance         the alert to be sent
     */
    void _sendAlerts (
        const Array <CIMInstance> & subscriptions,
        /* const */ CIMInstance & alertInstance);
#endif
      
    /**
        Sends an Enable Indications request to the specified providers.

        @param   enableProviders       the providers to be enabled
     */
    void _sendEnable (
        const Array <ProviderClassList> & enableProviders,
        const CIMRequestMessage * origRequest);

    /**
        Sends a Disable Indications request to the specified providers.

        @param   disableProviders      the providers to be disabled
     */
    void _sendDisable 
        (const Array <ProviderClassList> & disableProviders,
         const CIMRequestMessage * origRequest);

    WQLSimplePropertySource _getPropertySourceFromInstance(
        CIMInstance & indicationInstance);

    /**
        Gets the value of the Creator property from the specified Subscription
        instance.  If this function returns False, the value of the creator 
        parameter is unchanged.

        @param   instance              subscription instance
        @param   creator               value of Creator property if retrieved

        @return  True if the value of the Creator property was retrieved
                 False if Creator property was missing, null, or of an
                       incorrect type.
     */
    Boolean _getCreator (
        const CIMInstance & instance,
        String & creator) const;

    /**
        Gets the value of the SubscriptionState property from the specified 
        Subscription instance.  If this function returns False, the value of 
        the state parameter is unchanged.

        @param   instance              subscription instance
        @param   state                 value of SubscriptionState property if 
                                       retrieved

        @return  True  if the value of the SubscriptionState property was 
                       retrieved
                 False if SubscriptionState property was missing, null, of an
                       incorrect type, or with an invalid value.
     */
    Boolean _getState (
        const CIMInstance & instance,
        Uint16 & state) const;

    /**
        This function peforms an authorization test based on the
        value of the enableSubscriptionForNonprivilegedUsers.

        @param   userName                String

        @return  True  if authentication is not enabled or the 
                       user is a privileged system user. 
                 False if authentication is enabled and the
                       user is not privileged.
     */
    void _checkNonprivilegedAuthorization (
        const String & userName);

    /**
        Updates the propertyList, in preparation for calling the Repository.
        If the propertyList is not null, the Creator property must be added to 
        the list.  Also, if the request is for the Subscription class, the 
        value of the Time Remaining property need only be calculated if it is 
        requested.  In that case, the Subscription Duration and Start Time 
        properties must be added to the list if not already there. 

        @param   className             class name for the request
        @param   propertyList          list of properties requested
        @param   setTimeRemaining      indicates whether Time Remaining property
                                       was requested
        @param   startTimeAdded        indicates whether Start Time property was
                                       added to the list
        @param   durationAdded         indicates whether Duration property was
                                       added to the list
     */
    void _updatePropertyList
        (CIMName & className,
         CIMPropertyList & propertyList,
         Boolean & setTimeRemaining,
         Boolean & startTimeAdded,
         Boolean & durationAdded);

    /**
        Gets a String containing the comma-separated Subscription Filter Name 
        and Handler Name, for use in a log message to identify the subscription.

        @param   subscription          subscription instance

        @return  String containing the comma-separated Subscription Filter Name
                 and Handler Name
     */
    String _getSubscriptionLogString
        (CIMInstance & subscription);

    /**
        Gets a String containing the Provider Name, for use in a log message to
        identify the provider.

        @param   provider              provider instance

        @return  String containing the Provider Name
     */
    String _getProviderLogString
        (CIMInstance & provider);

    /**
        Determines whether two instances are the same, based on the key values.

        @param   instance1             one instance
        @param   instance2             the other instance
        @param   theClass              the class to which the instances belong

        @return  True  if the instances are the same
                 False otherwise
     */
    Boolean _sameInstance
        (const CIMInstance & instance1,
         const CIMInstance & instance2,
         const CIMClass & theClass) const;

    CIMRepository * _repository;

    /**
        Handle to Provider Registration Manager
     */
    ProviderRegistrationManager * _providerRegManager;

    /**
        Integer representing queue ID for accessing Provider Manager Service
     */
    Uint32 _providerManager;

    /**
        Integer representing queue ID for accessing Handler Manager Service
     */
    Uint32 _handlerService;

    /**
        FUTURE: Integer representing queue ID for accessing Repository Service
     */
    //Uint32 _repository;

    /**
        Boolean indicating that the CIM Server has been configured to
        allow non-privileged users read and write access to the
        Subscription classes.
     */
    Boolean _enableSubscriptionsForNonprivilegedUsers;

    /**
        Active Subscriptions information table.  Access to this table is
        controlled by the _activeSubscriptionsTableLock.
     */
    ActiveSubscriptionsTable _activeSubscriptionsTable;
    /**
        A lock to control access to the _activeSubscriptionsTable.  Before
        accessing the _activeSubscriptionsTable, one must first lock this for
        read access.  Before updating the _activeSubscriptionsTable, one must
        first lock this for write access.
     */
    ReadWriteSem _activeSubscriptionsTableLock;

    /**
        Subscription Classes information table.  Access to this table is
        controlled by the _subscriptionClassesTableLock.
     */
    SubscriptionClassesTable _subscriptionClassesTable;
    /**
        A lock to control access to the _subscriptionClassesTable.  Before
        accessing the _subscriptionClassesTable, one must first lock this for
        read access.  Before updating the _subscriptionClassesTable, one must
        first lock this for write access.
     */
    ReadWriteSem _subscriptionClassesTableLock;

    Array <Uint16> _validStates;
    Array <Uint16> _validRepeatPolicies;
    Array <Uint16> _validErrorPolicies;
    Array <Uint16> _validPersistenceTypes;
    
    /**
        Values for the Subscription State property of the Subscription class,
        as defined in the CIM Events MOF
     */
    enum SubscriptionState {_STATE_UNKNOWN = 0, _STATE_OTHER = 1, 
         _STATE_ENABLED = 2, _STATE_ENABLEDDEGRADED = 3, _STATE_DISABLED = 4};

    /**
        Values for the Repeat Notification Policy property of the Subscription 
        class, as defined in the CIM Events MOF
     */
    enum RepeatNotificationPolicy {_POLICY_UNKNOWN = 0, _POLICY_OTHER = 1,
         _POLICY_NONE = 2, _POLICY_SUPPRESS = 3, _POLICY_DELAY = 4};

    /**
        Values for the On Fatal Error Policy property of the Subscription 
        class, as defined in the CIM Events MOF
     */
    enum OnFatalErrorPolicy {_ERRORPOLICY_OTHER = 1, _ERRORPOLICY_IGNORE = 2, 
        _ERRORPOLICY_DISABLE = 3, _ERRORPOLICY_REMOVE = 4};

    /**
        Values for the Persistence Type property of the Handler class, 
        as defined in the CIM Events MOF
     */
    enum PersistenceType {_PERSISTENCE_OTHER = 1, _PERSISTENCE_PERMANENT = 2, 
        _PERSISTENCE_TRANSIENT = 3};

    /**
        Values for the Perceived Severity property of the Alert Indication 
        class, as defined in the CIM Events MOF
     */
    enum PerceivedSeverity {_SEVERITY_UNKNOWN = 0, _SEVERITY_OTHER = 1, 
         _SEVERITY_INFORMATION = 2, _SEVERITY_WARNING = 3, _SEVERITY_MINOR = 4,
         _SEVERITY_MAJOR = 5, _SEVERITY_CRITICAL = 6, _SEVERITY_FATAL = 7};

    /**
        Values for the Probable Cause property of the Alert Indication 
        class, as defined in the CIM Events MOF
        Note: not all possible values have been included
     */
    enum ProbableCause {_CAUSE_UNKNOWN = 0, _CAUSE_OTHER = 1};

    /**
        Values for the Alert Type property of the Alert Indication class, 
        as defined in the CIM Events MOF
     */
    enum AlertType {_TYPE_OTHER = 1, _TYPE_COMMUNICATIONS = 2, _TYPE_QOS = 3,
         _TYPE_PROCESSING = 4, _TYPE_DEVICE = 5, _TYPE_ENVIRONMENTAL = 6,
         _TYPE_MODELCHANGE = 7, _TYPE_SECURITY = 8};

    //
    //  Class names
    //

    /**
        The name of the CIMOM Shutdown alert indication class
     */
    static const CIMName   _CLASS_CIMOM_SHUTDOWN_ALERT;

    /**
        The name of the No Provider alert indication class
     */
    static const CIMName   _CLASS_NO_PROVIDER_ALERT;

    /**
        The name of the CIMOM shutdown alert indication class
     */
    static const CIMName   _CLASS_PROVIDER_TERMINATED_ALERT;


    //
    //  Property names
    //

    /**
        The name of the Subscription State property for Indication Subscription
        class
     */
    static const CIMName   _PROPERTY_STATE;

    /**
        The name of the Other Subscription State property for Indication
        Subscription class
     */
    static const CIMName   _PROPERTY_OTHERSTATE;

    /**
        The name of the repeat notification policy property for indication
        subscription class
     */
    static const CIMName   _PROPERTY_REPEATNOTIFICATIONPOLICY;

    /**
        The name of the other repeat notification policy property for
        indication subscription class
     */
    static const CIMName   _PROPERTY_OTHERREPEATNOTIFICATIONPOLICY;

    /**
        The name of the repeat notification interval property for indication
        subscription class
     */
    static const CIMName   _PROPERTY_REPEATNOTIFICATIONINTERVAL;

    /**
        The name of the repeat notification gap property for indication
        subscription class
     */
    static const CIMName   _PROPERTY_REPEATNOTIFICATIONGAP;

    /**
        The name of the repeat notification count property for indication
        subscription class
     */
    static const CIMName   _PROPERTY_REPEATNOTIFICATIONCOUNT;

    /**
        The name of the On Fatal Error Policy property for Indication 
        Subscription class
     */
    static const CIMName   _PROPERTY_ONFATALERRORPOLICY;

    /**
        The name of the Other On Fatal Error Policy property for Indication
        Subscription class
     */
    static const CIMName   _PROPERTY_OTHERONFATALERRORPOLICY;

    /**
        The name of the Time Of Last State Change property for Indication 
        Subscription class
     */
    static const CIMName   _PROPERTY_LASTCHANGE;

    /**
        The name of the Subscription Start Time property for Indication 
        Subscription class
     */
    static const CIMName   _PROPERTY_STARTTIME;

    /**
        The name of the Subscription Duration property for Indication 
        Subscription class
     */
    static const CIMName   _PROPERTY_DURATION;

    /**
        The name of the Subscription Time Remaining property for Indication 
        Subscription class
     */
    static const CIMName   _PROPERTY_TIMEREMAINING;

    /**
        The name of the filter reference property for indication subscription
        class
     */
    static const CIMName   _PROPERTY_FILTER;

    /**
        The name of the handler reference property for indication subscription
        class
     */
    static const CIMName   _PROPERTY_HANDLER;

    /**
        The name of the query property for indication filter class
     */
    static const CIMName   _PROPERTY_QUERY;

    /**
        The name of the query language property for indication filter class
     */
    static const CIMName   _PROPERTY_QUERYLANGUAGE;

    /**
        The name of the Source Namespace property for indication filter class
     */
    static const CIMName   _PROPERTY_SOURCENAMESPACE;

    /**
        The name of the name property for indication filter and indication
        handler classes
     */
    static const CIMName   _PROPERTY_NAME;

    /**
        The name of the creation class name property for indication filter and
        indication handler classes
     */
    static const CIMName   _PROPERTY_CREATIONCLASSNAME;

    /**
        The name of the system name property for indication filter and
        indication handler classes
     */
    static const CIMName   _PROPERTY_SYSTEMNAME;

    /**
        The name of the system creation class name property for indication
        filter and indication handler classes
     */
    static const CIMName   _PROPERTY_SYSTEMCREATIONCLASSNAME;

    /**
        The name of the Persistence Type property for Indication Handler class
     */
    static const CIMName   _PROPERTY_PERSISTENCETYPE;

    /**
        The name of the Other Persistence Type property for Indication Handler
        class
     */
    static const CIMName   _PROPERTY_OTHERPERSISTENCETYPE;

    /**
        The name of the Destination property for CIM XML Indication Handler 
        subclass
     */
    static const CIMName   _PROPERTY_DESTINATION;

    /**
        The name of the TargetHost property for SNMP Mapper Indication
        Handler subclass
     */
    static const CIMName   _PROPERTY_TARGETHOST;

    /**
        The name of the TargetHostFormat property for SNMP Indication Handler subclass
     */
    static const CIMName   _PROPERTY_TARGETHOSTFORMAT;

    /**
        The name of the SNMP Version property for SNMP Indication Handler subclass
      */
    static const CIMName   _PROPERTY_SNMPVERSION;

    /**
        The name of the Alert Type property for Alert Indication class
     */
    static const CIMName   _PROPERTY_ALERTTYPE;

    /**
        The name of the Other Alert Type property for Alert Indication class
     */
    static const CIMName   _PROPERTY_OTHERALERTTYPE;

    /**
        The name of the Perceived Severity property for Alert Indication class
     */
    static const CIMName   _PROPERTY_PERCEIVEDSEVERITY;

    /**
        The name of the Probable Cause property for Alert Indication class
     */
    static const CIMName   _PROPERTY_PROBABLECAUSE;

    /**
        The name of the Provider Name property for Provider class
     */
    static const CIMName   _PROPERTY_PROVIDERNAME;

    /**
        The name of the Provider Module Name property for Provider class
     */
    static const CIMName   _PROPERTY_PROVIDERMODULENAME;


    //
    //  Qualifier names
    //

    /**
        The name of the Indication qualifier for classes
     */
    static const CIMName   _QUALIFIER_INDICATION;


    //
    //  Other literal values
    //

    /**
        The WHERE keyword in WQL
     */
    static const char   _QUERY_WHERE [];

    /**
        The string representing the asterisk all properties symbol in WQL
     */
    static const char   _QUERY_ALLPROPERTIES [];

    /**
        A zero value CIMDateTime interval
     */
    static const char _ZERO_INTERVAL_STRING [];


    //
    //  Message substrings used in exception messages
    //

    // l10n

    // this one is tricky because it is used in _checkRequiredProperty with the two below
    static const char _MSG_MISSING_REQUIRED [];

    static const char _MSG_KEY_PROPERTY [];
    static const char _MSG_KEY_PROPERTY_KEY [];

    static const char _MSG_PROPERTY [];
    static const char _MSG_PROPERTY_KEY [];

    static const char _MSG_PROPERTY_PRESENT [];
    static const char _MSG_VALUE_NOT [];
    static const char _MSG_PROPERTY_PRESENT_BUT_VALUE_NOT_KEY [];

    static const char _MSG_NO_PROVIDERS [];
    static const char _MSG_NO_PROVIDERS_KEY[];

    static const char _MSG_NOT_ACCEPTED [];
    static const char _MSG_NOT_ACCEPTED_KEY [];

    static const char _MSG_INVALID_CLASSNAME [];

    static const char _MSG_IN_FROM [];

    static const char _MSG_INVALID_CLASSNAME_IN_FROM_PROPERTY_KEY [];

    static const char _MSG_EXPIRED [];
    static const char _MSG_EXPIRED_KEY [];

    static const char _MSG_REFERENCED [];
    static const char _MSG_REFERENCED_KEY [];

    static const char _MSG_INVALID_VALUE [];

    static const char _MSG_INVALID_TYPE [];

    static const char _MSG_FOR_PROPERTY [];

    static const char _MSG_ARRAY_OF [];

    static const char _MSG_INVALID_VALUE_FOR_PROPERTY_KEY [];

    static const char _MSG_CLASS_NOT_SERVED [];

    static const char _MSG_CLASS_NOT_SERVED_KEY [];

    static const char _MSG_INVALID_INSTANCES [];
    
    static const char _MSG_INVALID_INSTANCES_KEY [];

    static const char _MSG_PROVIDER_NO_LONGER_SERVING [];
    
    static const char _MSG_PROVIDER_NO_LONGER_SERVING_KEY [];

    static const char _MSG_PROVIDER_NOW_SERVING [];
    
    static const char _MSG_PROVIDER_NOW_SERVING_KEY [];

    static const char _MSG_NO_PROVIDER [];
    
    static const char _MSG_NO_PROVIDER_KEY [];

    static const char _MSG_NON_PRIVILEGED_ACCESS_DISABLED [];
 
    static const char _MSG_NON_PRIVILEGED_ACCESS_DISABLED_KEY [];
};

PEGASUS_NAMESPACE_END

#endif  /* Pegasus_IndicationService_h */
