CMPIObjectPath * _makePath_ServiceProcess( const CMPIBroker * _broker, 
					   const CMPIObjectPath * service,
					   CMPIObjectPath * process,
					   CMPIStatus * rc) {
  CMPIObjectPath * op = NULL;
  CMPIInstance   * ci = NULL;

  _OSBASE_TRACE(4,("--- _makePath_ServiceProcess() called"));

  ci = _makeInst_ServiceProcess(_broker, service, process, rc);
  if( ci == NULL ) { return NULL; }

  op = CMGetObjectPath(ci,rc); 
  CMSetNameSpace(op,CMGetCharPtr(CMGetNameSpace(service,rc)));

  _OSBASE_TRACE(4,("--- _makePath_ServiceProcess() exited"));
  return op; 
}
CMPIStatus
getRefs(const CMPIContext *ctx, const CMPIResult *rslt,
        const CMPIObjectPath * cop,
        const char *assocClass,
        const char *resultClass,
        const char *role,
        const char *resultRole,
        const char **propertyList, int associatorFunction)
{
  UtilList       *refs = UtilFactory->newList(memAddUtilList, memUnlinkEncObj);
  char           *ns = (char *) CMGetNameSpace(cop, NULL)->hdl;
  CMPIStatus      st = { CMPI_RC_OK, NULL };

  _SFCB_ENTER(TRACE_INTERNALPROVIDER, "getRefs");

  if (assocClass != NULL) {
    CMPIObjectPath *path;
    if (assocForName(ns, assocClass, role, resultRole) == NULL) {
      /*
       * for an unknown class we just return nothing 
       */
      _SFCB_RETURN(st);
    }
    path = CMNewObjectPath(_broker, ns, assocClass, NULL);
    SafeInternalProviderAddEnumInstances(refs, NULL, ctx, path,
                                         propertyList, &st, 1);
  }

  else {
    CMPIData        rv;
    CMPIObjectPath *op =
        CMNewObjectPath(Broker, ns, "$ClassProvider$", &st);
    CMPIArgs       *in = CMNewArgs(Broker, NULL);
    CMPIArgs       *out = CMNewArgs(Broker, NULL);
    rv = CBInvokeMethod(Broker, ctx, op, "getassocs", in, out, &st);
    if (out) {
      int             i,
                      m;
      CMPIArray      *ar = CMGetArg(out, "assocs", &st).value.array;
      for (i = 0, m = CMGetArrayCount(ar, NULL); i < m; i++) {
        char           *name =
            CMGetArrayElementAt(ar, i, NULL).value.string->hdl;
        if (name) {
          CMPIObjectPath *cop = CMNewObjectPath(Broker, ns, name, NULL);
          if (cop) {
            SafeInternalProviderAddEnumInstances(refs, NULL, ctx, cop,
                                                 propertyList, &st, 1);
          }
        }
        _SFCB_TRACE(1, ("--- assoc %s", name));
      }
    }
  }

  if (role) {
    // filter out the associations not matching the role property
    CMPIInstance   *ci;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIData        data = CMGetProperty(ci, role, NULL);
      if ((data.state & CMPI_notFound) ||
          data.type != CMPI_ref ||
          objectPathEquals(pn, data.value.ref, NULL, 0) == 0) {
        refs->ft->removeCurrent(refs);
      }
    }
    pn->ft->release(pn);
  }

  else {
    // filter out associations not referencing pathName
    CMPIInstance   *ci;
    int             matched,
                    i,
                    m;
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      for (matched = 0, i = 0, m = CMGetPropertyCount(ci, NULL); i < m;
           i++) {
        CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
        if (data.type == CMPI_ref
            && objectPathEquals(pn, data.value.ref, NULL, 0)) {
          matched = 1;
          break;
        }
      }
      if (matched == 0)
        refs->ft->removeCurrent(refs);
    }
    pn->ft->release(pn);
  }

  if (associatorFunction == REF) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMReturnInstance(rslt, ci);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else if (associatorFunction == REF_NAME) {
    CMPIInstance   *ci;
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      CMPIObjectPath *ref = CMGetObjectPath(ci, NULL);
      CMReturnObjectPath(rslt, ref);
    }
    refs->ft->release(refs);
    _SFCB_RETURN(st);
  }

  else {
    // Use hashtable to avoid dup'd associators
    CMPIInstance   *ci;
    UtilHashTable  *assocs =
        UtilFactory->newHashTable(61, UtilHashTable_charKey);
    UtilStringBuffer *pn = normalizeObjectPathStrBuf(cop);
    for (ci = refs->ft->getFirst(refs); ci; ci = refs->ft->getNext(refs)) {
      // Q: for ASSOC_NAME we should not require the
      // object exist if we go by the book, should we?
      // The current approach retrieves the instances
      // via the CIMOM handle
      if (resultRole) {
        CMPIData        data = CMGetProperty(ci, resultRole, NULL);
        UtilStringBuffer *an = NULL;
        if ((data.state & CMPI_notFound) == 0 && data.type == CMPI_ref &&
            objectPathEquals(pn, data.value.ref, &an, 0) == 0) {
          if (resultClass == NULL
              || CMClassPathIsA(Broker, data.value.ref, resultClass,
                                NULL)) {
            CMPIInstance   *aci =
                CBGetInstance(Broker, ctx, data.value.ref, propertyList,
                              &st);
            assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
          }
        }
      }

      else {
        // must loop over the properties to find ref instances
        int             i,
                        m;
        for (i = 0, m = CMGetPropertyCount(ci, NULL); i < m; i++) {
          CMPIData        data = CMGetPropertyAt(ci, i, NULL, NULL);
          if (data.type == CMPI_ref) {
            CMPIObjectPath *ref = data.value.ref;
            CMPIString     *tns = CMGetNameSpace(ref, NULL);
            if (tns == NULL || tns->hdl == NULL)
              CMSetNameSpace(ref, ns);
            UtilStringBuffer *an = NULL;
            if (objectPathEquals(pn, ref, &an, 0) == 0) {

              if (resultClass == NULL
                  || CMClassPathIsA(Broker, ref, resultClass, NULL)) {
                CMPIInstance   *aci =
                    CBGetInstance(Broker, ctx, ref, propertyList, &st);
                if (aci)
                  assocs->ft->put(assocs, an->ft->getCharPtr(an), aci);
              }
            }
          }
        }
      }
    }

    {
      HashTableIterator *it;
      char           *an;
      CMPIInstance   *aci;
      for (it =
           assocs->ft->getFirst(assocs, (void **) &an, (void **) &aci); it;
           it =
           assocs->ft->getNext(assocs, it, (void **) &an,
                               (void **) &aci)) {
        if (associatorFunction == ASSOC)
          CMReturnInstance(rslt, aci);
        else {
          CMPIObjectPath *op = CMGetObjectPath(aci, NULL);
          CMReturnObjectPath(rslt, op);
        }
      }
    }

    refs->ft->release(refs);
    assocs->ft->release(assocs);
    pn->ft->release(pn);
    _SFCB_RETURN(st);

  }
}
CMPIStatus
TestAssociationProviderReferenceNames(CMPIAssociationMI * mi,
                                      const CMPIContext *ctx,
                                      const CMPIResult *rslt,
                                      const CMPIObjectPath * ref,
                                      const char *resultClass,
                                      const char *role)
{
  CMPIInstance   *ci = NULL;
  CMPIObjectPath *op = NULL;
  CMPIObjectPath *rop = NULL;
  CMPIObjectPath *cop = NULL;
  CMPIEnumeration *en = NULL;
  CMPIData        data;

  const char     *targetName = NULL;
  const char     *_thisClassName;
  const char     *_RefLeftClass = NULL;
  const char     *_RefRightClass = NULL;

  CMPIStatus      rc = { CMPI_RC_OK, NULL };
  _thisClassName = _ClassName;

  /*
   * get object path of the target class 
   */
  op = get_assoc_targetClass_ObjectPath(_broker,
                                        ref,
                                        _RefLeftClass,
                                        _RefRightClass, &rc);

  /*
   * check for a failure in creating the object path
   */
  if (rc.rc != CMPI_RC_OK)
    return rc;

  /*
   * the target class does not belong to us so just return CMPI_RC_OK
   */
  if (!op) {
    CMSetStatusWithChars( _broker, &rc, CMPI_RC_OK, NULL );
    return rc;
  }

  /*
   * create new object path of association 
   */
  rop = CMNewObjectPath(_broker,
                        CMGetCharsPtr(CMGetNameSpace(ref, &rc), NULL),
                        _thisClassName, &rc);

  /*
   * upcall to CIMOM; call enumInstanceNames() of the target class 
   */
  en = CBEnumInstanceNames(_broker, ctx, op, &rc);

  /*
   * as long as object path entries are found in the enumeration 
   */
  if (!rc.rc)
    while (CMHasNext(en, &rc)) {
      /*
       * get the object path 
       */
      data = CMGetNext(en, &rc);

      /*
       * create new instance of the association 
       */
      ci = CMNewInstance(_broker, rop, &rc);

      /*
       * get name of the target class 
       */
      targetName = get_assoc_targetClass_Name(_broker,
                                              ref,
                                              _RefLeftClass,
                                              _RefRightClass, &rc);

      /*
       * set the properties of the association instance depending on the
       * constellation of the source class (parameter ref) and the target
       * class (see targetName) 
       */

      if (strcmp(targetName, "CMPI_TEST_Person") == 0) {
        CMSetProperty(ci,
                      "model", (CMPIValue *) & (data.value.ref), CMPI_ref);
        CMSetProperty(ci, "driver", (CMPIValue *) & (ref), CMPI_ref);
      } else if (strcmp(targetName, "CMPI_TEST_Vehicle") == 0) {
        CMSetProperty(ci,
                      "model", (CMPIValue *) & (data.value.ref), CMPI_ref);
        CMSetProperty(ci, "driver", (CMPIValue *) & (ref), CMPI_ref);
      }

      /*
       * get object path of association instance 
       */
      cop = CMGetObjectPath(ci, &rc);

      /*
       * set namespace in object path of association 
       */
      CMSetNameSpace(cop, CMGetCharsPtr(CMGetNameSpace(ref, &rc), NULL));

      /*
       * and return the association object path as result of the
       * referenceNames() call 
       */
      CMReturnObjectPath(rslt, cop);
    }

  return rc;
}
static CMPIStatus raise_indication(const CMPIBroker *broker,
                                   const CMPIContext *ctx,
                                   const CMPIObjectPath *ref,
                                   const CMPIInstance *ind)
{
        struct std_indication_ctx *_ctx = NULL;
        CMPIStatus s = {CMPI_RC_OK, NULL};
        struct ind_args *args = NULL;
        CMPIObjectPath *_ref = NULL;

        _ctx = malloc(sizeof(struct std_indication_ctx));
        if (_ctx == NULL) {
                cu_statusf(broker, &s,
                           CMPI_RC_ERR_FAILED,
                           "Unable to allocate indication context");
                goto out;
        }

        _ctx->brkr = broker;
        _ctx->handler = NULL;
        _ctx->filters = filters;
        _ctx->enabled = 1;

        args = malloc(sizeof(struct ind_args));
        if (args == NULL) {
                cu_statusf(broker, &s,
                           CMPI_RC_ERR_FAILED,
                           "Unable to allocate ind_args");
                goto out;
        }

        _ref = CMGetObjectPath(ind, &s);
        if (_ref == NULL) {
                cu_statusf(broker, &s,
                           CMPI_RC_ERR_FAILED,
                           "Got a null object path");
                goto out;
        }

        /* FIXME:  This is a Pegasus work around. Pegsus loses the namespace
                   when an ObjectPath is pulled from an instance */


        CMSetNameSpace(_ref, "root/virt");
        args->ns = strdup(NAMESPACE(_ref));
        args->classname = strdup(CLASSNAME(_ref));
        args->_ctx = _ctx;

        /* This is a workaround for Pegasus, it loses its objectpath by
           CMGetObjectPath. So set it back. */
        ind->ft->setObjectPath((CMPIInstance *)ind, _ref);

        s = stdi_deliver(broker, ctx, args, (CMPIInstance *)ind);
        if (s.rc == CMPI_RC_OK) {
                CU_DEBUG("Indication delivered");
        } else {
                if (s.msg == NULL) {
                        CU_DEBUG("Not delivered: msg is NULL.");
                } else {
                        CU_DEBUG("Not delivered: %s", CMGetCharPtr(s.msg));
                }
        }

 out:
        if (args != NULL)
                stdi_free_ind_args(&args);

        if (_ctx != NULL)
                free(_ctx);

        return s;
}
static int
_testCMPIObjectPath()
{
  CMPIStatus      rc = { CMPI_RC_OK, NULL };

  CMPIObjectPath *objPath = NULL;
  CMPIObjectPath *clonedObjPath = NULL;
  CMPIObjectPath *otherObjPath = NULL;
  CMPIObjectPath *fakeObjPath = NULL;

  const char     *hostName = "HOSTNAME";
  const char     *nameSpace = "root/dummy";
  const char     *className = "classname";

  CMPIString     *returnedHostname = NULL;
  CMPIBoolean     equalHostname = 0;
  CMPIString     *returnedNamespace = NULL;
  CMPIBoolean     equalNamespace = 0;
  CMPIString     *returnedClassName;
  CMPIBoolean     equalClassName = 0;
  CMPIString     *returnedObjectPath;
  CMPIBoolean     cloneSuccessful = 0;
  CMPIBoolean     getKeySuccessful = 0;
  CMPIBoolean     getKeyCountSuccessful = 0;
  CMPIBoolean     getKeyAtSuccessful = 0;
  const char     *objectPath1 = NULL;
  const char     *objectPath2 = NULL;
  CMPIData        data;
  CMPIValue       value;
  unsigned int    keyCount = 0;
  objPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  rc = CMSetHostname(objPath, hostName);
  returnedHostname = CMGetHostname(objPath, &rc);
  if (strcmp(hostName, CMGetCharsPtr(returnedHostname, &rc)) == 0) {
    equalHostname = 1;
  }
  rc = CMSetNameSpace(objPath, nameSpace);
  returnedNamespace = CMGetNameSpace(objPath, &rc);
  if (strcmp(nameSpace, CMGetCharsPtr(returnedNamespace, &rc)) == 0) {
    equalNamespace = 1;
  }
  rc = CMSetClassName(objPath, className);
  returnedClassName = CMGetClassName(objPath, &rc);
  if (strcmp(className, CMGetCharsPtr(returnedClassName, &rc)) == 0) {
    equalClassName = 1;
  }
  otherObjPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  returnedNamespace = CMGetNameSpace(otherObjPath, &rc);
  rc = CMSetNameSpaceFromObjectPath(otherObjPath, objPath);
  returnedNamespace = CMGetNameSpace(otherObjPath, &rc);
  if (strcmp(nameSpace, CMGetCharsPtr(returnedNamespace, &rc)) == 0) {
    equalNamespace = 1;
  }
  returnedHostname = CMGetHostname(otherObjPath, &rc);
  rc = CMSetHostAndNameSpaceFromObjectPath(otherObjPath, objPath);
  returnedHostname = CMGetHostname(otherObjPath, &rc);
  if (strcmp(hostName, CMGetCharsPtr(returnedHostname, &rc)) == 0) {
    equalHostname = 1;
  }
  returnedObjectPath = CMObjectPathToString(objPath, &rc);
  objectPath1 = CMGetCharsPtr(returnedObjectPath, &rc);
  clonedObjPath = objPath->ft->clone(objPath, &rc);
  returnedObjectPath = CMObjectPathToString(clonedObjPath, &rc);
  rc = clonedObjPath->ft->release(clonedObjPath);
  objectPath2 = CMGetCharsPtr(returnedObjectPath, &rc);
  if (strcmp(objectPath1, objectPath2) == 0) {
    cloneSuccessful = 1;
  } else {
    cloneSuccessful = 0;
  }
  fakeObjPath = CMNewObjectPath(_broker, "root#cimv2",
                                "Sample_Instance", &rc);
  rc = CMAddKey(fakeObjPath, "ElementName",
                (CMPIValue *) "Fake", CMPI_chars);
  rc = CMAddKey(otherObjPath, "ElementName1",
                (CMPIValue *) "otherObjPath", CMPI_chars);
  data = CMGetKey(fakeObjPath, "ElementName", &rc);
  if (strcmp(CMGetCharsPtr(data.value.string, &rc), "Fake") == 0) {
    getKeySuccessful = 1;
  }
  keyCount = CMGetKeyCount(fakeObjPath, &rc);
  if (keyCount == 1) {
    getKeyCountSuccessful = 1;
  }
  data = CMGetKeyAt(fakeObjPath, 0, NULL, &rc);
  if (rc.rc == 0) {
    getKeyAtSuccessful = 1;
  }
  value.uint16 = 67;
  rc = CMAddKey(fakeObjPath, "Numeric_key_unsigned",
                (CMPIValue *) & value, CMPI_uint16);
  data = CMGetKey(fakeObjPath, "Numeric_key_unsigned", &rc);
  value.sint16 = -67;
  rc = CMAddKey(fakeObjPath, "Numeric_key_signed",
                (CMPIValue *) & value, CMPI_sint16);
  data = CMGetKey(fakeObjPath, "Numeric_key_signed", &rc);
  value.boolean = 1;
  rc = CMAddKey(fakeObjPath, "Boolean_key",
                (CMPIValue *) & value, CMPI_boolean);
  data = CMGetKey(fakeObjPath, "Boolean_key", &rc);
  CMGetKeyAt(objPath, 500, NULL, &rc);
  if (rc.rc != CMPI_RC_ERR_NO_SUCH_PROPERTY) {
    return 1;
  }
  rc = objPath->ft->release(objPath);
  rc = fakeObjPath->ft->release(fakeObjPath);
  return 0;
}
static int
_testCMPIInstance()
{
  CMPIStatus      rc = { CMPI_RC_OK, NULL };

  CMPIInstance   *instance = NULL;
  CMPIInstance   *clonedInstance = NULL;
  CMPIObjectPath *objPath = NULL;
  CMPIObjectPath *newObjPath = NULL;
  CMPIObjectPath *returnedObjPath = NULL;

  CMPIData        returnedData1;
  CMPIData        returnedData2;
  CMPIData        clonedData1;

  CMPIString     *returnedName = NULL;
  unsigned int    count = 0;
  const char     *name1 = "firstPropertyName";
  CMPIValue       value1;
  const char     *name2 = "secondPropertyName";
  CMPIValue       value2;
  CMPIType        type = CMPI_uint64;
  CMPIBoolean     dataEqual = 0;
  CMPIBoolean     objectPathEqual = 0;
  CMPIBoolean     cloneSuccessful = 0;
  CMPIString     *beforeObjPath = NULL;
  CMPIString     *afterObjPath = NULL;
  const char     *beforeString = NULL;
  const char     *afterString = NULL;
  objPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  instance = make_Instance(objPath);
  value1.uint32 = 10;
  rc = CMSetProperty(instance, name1, &value1, type);
  value2.uint32 = 20;
  rc = CMSetProperty(instance, name2, &value2, type);
  count = CMGetPropertyCount(instance, &rc);
  returnedData1 = CMGetProperty(instance, name1, &rc);
  if (returnedData1.value.uint32 == 10) {
    dataEqual = 1;
  }
  returnedData2 = CMGetPropertyAt(instance, 2, &returnedName, &rc);
  if (returnedData2.value.uint32 == 20) {
    dataEqual = 1;
  }
  newObjPath = make_ObjectPath(_broker, _Namespace, _ClassName);
  returnedObjPath = CMGetObjectPath(instance, &rc);
  beforeObjPath = CMObjectPathToString(returnedObjPath, &rc);
  beforeString = CMGetCharsPtr(beforeObjPath, &rc);
  rc = CMSetNameSpace(newObjPath, "newNamespace");
  rc = CMSetObjectPath(instance, newObjPath);
  returnedObjPath = CMGetObjectPath(instance, &rc);
  afterObjPath = CMObjectPathToString(returnedObjPath, &rc);
  afterString = CMGetCharsPtr(afterObjPath, &rc);
  afterString = CMGetCharsPtr(CMGetNameSpace(returnedObjPath, &rc), &rc);
  if (strcmp("newNamespace", afterString) == 0) {
    objectPathEqual = 1;
  }
  clonedInstance = instance->ft->clone(instance, &rc);
  clonedData1 = CMGetProperty(clonedInstance, name1, &rc);
  rc = clonedInstance->ft->release(clonedInstance);
  if (returnedData1.value.uint32 == clonedData1.value.uint32) {
    cloneSuccessful = 1;
  } else {
    cloneSuccessful = 0;
  }
  CMGetProperty(instance, "noProperty", &rc);
  if (rc.rc != CMPI_RC_ERR_NO_SUCH_PROPERTY) {
    return 1;
  }

  CMGetPropertyAt(instance, 100, &returnedName, &rc);
  if (rc.rc != CMPI_RC_ERR_NO_SUCH_PROPERTY) {
    return 1;
  }
  rc = instance->ft->release(instance);
  return 0;
}