static int doDescribeInstances(struct nc_state_t *nc, ncMetadata * pMeta, char **instIds, int instIdsLen, ncInstance *** outInsts, int *outInstsLen)
{
    ncInstance *instance = NULL;
    ncInstance *tmp = NULL;
    int total = 0;
    int i = 0;
    int j = 0;
    int k = 0;

    LOGDEBUG("invoked userId=%s correlationId=%s epoch=%d services[0]{.name=%s .type=%s .uris[0]=%s}\n",
             SP(pMeta->userId), SP(pMeta->correlationId), pMeta->epoch, SP(pMeta->services[0].name), SP(pMeta->services[0].type), SP(pMeta->services[0].uris[0]));

    *outInstsLen = 0;
    *outInsts = NULL;

    sem_p(inst_copy_sem);
    if (instIdsLen == 0)               // describe all instances
        total = total_instances(&global_instances_copy);
    else
        total = instIdsLen;

    *outInsts = EUCA_ZALLOC(total, sizeof(ncInstance *));
    if ((*outInsts) == NULL) {
        sem_v(inst_copy_sem);
        return EUCA_MEMORY_ERROR;
    }

    k = 0;
    for (i = 0; (instance = get_instance(&global_instances_copy)) != NULL; i++) {
        // only pick ones the user (or admin) is allowed to see
        if (strcmp(pMeta->userId, nc->admin_user_id)
            && strcmp(pMeta->userId, instance->userId))
            continue;

        if (instIdsLen > 0) {
            for (j = 0; j < instIdsLen; j++)
                if (!strcmp(instance->instanceId, instIds[j]))
                    break;

            if (j >= instIdsLen)
                // instance of no relevance right now
                continue;
        }
        // (* outInsts)[k++] = instance;
        tmp = (ncInstance *) EUCA_ALLOC(1, sizeof(ncInstance));
        memcpy(tmp, instance, sizeof(ncInstance));
        (*outInsts)[k++] = tmp;
    }
    *outInstsLen = k;
    sem_v(inst_copy_sem);

    return EUCA_OK;
}
static int doDescribeInstances(struct nc_state_t *nc, ncMetadata * pMeta, char **instIds, int instIdsLen, ncInstance *** outInsts, int *outInstsLen)
{
    ncInstance *instance = NULL;
    ncInstance *tmp = NULL;
    int total = 0;
    int i = 0;
    int j = 0;
    int k = 0;

    LOGDEBUG("invoked userId=%s correlationId=%s epoch=%d services[0]{.name=%s .type=%s .uris[0]=%s}\n",
             SP(pMeta->userId), SP(pMeta->correlationId), pMeta->epoch, SP(pMeta->services[0].name), SP(pMeta->services[0].type), SP(pMeta->services[0].uris[0]));

    *outInstsLen = 0;
    *outInsts = NULL;

    sem_p(inst_copy_sem);
    if (instIdsLen == 0)                
        total = total_instances(&global_instances_copy);
    else
        total = instIdsLen;

    *outInsts = EUCA_ZALLOC(total, sizeof(ncInstance *));
    if ((*outInsts) == NULL) {
        sem_v(inst_copy_sem);
        return EUCA_MEMORY_ERROR;
    }

    k = 0;
    for (i = 0; (instance = get_instance(&global_instances_copy)) != NULL; i++) {
         
        if (strcmp(pMeta->userId, nc->admin_user_id)
            && strcmp(pMeta->userId, instance->userId))
            continue;

        if (instIdsLen > 0) {
            for (j = 0; j < instIdsLen; j++)
                if (!strcmp(instance->instanceId, instIds[j]))
                    break;

            if (j >= instIdsLen)
                 
                continue;
        }
         
        tmp = (ncInstance *) EUCA_ALLOC(1, sizeof(ncInstance));
        memcpy(tmp, instance, sizeof(ncInstance));
        (*outInsts)[k++] = tmp;
    }
    *outInstsLen = k;
    sem_v(inst_copy_sem);

    return EUCA_OK;
}