private void addParamEdges(LocalPointerKey pk, CGNode node) {
   // get parameter position: value number - 1?
   int paramPos = pk.getValueNumber() - 1;
   // iterate over callers
   for (CGNode caller : cg) {
     // TODO we don't need to add the graph if null is passed
     // as the argument
     addSubgraphForNode(caller);
     IR ir = caller.getIR();
     for (Iterator<CallSiteReference> iterator = ir.iterateCallSites(); iterator.hasNext(); ) {
       CallSiteReference call = iterator.next();
       if (cg.getPossibleTargets(caller, call).contains(node)) {
         SSAAbstractInvokeInstruction[] callInstrs = ir.getCalls(call);
         for (int i = 0; i < callInstrs.length; i++) {
           SSAAbstractInvokeInstruction callInstr = callInstrs[i];
           PointerKey actualPk =
               heapModel.getPointerKeyForLocal(caller, callInstr.getUse(paramPos));
           assert containsNode(actualPk);
           assert containsNode(pk);
           addEdge(pk, actualPk);
         }
       }
     }
   }
 }
 @Override
 public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
   if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
     assert cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root));
     IR callerIR = caller.getIR();
     SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls(site);
     assert callStmts.length == 1;
     int nargs = callStmts[0].getNumberOfParameters();
     return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs - 1);
   } else {
     return base.getCalleeTarget(caller, site, receiver);
   }
 }