const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
CallXPCOMMethod(JNIEnv *env, jclass that, jobject aJavaObject,                jint aMethodIndex, jobjectArray aParams, jvalue &aResult){  // Find corresponding XPCOM object  void* xpcomObj = GetMatchingXPCOMObject(env, aJavaObject);  NS_ASSERTION(xpcomObj != nsnull, "Failed to get matching XPCOM object");  if (xpcomObj == nsnull) {    ThrowXPCOMException(env, 0);    return;  }  NS_ASSERTION(!IsXPTCStub(xpcomObj), "Expected JavaXPCOMInstance, but got nsJavaXPTCStub");  JavaXPCOMInstance* inst = (JavaXPCOMInstance*) xpcomObj;  // Get method info  const nsXPTMethodInfo* methodInfo;  nsIInterfaceInfo* iinfo = inst->InterfaceInfo();  nsresult rv = iinfo->GetMethodInfo(aMethodIndex, &methodInfo);  NS_ASSERTION(NS_SUCCEEDED(rv), "GetMethodInfo failed");  #ifdef DEBUG  const char* ifaceName;  iinfo->GetNameShared(&ifaceName);  LOG("=> Calling %s::%s()\n", ifaceName, methodInfo->GetName());#endif  PRUint8 paramCount = methodInfo->GetParamCount();  nsXPTCVariant* params = nsnull;  if (paramCount)  {    params = new nsXPTCVariant[paramCount];    for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)    {      LOG("\t Param %d: ", i);      const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);      if (!paramInfo.IsRetval() && !paramInfo.IsDipper()) {        rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,                         methodInfo, iinfo, aMethodIndex, params, params[i]);      } else if (paramInfo.IsDipper()) {        LOG("dipper");        const nsXPTType &type = paramInfo.GetType();        switch (type.TagPart())        {          case nsXPTType::T_ASTRING:          case nsXPTType::T_DOMSTRING:            params[i].val.p = params[i].ptr = new nsString();            params[i].type = type;            params[i].flags = nsXPTCVariant::PTR_IS_DATA |                              nsXPTCVariant::VAL_IS_DOMSTR;            break;          case nsXPTType::T_UTF8STRING:          case nsXPTType::T_CSTRING:            params[i].val.p = params[i].ptr = new nsCString();            params[i].type = type;            params[i].flags = nsXPTCVariant::PTR_IS_DATA |                              nsXPTCVariant::VAL_IS_CSTR;            break;          default:            LOG("unhandled dipper type\n");            rv = NS_ERROR_UNEXPECTED;        }      } else {        LOG("retval\n");        params[i].ptr = &(params[i].val);        params[i].type = paramInfo.GetType();        params[i].flags = nsXPTCVariant::PTR_IS_DATA;      }    }    if (NS_FAILED(rv)) {      NS_WARNING("SetupParams failed");      ThrowXPCOMException(env, rv);      return;    }  }  nsresult invokeResult;  invokeResult = XPTC_InvokeByIndex(inst->GetInstance(), aMethodIndex,                                    paramCount, params);  for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)  {    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);    if (!paramInfo.IsRetval()) {      rv = FinalizeParams(env, env->GetObjectArrayElement(aParams, i),                          paramInfo, methodInfo, iinfo, aMethodIndex,                          params, params[i]);    } else {      rv = SetRetval(env, paramInfo, methodInfo, iinfo, aMethodIndex, params,                     params[i], aResult);    }  }  if (NS_FAILED(rv)) {    NS_WARNING("FinalizeParams failed");    ThrowXPCOMException(env, rv);    return;  }  // XXX Normally, we would delete any created nsID object in the above loop.  //  However, GetIIDForMethodParam may need some of the nsID params when it's  //  looking for the IID of an INTERFACE_IS.  Therefore, we can't delete it  //  until we've gone through the 'Finalize' loop once and created the result.  for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)  {    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);    const nsXPTType &type = paramInfo.GetType();    if (type.TagPart() == nsXPTType::T_IID) {      nsID* iid = (nsID*) params[i].ptr;      delete iid;    }  }  if (params) {    delete params;  }  // If the XPCOM method invocation failed, we don't immediately throw an  // exception and return so that we can clean up any parameters.  if (NS_FAILED(invokeResult)) {    ThrowXPCOMException(env, invokeResult);  }  return;}