//
// Local version of enumerateInstances to be used by other functions in the
// provider. Note that this delivers instances as a group rather than one
// at a time. This design point may need to be revisited if this provider
// is used in environments such that returning segmented responses would have
// significant performance advantages. For now, that doesn't seem to be the
// case.
//
Array<CIMInstance> InteropProvider::localEnumerateInstances(
    const OperationContext & context,
    const CIMObjectPath & ref,
    const CIMPropertyList& propertyList)
{
    PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,
                     "InteropProvider::localEnumerateInstances()");

    const CIMName & className = ref.getClassName();
    PEG_TRACE((TRC_CONTROLPROVIDER, Tracer::LEVEL4,
               "%s enumerateInstances. referenc= %s , PropertyList= %s",
               thisProvider,
               (const char *)className.getString().getCString(),
               (const char *)propertyList.toString().getCString()));

    // Verify that ClassName is correct and get its enum value
    TARGET_CLASS classEnum = translateClassInput(className);

    Array<CIMInstance> instances;
    switch(classEnum)
    {
    case PG_OBJECTMANAGER:
    {
        instances.append(getObjectManagerInstance());
        break;
    }
    case PG_CIMXMLCOMMUNICATIONMECHANISM:
    {
        instances = enumCIMXMLCommunicationMechanismInstances();
        break;
    }
    case PG_NAMESPACEINMANAGER:
    {
        instances = enumNamespaceInManagerInstances();
        break;
    }
    case PG_COMMMECHANISMFORMANAGER:
    {
        instances = enumCommMechanismForManagerInstances();
        break;
    }
    case PG_NAMESPACE:
    {
        instances = enumNamespaceInstances();
        break;
    }
    case PG_REGISTEREDPROFILE:
    {
        instances = enumRegisteredProfileInstances();
        break;
    }
    case PG_REGISTEREDSUBPROFILE:
    {
        instances = enumRegisteredSubProfileInstances();
        break;
    }
    case PG_REFERENCEDPROFILE:
    {
        instances = enumReferencedProfileInstances();
        break;
    }
    case PG_ELEMENTCONFORMSTOPROFILE:
    {
        instances = enumElementConformsToProfileInstances(context,
                    ref.getNameSpace());
        break;
    }
    case PG_ELEMENTCONFORMSTOPROFILE_RP_RP:
    {
        instances = enumElementConformsToProfileRPRPInstances(
                        context,
                        ref.getNameSpace());
        break;
    }
    case PG_SUBPROFILEREQUIRESPROFILE:
    {
        instances = enumSubProfileRequiresProfileInstances();
        break;
    }
    case PG_SOFTWAREIDENTITY:
    {
        instances = enumSoftwareIdentityInstances();
        break;
    }
    case PG_ELEMENTSOFTWAREIDENTITY:
    {
        instances = enumElementSoftwareIdentityInstances();
        break;
    }
    case PG_INSTALLEDSOFTWAREIDENTITY:
    {
        instances = enumInstalledSoftwareIdentityInstances(context);
        break;
    }
    case PG_COMPUTERSYSTEM:
    {
        instances.append(getComputerSystemInstance(context));
        break;
    }
    case PG_HOSTEDOBJECTMANAGER:
    {
        instances.append(getHostedObjectManagerInstance(context));
        break;
    }
    case PG_HOSTEDACCESSPOINT:
    {
        instances = enumHostedAccessPointInstances(context);
        break;
    }
    //We don't support enumerate CIM_Namespace instances. PG_Namespace is
    //supported.
    case CIM_NAMESPACE:
    {
        break;
    }
    case PG_PROVIDERPROFILECAPABILITIES:
    {
        instances = enumProviderProfileCapabilityInstances(false);
        break;
    }

#ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
    case PG_ELEMENTCAPABILITIES:
    {
        instances = enumElementCapabilityInstances(context);
        break;
    }
    case PG_HOSTEDINDICATIONSERVICE:
    {
        instances = enumHostedIndicationServiceInstances(context);
        break;
    }
    case PG_SERVICEAFFECTSELEMENT:
    {
        instances = enumServiceAffectsElementInstances(context);
        break;
    }
    case CIM_INDICATIONSERVICE:
    {
        instances = enumIndicationServiceInstances(context);
        break;
    }
#endif
    default:
        PEG_METHOD_EXIT();
        throw CIMNotSupportedException(className.getString() +
                                       " not supported by Interop Provider enumerate");
    }

    // Filter and deliver the resulting instances
    for (Uint32 i = 0 ; i < instances.size() ; i++)
    {
        normalizeInstance(instances[i], ref, false,
                          false, propertyList);
    }

    PEG_METHOD_EXIT();
    return instances;
}
//
// Local version of getInstance to be used by other functions in the the
// provider. Returns a single instance. Note that it always returns an
// instance. If none was found, it is uninialitized.
//
CIMInstance InteropProvider::localGetInstance(
    const OperationContext & context,
    const CIMObjectPath & instanceName,
    const CIMPropertyList & propertyList)
{
    PEG_METHOD_ENTER(TRC_CONTROLPROVIDER, "InteropProvider::localGetInstance");

    PEG_TRACE((TRC_CONTROLPROVIDER, Tracer::LEVEL4,
               "%s getInstance. instanceName= %s , PropertyList= %s",
               thisProvider,
               (const char *)instanceName.toString().getCString(),
               (const char *)propertyList.toString().getCString()));

    // Test if we're looking for something outside of our namespace. This will
    // happen during associators calls from PG_RegisteredProfile instances
    // through the PG_ElementConformsToProfile association
    CIMNamespaceName opNamespace = instanceName.getNameSpace();
    CIMName opClass = instanceName.getClassName();
    if((opNamespace != PEGASUS_NAMESPACENAME_INTEROP &&
            opClass != PEGASUS_CLASSNAME_PG_ELEMENTCONFORMSTOPROFILE)
            // Get CIM_IndicationService instance from IndicationService.
#ifdef PEGASUS_ENABLE_DMTF_INDICATION_PROFILE_SUPPORT
            || opClass == PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE
#endif
      )
    {
        AutoMutex mut(interopMut);
        CIMInstance gotInstance = cimomHandle.getInstance(
                                      context,
                                      opNamespace,
                                      instanceName,
                                      false,
                                      false,
                                      false,
                                      propertyList);
        PEG_METHOD_EXIT();
        return gotInstance;
    }

    TARGET_CLASS classEnum  = translateClassInput(opClass);
    CIMInstance retInstance;
    switch(classEnum)
    {
    case PG_SOFTWAREIDENTITY:
    {
        retInstance = getSoftwareIdentityInstance(instanceName);
        normalizeInstance(
            retInstance, instanceName, false, false, propertyList);
    }
    break;
    case PG_NAMESPACE:
    {
        retInstance = getNameSpaceInstance(instanceName);
        normalizeInstance(
            retInstance, instanceName, false, false, propertyList);
    }
    break;
    // ATTN: Implement getIntstance for all other classes. Currently
    // this method calls localEnumerateInstances() to select instance
    // which is too expensive.
    default:
    {
        // Create reference from host, namespace, class components of
        // instance name
        CIMObjectPath ref;
        ref.setHost(instanceName.getHost());
        ref.setClassName(opClass);
        ref.setNameSpace(opNamespace);

        // Enumerate instances for this class. Returns all instances
        // Note that this returns paths setup and instances already
        // filtered per the input criteria.
        Array<CIMInstance> instances =  localEnumerateInstances(
                                            context,
                                            ref,
                                            propertyList);
        ConstArrayIterator<CIMInstance> instancesIter(instances);

        // deliver a single instance if found.
        bool found = false;
        for(Uint32 i = 0; i < instancesIter.size(); i++)
        {
            CIMObjectPath currentInstRef = instancesIter[i].getPath();
            currentInstRef.setHost(instanceName.getHost());
            currentInstRef.setNameSpace(instanceName.getNameSpace());
            if(instanceName == currentInstRef)
            {
                retInstance = instancesIter[i];
                found = true;
                break;
            }
        }

        if (!found)
        {
            PEG_METHOD_EXIT();
            throw CIMObjectNotFoundException(instanceName.toString());
        }
    }
    }

    PEG_METHOD_EXIT();
    return retInstance;
}