changes: now Inference engine works fine with the EyeTracking benchmark.
[IRC.git] / Robust / src / Analysis / SSJava / LocationInference.java
index c3440672619a9a869369314d5551ee0622ab58d9..8c1c97926e25814c8f21649d7c1c6bed7ba6b612 100644 (file)
@@ -370,6 +370,26 @@ public class LocationInference {
     System.out.println("\nSSJAVA: Add addtional ordering constriants:");
     MethodDescriptor methodEventLoopDesc = ssjava.getMethodContainingSSJavaLoop();
     addAddtionalOrderingConstraints(methodEventLoopDesc);
+    // calculateReturnHolderLocation();
+  }
+
+  private void calculateReturnHolderLocation() {
+    LinkedList<MethodDescriptor> methodDescList =
+        (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+    while (!methodDescList.isEmpty()) {
+      MethodDescriptor md = methodDescList.removeLast();
+
+      FlowGraph fg = getFlowGraph(md);
+      Set<FlowNode> nodeSet = fg.getNodeSet();
+      for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
+        FlowNode flowNode = (FlowNode) iterator.next();
+        if (flowNode.isFromHolder()) {
+          calculateCompositeLocationFromFlowGraph(md, flowNode);
+        }
+      }
+
+    }
   }
 
   private void updateCompositeLocationAssignments() {
@@ -560,19 +580,53 @@ public class LocationInference {
       //
       // update return flow nodes in the caller
       CompositeLocation returnLoc = getMethodSummary(mdCallee).getRETURNLoc();
-
       System.out.println("### min=" + min.printNode(0) + "  returnLoc=" + returnLoc);
       if (returnLoc != null && returnLoc.get(0).getLocDescriptor().equals(mdCallee.getThis())
           && returnLoc.getSize() > 1) {
         System.out.println("###RETURN COMP LOC=" + returnLoc);
         NTuple<Location> returnLocTuple = returnLoc.getTuple();
         NTuple<Descriptor> baseTuple = mapMethodInvokeNodeToBaseTuple.get(min);
+        System.out.println("###basetuple=" + baseTuple);
         NTuple<Descriptor> newReturnTuple = baseTuple.clone();
         for (int i = 1; i < returnLocTuple.size(); i++) {
           newReturnTuple.add(returnLocTuple.get(i).getLocDescriptor());
         }
         System.out.println("###NEW RETURN TUPLE FOR CALLER=" + newReturnTuple);
+
+        FlowReturnNode holderNode = callerFlowGraph.getFlowReturnNode(min);
+        NodeTupleSet holderTupleSet =
+            getNodeTupleSetFromReturnNode(getFlowGraph(mdCaller), holderNode);
+
         callerFlowGraph.getFlowReturnNode(min).setNewTuple(newReturnTuple);
+
+        // then need to remove old constraints
+        // TODO SAT
+        System.out.println("###REMOVE OLD CONSTRAINTS=" + holderNode);
+        for (Iterator<NTuple<Descriptor>> iter = holderTupleSet.iterator(); iter.hasNext();) {
+          NTuple<Descriptor> tupleFromHolder = iter.next();
+          Set<FlowEdge> holderOutEdge = callerFlowGraph.getOutEdgeSet(holderNode);
+          for (Iterator iterator2 = holderOutEdge.iterator(); iterator2.hasNext();) {
+            FlowEdge outEdge = (FlowEdge) iterator2.next();
+            NTuple<Descriptor> toberemovedTuple = outEdge.getEndTuple();
+            System.out.println("---remove " + tupleFromHolder + " -> " + toberemovedTuple);
+            callerFlowGraph.removeEdge(tupleFromHolder, toberemovedTuple);
+          }
+        }
+
+      } else {
+        // if the return loc set was empty and later pcloc was connected to the return loc
+        // need to make sure that return loc reflects to this changes.
+        FlowReturnNode flowReturnNode = callerFlowGraph.getFlowReturnNode(min);
+        if (flowReturnNode != null && flowReturnNode.getReturnTupleSet().isEmpty()) {
+
+          if (needToUpdateReturnLocHolder(min.getMethod(), flowReturnNode)) {
+            NTuple<Descriptor> baseTuple = mapMethodInvokeNodeToBaseTuple.get(min);
+            NTuple<Descriptor> newReturnTuple = baseTuple.clone();
+            flowReturnNode.addTuple(newReturnTuple);
+          }
+
+        }
+
       }
 
     }
@@ -584,6 +638,23 @@ public class LocationInference {
 
   }
 
+  private boolean needToUpdateReturnLocHolder(MethodDescriptor mdCallee,
+      FlowReturnNode flowReturnNode) {
+    FlowGraph fg = getFlowGraph(mdCallee);
+    MethodSummary summary = getMethodSummary(mdCallee);
+    CompositeLocation returnCompLoc = summary.getRETURNLoc();
+    NTuple<Descriptor> returnDescTuple = translateToDescTuple(returnCompLoc.getTuple());
+    Set<FlowNode> incomingNodeToReturnNode =
+        fg.getIncomingFlowNodeSet(fg.getFlowNode(returnDescTuple));
+    for (Iterator iterator = incomingNodeToReturnNode.iterator(); iterator.hasNext();) {
+      FlowNode inNode = (FlowNode) iterator.next();
+      if (inNode.getDescTuple().get(0).equals(mdCallee.getThis())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   private void addMapMethodDescToMethodInvokeNodeSet(MethodInvokeNode min) {
     MethodDescriptor md = min.getMethod();
     if (!mapMethodDescToMethodInvokeNodeSet.containsKey(md)) {
@@ -627,6 +698,7 @@ public class LocationInference {
             System.out.println("----- add global flow globalArgLocTuple=" + globalArgLocTuple
                 + "-> globalParamLocTuple=" + globalParamLocTuple);
             hasChanges = true;
+            System.out.println("B1");
             globalGraph.addValueFlowEdge(globalArgLocTuple, globalParamLocTuple);
           }
         }
@@ -642,6 +714,8 @@ public class LocationInference {
                       + "-> globalParamLocTu!globalArgLocTuple.get(0).getLocDescriptor().equals(LITERALDESC)ple="
                       + globalParamLocTuple);
               hasChanges = true;
+              System.out.println("B2");
+
               globalGraph.addValueFlowEdge(pcLocTuple, globalParamLocTuple);
             }
           }
@@ -678,6 +752,8 @@ public class LocationInference {
     System.out.println("generateCompositeLocation=" + nodeDescTuple + " with inferCompLoc="
         + inferCompLoc);
 
+    MethodDescriptor md = (MethodDescriptor) inferCompLoc.get(0).getDescriptor();
+
     CompositeLocation newCompLoc = new CompositeLocation();
     for (int i = 0; i < inferCompLoc.getSize(); i++) {
       newCompLoc.addLocation(inferCompLoc.get(i));
@@ -686,7 +762,7 @@ public class LocationInference {
     Descriptor lastDescOfPrefix = nodeDescTuple.get(0);
     Descriptor enclosingDescriptor;
     if (lastDescOfPrefix instanceof InterDescriptor) {
-      enclosingDescriptor = null;
+      enclosingDescriptor = getFlowGraph(md).getEnclosingDescriptor(lastDescOfPrefix);
     } else {
       enclosingDescriptor = ((VarDescriptor) lastDescOfPrefix).getType().getClassDesc();
     }
@@ -1256,6 +1332,7 @@ public class LocationInference {
 
     MethodDescriptor md = (MethodDescriptor) targetLocalLoc.getDescriptor();
     FlowGraph flowGraph = getFlowGraph(md);
+
     FlowNode flowNode = flowGraph.getFlowNode(node.getDescTuple());
     Set<FlowNode> reachableSet = flowGraph.getReachFlowNodeSetFrom(flowNode);
 
@@ -1504,6 +1581,132 @@ public class LocationInference {
 
   }
 
+  private CompositeLocation calculateCompositeLocationFromFlowGraph(MethodDescriptor md,
+      FlowNode node) {
+
+    System.out.println("#############################################################");
+    System.out.println("calculateCompositeLocationFromFlowGraph=" + node);
+
+    FlowGraph flowGraph = getFlowGraph(md);
+    // NTuple<Location> paramLocTuple = translateToLocTuple(md, paramNode.getDescTuple());
+    // GlobalFlowNode paramGlobalNode = subGlobalFlowGraph.getFlowNode(paramLocTuple);
+
+    List<NTuple<Location>> prefixList = calculatePrefixListFlowGraph(flowGraph, node);
+
+    // Set<GlobalFlowNode> reachableNodeSet =
+    // subGlobalFlowGraph.getReachableNodeSetByPrefix(paramGlobalNode.getLocTuple().get(0));
+    //
+    Set<FlowNode> reachableNodeSet =
+        flowGraph.getReachableSetFrom(node.getDescTuple().subList(0, 1));
+
+    // Set<GlobalFlowNode> reachNodeSet = globalFlowGraph.getReachableNodeSetFrom(node);
+
+    // System.out.println("node=" + node + "    prefixList=" + prefixList);
+
+    for (int i = 0; i < prefixList.size(); i++) {
+      NTuple<Location> curPrefix = prefixList.get(i);
+      Set<NTuple<Location>> reachableCommonPrefixSet = new HashSet<NTuple<Location>>();
+
+      for (Iterator iterator2 = reachableNodeSet.iterator(); iterator2.hasNext();) {
+        FlowNode reachNode = (FlowNode) iterator2.next();
+        NTuple<Location> reachLocTuple = translateToLocTuple(md, reachNode.getCurrentDescTuple());
+        if (reachLocTuple.startsWith(curPrefix)) {
+          reachableCommonPrefixSet.add(reachLocTuple);
+        }
+      }
+      // System.out.println("reachableCommonPrefixSet=" + reachableCommonPrefixSet);
+
+      if (!reachableCommonPrefixSet.isEmpty()) {
+
+        MethodDescriptor curPrefixFirstElementMethodDesc =
+            (MethodDescriptor) curPrefix.get(0).getDescriptor();
+
+        // MethodDescriptor nodePrefixLocFirstElementMethodDesc =
+        // (MethodDescriptor) prefixLoc.getDescriptor();
+
+        // System.out.println("curPrefixFirstElementMethodDesc=" +
+        // curPrefixFirstElementMethodDesc);
+        // System.out.println("nodePrefixLocFirstElementMethodDesc="
+        // + nodePrefixLocFirstElementMethodDesc);
+
+        // TODO
+        // if (!node.getLocTuple().startsWith(curPrefix.get(0))) {
+
+        Location curPrefixLocalLoc = curPrefix.get(0);
+
+        Location targetLocalLoc = new Location(md, node.getDescTuple().get(0));
+        // Location targetLocalLoc = paramGlobalNode.getLocTuple().get(0);
+
+        CompositeLocation newCompLoc = generateCompositeLocation(curPrefix);
+        System.out.println("NEED2ASSIGN COMP LOC TO " + node + " with prefix=" + curPrefix);
+        System.out.println("-targetLocalLoc=" + targetLocalLoc + "   - newCompLoc=" + newCompLoc);
+
+        // // makes sure that a newly generated location appears in the hierarchy graph
+        // for (int compIdx = 0; compIdx < newCompLoc.getSize(); compIdx++) {
+        // Location curLoc = newCompLoc.get(compIdx);
+        // getHierarchyGraph(curLoc.getDescriptor()).getHNode(curLoc.getLocDescriptor());
+        // }
+        // subGlobalFlowGraph.addMapLocationToInferCompositeLocation(targetLocalLoc, newCompLoc);
+        node.setCompositeLocation(newCompLoc);
+
+        return newCompLoc;
+
+      }
+
+    }
+    return null;
+  }
+
+  private List<NTuple<Location>> calculatePrefixListFlowGraph(FlowGraph graph, FlowNode node) {
+
+    System.out.println("\n##### calculatePrefixList node=" + node);
+
+    MethodDescriptor md = graph.getMethodDescriptor();
+    Set<FlowNode> incomingNodeSetPrefix =
+        graph.getIncomingNodeSetByPrefix(node.getDescTuple().get(0));
+    // System.out.println("---incomingNodeSetPrefix=" + incomingNodeSetPrefix);
+
+    Set<FlowNode> reachableNodeSetPrefix =
+        graph.getReachableSetFrom(node.getDescTuple().subList(0, 1));
+    // System.out.println("---reachableNodeSetPrefix=" + reachableNodeSetPrefix);
+
+    List<NTuple<Location>> prefixList = new ArrayList<NTuple<Location>>();
+
+    for (Iterator iterator = incomingNodeSetPrefix.iterator(); iterator.hasNext();) {
+      FlowNode inNode = (FlowNode) iterator.next();
+      NTuple<Location> inNodeTuple = translateToLocTuple(md, inNode.getCurrentDescTuple());
+
+      // if (inNodeTuple.get(0).getLocDescriptor() instanceof InterDescriptor
+      // || inNodeTuple.get(0).getLocDescriptor().equals(GLOBALDESC)) {
+      // continue;
+      // }
+
+      for (int i = 1; i < inNodeTuple.size(); i++) {
+        NTuple<Location> prefix = inNodeTuple.subList(0, i);
+        if (!prefixList.contains(prefix)) {
+          prefixList.add(prefix);
+        }
+      }
+    }
+
+    Collections.sort(prefixList, new Comparator<NTuple<Location>>() {
+      public int compare(NTuple<Location> arg0, NTuple<Location> arg1) {
+        int s0 = arg0.size();
+        int s1 = arg1.size();
+        if (s0 > s1) {
+          return -1;
+        } else if (s0 == s1) {
+          return 0;
+        } else {
+          return 1;
+        }
+      }
+    });
+
+    return prefixList;
+
+  }
+
   private boolean containsClassDesc(ClassDescriptor cd, NTuple<Location> prefixLocTuple) {
     for (int i = 0; i < prefixLocTuple.size(); i++) {
       Location loc = prefixLocTuple.get(i);
@@ -1559,6 +1762,7 @@ public class LocationInference {
       // Location loc = new Location(md, dstVarDesc);
       // dstLocTuple.add(loc);
       // }
+      System.out.println("B11");
 
       globalGraph.addValueFlowEdge(srcLocTuple, dstLocTuple);
 
@@ -1572,7 +1776,6 @@ public class LocationInference {
     NTuple<Location> locTuple = new NTuple<Location>();
 
     Descriptor enclosingDesc = md;
-    // System.out.println("md=" + md + "  descTuple=" + descTuple);
     for (int i = 0; i < descTuple.size(); i++) {
       Descriptor desc = descTuple.get(i);
 
@@ -1672,6 +1875,8 @@ public class LocationInference {
         if (callerSrcNodeLocTuple != null && callerSrcNodeLocTuple.size() > 0) {
           for (Iterator iterator2 = pcLocTupleSet.iterator(); iterator2.hasNext();) {
             NTuple<Location> pcLocTuple = (NTuple<Location>) iterator2.next();
+            System.out.println("B12");
+
             callerSubGlobalGraph.addValueFlowEdge(pcLocTuple, callerSrcNodeLocTuple);
           }
         }
@@ -1687,11 +1892,11 @@ public class LocationInference {
     GlobalFlowGraph calleeSubGlobalGraph = getSubGlobalFlowGraph(mdCallee);
     GlobalFlowGraph callerSubGlobalGraph = getSubGlobalFlowGraph(mdCaller);
 
-    // System.out.println("$addValueFlowFromCalleeNode calleeSrcNode=" + calleeSrcNode);
+    System.out.println("$addValueFlowFromCalleeNode calleeSrcNode=" + calleeSrcNode);
 
     NTuple<Location> callerSrcNodeLocTuple =
         translateToCallerLocTuple(min, mdCallee, mdCaller, calleeSrcNode.getLocTuple());
-    // System.out.println("---callerSrcNodeLocTuple=" + callerSrcNodeLocTuple);
+    System.out.println("---callerSrcNodeLocTuple=" + callerSrcNodeLocTuple);
 
     if (callerSrcNodeLocTuple != null && callerSrcNodeLocTuple.size() > 0) {
 
@@ -1703,7 +1908,9 @@ public class LocationInference {
             translateToCallerLocTuple(min, mdCallee, mdCaller, outNode.getLocTuple());
         // System.out.println("outNode=" + outNode + "   callerDstNodeLocTuple="
         // + callerDstNodeLocTuple);
-        if (callerDstNodeLocTuple != null) {
+        if (callerSrcNodeLocTuple != null && callerDstNodeLocTuple != null
+            && callerSrcNodeLocTuple.size() > 0 && callerDstNodeLocTuple.size() > 0) {
+          System.out.println("B3");
           callerSubGlobalGraph.addValueFlowEdge(callerSrcNodeLocTuple, callerDstNodeLocTuple);
         }
       }
@@ -1716,8 +1923,9 @@ public class LocationInference {
     // this method will return the same nodeLocTuple if the corresponding argument is literal
     // value.
 
-    FlowGraph calleeFlowGraph = getFlowGraph(mdCallee);
+    // System.out.println("translateToCallerLocTuple=" + nodeLocTuple);
 
+    FlowGraph calleeFlowGraph = getFlowGraph(mdCallee);
     NTuple<Descriptor> nodeDescTuple = translateToDescTuple(nodeLocTuple);
     if (calleeFlowGraph.isParameter(nodeDescTuple)) {
       int paramIdx = calleeFlowGraph.getParamIdx(nodeDescTuple);
@@ -1727,7 +1935,8 @@ public class LocationInference {
       // // the type of argument is primitive.
       // return nodeLocTuple.clone();
       // }
-      // System.out.println("paramIdx=" + paramIdx + "  argDescTuple=" + argDescTuple);
+      // System.out.println("paramIdx=" + paramIdx + "  argDescTuple=" + argDescTuple + " from min="
+      // + min.printNode(0));
       NTuple<Location> argLocTuple = translateToLocTuple(mdCaller, argDescTuple);
 
       NTuple<Location> callerLocTuple = new NTuple<Location>();
@@ -1762,7 +1971,7 @@ public class LocationInference {
 
       TypeDescriptor type = ((FieldDescriptor) desc).getType();
       if (type.isArray()) {
-        return false;
+        return !type.isPrimitive();
       } else {
         return type.isPtr();
       }
@@ -1770,7 +1979,7 @@ public class LocationInference {
     } else if (desc instanceof VarDescriptor) {
       TypeDescriptor type = ((VarDescriptor) desc).getType();
       if (type.isArray()) {
-        return false;
+        return !type.isPrimitive();
       } else {
         return type.isPtr();
       }
@@ -2159,6 +2368,60 @@ public class LocationInference {
 
   private void constructHierarchyGraph() {
 
+    LinkedList<MethodDescriptor> methodDescList =
+        (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
+
+    while (!methodDescList.isEmpty()) {
+      MethodDescriptor md = methodDescList.removeLast();
+      if (state.SSJAVADEBUG) {
+        HierarchyGraph hierarchyGraph = new HierarchyGraph(md);
+        System.out.println();
+        System.out.println("SSJAVA: Construcing the hierarchy graph from " + md);
+        constructHierarchyGraph(md, hierarchyGraph);
+        mapDescriptorToHierarchyGraph.put(md, hierarchyGraph);
+
+      }
+    }
+
+    setupToAnalyze();
+    while (!toAnalyzeIsEmpty()) {
+      ClassDescriptor cd = toAnalyzeNext();
+      HierarchyGraph graph = getHierarchyGraph(cd);
+      for (Iterator iter = cd.getFields(); iter.hasNext();) {
+        FieldDescriptor fieldDesc = (FieldDescriptor) iter.next();
+        if (!(fieldDesc.isStatic() && fieldDesc.isFinal())) {
+          graph.getHNode(fieldDesc);
+        }
+      }
+    }
+
+    Set<Descriptor> keySet = mapDescriptorToHierarchyGraph.keySet();
+    for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+      Descriptor key = (Descriptor) iterator.next();
+      HierarchyGraph graph = getHierarchyGraph(key);
+
+      Set<HNode> nodeToBeConnected = new HashSet<HNode>();
+      for (Iterator iterator2 = graph.getNodeSet().iterator(); iterator2.hasNext();) {
+        HNode node = (HNode) iterator2.next();
+        if (!node.isSkeleton() && !node.isCombinationNode()) {
+          if (graph.getIncomingNodeSet(node).size() == 0) {
+            nodeToBeConnected.add(node);
+          }
+        }
+      }
+
+      for (Iterator iterator2 = nodeToBeConnected.iterator(); iterator2.hasNext();) {
+        HNode node = (HNode) iterator2.next();
+        System.out.println("NEED TO BE CONNECTED TO TOP=" + node);
+        graph.addEdge(graph.getHNode(TOPDESC), node);
+      }
+
+    }
+
+  }
+
+  private void constructHierarchyGraph2() {
+
     // do fixed-point analysis
 
     LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
@@ -2368,6 +2631,9 @@ public class LocationInference {
           System.out.println("-srcCurTuple=" + srcCurTuple + "  dstCurTuple=" + dstCurTuple
               + "  srcNode=" + srcNode + "   dstNode=" + dstNode);
 
+          // srcCurTuple = translateBaseTuple(srcNode, srcCurTuple);
+          // dstCurTuple = translateBaseTuple(dstNode, dstCurTuple);
+
           if ((srcCurTuple.size() > 1 && dstCurTuple.size() > 1)
               && srcCurTuple.get(0).equals(dstCurTuple.get(0))) {
 
@@ -2432,6 +2698,31 @@ public class LocationInference {
 
   }
 
+  private NTuple<Descriptor> translateBaseTuple(FlowNode flowNode, NTuple<Descriptor> inTuple) {
+
+    if (flowNode.getBaseTuple() != null) {
+
+      NTuple<Descriptor> translatedTuple = new NTuple<Descriptor>();
+
+      NTuple<Descriptor> baseTuple = flowNode.getBaseTuple();
+
+      for (int i = 0; i < baseTuple.size(); i++) {
+        translatedTuple.add(baseTuple.get(i));
+      }
+
+      for (int i = 1; i < inTuple.size(); i++) {
+        translatedTuple.add(inTuple.get(i));
+      }
+
+      System.out.println("------TRANSLATED " + inTuple + " -> " + translatedTuple);
+      return translatedTuple;
+
+    } else {
+      return inTuple;
+    }
+
+  }
+
   private MethodSummary getMethodSummary(MethodDescriptor md) {
     if (!mapDescToLocationSummary.containsKey(md)) {
       mapDescToLocationSummary.put(md, new MethodSummary(md));
@@ -2561,20 +2852,31 @@ public class LocationInference {
       }
     }
 
-    rtr += "\")";
-
     if (desc instanceof MethodDescriptor) {
       System.out.println("#EXTRA LOC DECLARATION GEN=" + desc);
 
       MethodDescriptor md = (MethodDescriptor) desc;
       MethodSummary methodSummary = getMethodSummary(md);
 
+      TypeDescriptor returnType = ((MethodDescriptor) desc).getReturnType();
+      if (!ssjava.getMethodContainingSSJavaLoop().equals(desc) && returnType != null
+          && (!returnType.isVoid())) {
+        CompositeLocation returnLoc = methodSummary.getRETURNLoc();
+        if (returnLoc.getSize() == 1) {
+          String returnLocStr = generateLocationAnnoatation(methodSummary.getRETURNLoc());
+          if (rtr.indexOf(returnLocStr) == -1) {
+            rtr += "," + returnLocStr;
+          }
+        }
+      }
+      rtr += "\")";
+
       if (!ssjava.getMethodContainingSSJavaLoop().equals(desc)) {
-        TypeDescriptor returnType = ((MethodDescriptor) desc).getReturnType();
         if (returnType != null && (!returnType.isVoid())) {
           rtr +=
               "\n@RETURNLOC(\"" + generateLocationAnnoatation(methodSummary.getRETURNLoc()) + "\")";
         }
+
         CompositeLocation pcLoc = methodSummary.getPCLoc();
         if ((pcLoc != null) && (!pcLoc.get(0).isTop())) {
           rtr += "\n@PCLOC(\"" + generateLocationAnnoatation(pcLoc) + "\")";
@@ -2586,6 +2888,8 @@ public class LocationInference {
       }
       rtr += "\n@GLOBALLOC(\"" + methodSummary.getGlobalLocName() + "\")";
 
+    } else {
+      rtr += "\")";
     }
 
     return rtr;
@@ -2684,6 +2988,7 @@ public class LocationInference {
               if (mapDescToDefinitionLine.containsKey(localVarDesc)) {
                 int varLineNum = mapDescToDefinitionLine.get(localVarDesc);
                 String orgSourceLine = sourceVec.get(varLineNum);
+                System.out.println("varLineNum=" + varLineNum + "  org src=" + orgSourceLine);
                 int idx =
                     orgSourceLine.indexOf(generateVarDeclaration((VarDescriptor) localVarDesc));
                 System.out.println("idx=" + idx
@@ -3069,6 +3374,8 @@ public class LocationInference {
             if (!paramDescNOTHavingInFlowSet.contains(node.getCurrentDescTuple().get(0))) {
               flowNodeLowerthanPCLocSet.add(node);
               fg.addValueFlowEdge(pcDescTuple, node.getDescTuple());
+              System.out.println("B10");
+
               subGlobalFlowGraph.addValueFlowEdge(pcLocTuple,
                   translateToLocTuple(md, node.getDescTuple()));
             }
@@ -3083,7 +3390,7 @@ public class LocationInference {
           System.out.println("#########################################");
           for (Iterator iterator = flowNodeLowerthanPCLocSet.iterator(); iterator.hasNext();) {
             FlowNode lowerNode = (FlowNode) iterator.next();
-            if (lowerNode.getCompositeLocation() == null) {
+            if (lowerNode.getDescTuple().size() == 1 && lowerNode.getCompositeLocation() == null) {
               NTuple<Location> lowerLocTuple = translateToLocTuple(md, lowerNode.getDescTuple());
               CompositeLocation newComp =
                   calculateCompositeLocationFromSubGlobalGraph(md, lowerNode);
@@ -3149,9 +3456,11 @@ public class LocationInference {
     // calculate a return location:
     // the return location type is lower than all parameters and the location of return values
     MethodSummary methodSummary = getMethodSummary(md);
-    if (methodSummary.getRETURNLoc() != null) {
-      return;
-    }
+    // if (methodSummary.getRETURNLoc() != null) {
+    // System.out.println("$HERE?");
+    // return;
+    // }
+
     FlowGraph fg = getFlowGraph(md);
     Map<Integer, CompositeLocation> mapParamToLoc = methodSummary.getMapParamIdxToInferLoc();
     Set<Integer> paramIdxSet = mapParamToLoc.keySet();
@@ -3199,6 +3508,13 @@ public class LocationInference {
 
       }
 
+      // makes sure that PCLOC is higher than RETURNLOC
+      CompositeLocation pcLoc = methodSummary.getPCLoc();
+      if (!pcLoc.get(0).isTop()) {
+        NTuple<Descriptor> pcLocDescTuple = translateToDescTuple(pcLoc.getTuple());
+        fg.addValueFlowEdge(pcLocDescTuple, returnDescTuple);
+      }
+
     }
 
   }
@@ -3703,6 +4019,8 @@ public class LocationInference {
       } else if (curDescriptor instanceof NameDescriptor) {
         // it is "GLOBAL LOC" case!
         enclosingDescriptor = GLOBALDESC;
+      } else if (curDescriptor instanceof InterDescriptor) {
+        enclosingDescriptor = getFlowGraph(md).getEnclosingDescriptor(curDescriptor);
       } else {
         enclosingDescriptor = null;
       }
@@ -3986,6 +4304,21 @@ public class LocationInference {
     System.out.println("");
     toanalyze_methodDescList = computeMethodList();
 
+    // hack... it seems that there is a problem with topological sorting.
+    // so String.toString(Object o) is appeared too higher in the call chain.
+    MethodDescriptor mdToString = null;
+    for (Iterator iterator = toanalyze_methodDescList.iterator(); iterator.hasNext();) {
+      MethodDescriptor md = (MethodDescriptor) iterator.next();
+      if (md.toString().equals("public static String String.valueOf(Object o)")) {
+        mdToString = md;
+        break;
+      }
+    }
+    if (mdToString != null) {
+      toanalyze_methodDescList.remove(mdToString);
+      toanalyze_methodDescList.addLast(mdToString);
+    }
+
     LinkedList<MethodDescriptor> methodDescList =
         (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
 
@@ -4328,6 +4661,7 @@ public class LocationInference {
       newImplicitTupleSet.addTupleSet(implicitFlowTupleSet);
       newImplicitTupleSet.addTupleSet(condTupleNode);
 
+      System.out.println("A5");
       newImplicitTupleSet.addGlobalFlowTupleSet(implicitFlowTupleSet.getGlobalLocTupleSet());
       newImplicitTupleSet.addGlobalFlowTupleSet(condTupleNode.getGlobalLocTupleSet());
 
@@ -4442,7 +4776,7 @@ public class LocationInference {
   private void analyzeFlowIfStatementNode(MethodDescriptor md, SymbolTable nametable,
       IfStatementNode isn, NodeTupleSet implicitFlowTupleSet) {
 
-    // System.out.println("analyzeFlowIfStatementNode=" + isn.printNode(0));
+    System.out.println("analyzeFlowIfStatementNode=" + isn.printNode(0));
 
     NodeTupleSet condTupleNode = new NodeTupleSet();
     analyzeFlowExpressionNode(md, nametable, isn.getCondition(), condTupleNode, null,
@@ -4481,6 +4815,7 @@ public class LocationInference {
     // translateToLocTuple(md, callerImplicitTuple));
     // }
     // }
+    System.out.println("A4");
     newImplicitTupleSet.addGlobalFlowTupleSet(condTupleNode.getGlobalLocTupleSet());
 
     analyzeFlowBlockNode(md, nametable, isn.getTrueBlock(), newImplicitTupleSet);
@@ -4502,6 +4837,7 @@ public class LocationInference {
     fn.setDeclarationNode();
 
     if (dn.getExpression() != null) {
+      System.out.println("-analyzeFlowDeclarationNode=" + dn.printNode(0));
 
       NodeTupleSet nodeSetRHS = new NodeTupleSet();
       analyzeFlowExpressionNode(md, nametable, dn.getExpression(), nodeSetRHS, null,
@@ -4530,9 +4866,22 @@ public class LocationInference {
       GlobalFlowGraph globalFlowGraph = getSubGlobalFlowGraph(md);
       for (Iterator<NTuple<Location>> iterator = nodeSetRHS.globalIterator(); iterator.hasNext();) {
         NTuple<Location> calleeReturnLocTuple = iterator.next();
+        System.out.println("B7");
+
         globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple, translateToLocTuple(md, tupleLHS));
       }
 
+      for (Iterator<NTuple<Location>> iterator = implicitFlowTupleSet.globalIterator(); iterator
+          .hasNext();) {
+        NTuple<Location> implicitGlobalTuple = iterator.next();
+        System.out.println("B8");
+
+        globalFlowGraph.addValueFlowEdge(implicitGlobalTuple, translateToLocTuple(md, tupleLHS));
+      }
+
+      System.out.println("-nodeSetRHS=" + nodeSetRHS);
+      System.out.println("-implicitFlowTupleSet=" + implicitFlowTupleSet);
+
     }
 
   }
@@ -4552,12 +4901,13 @@ public class LocationInference {
       ExpressionNode en, NodeTupleSet nodeSet, NTuple<Descriptor> base,
       NodeTupleSet implicitFlowTupleSet, boolean isLHS) {
 
+    // System.out.println("en=" + en.printNode(0) + "   class=" + en.getClass());
+
     // note that expression node can create more than one flow node
     // nodeSet contains of flow nodes
     // base is always assigned to null except the case of a name node!
     NTuple<Descriptor> flowTuple;
     switch (en.kind()) {
-
     case Kind.AssignmentNode:
       analyzeFlowAssignmentNode(md, nametable, (AssignmentNode) en, nodeSet, base,
           implicitFlowTupleSet);
@@ -4670,6 +5020,7 @@ public class LocationInference {
       newImplicitTupleSet.addTuple(interTuple);
     }
 
+    System.out.println("A7");
     newImplicitTupleSet.addGlobalFlowTupleSet(tertiaryTupleNode.getGlobalLocTupleSet());
 
     System.out.println("---------newImplicitTupleSet=" + newImplicitTupleSet);
@@ -4681,6 +5032,7 @@ public class LocationInference {
     analyzeFlowExpressionNode(md, nametable, tn.getFalseExpr(), tertiaryTupleNode, null,
         newImplicitTupleSet, false);
 
+    System.out.println("A8");
     nodeSet.addGlobalFlowTupleSet(tertiaryTupleNode.getGlobalLocTupleSet());
     nodeSet.addTupleSet(tertiaryTupleNode);
 
@@ -4761,7 +5113,7 @@ public class LocationInference {
       addMapCallerMethodDescToMethodInvokeNodeSet(mdCaller, min);
 
       FlowGraph calleeFlowGraph = getFlowGraph(mdCallee);
-      System.out.println("mdCallee=" + mdCallee);
+      System.out.println("mdCallee=" + mdCallee + " calleeFlowGraph=" + calleeFlowGraph);
       Set<FlowNode> calleeReturnSet = calleeFlowGraph.getReturnNodeSet();
 
       System.out.println("---calleeReturnSet=" + calleeReturnSet);
@@ -4773,9 +5125,17 @@ public class LocationInference {
         NodeTupleSet baseNodeSet = new NodeTupleSet();
         analyzeFlowExpressionNode(mdCaller, nametable, min.getExpression(), baseNodeSet, null,
             implicitFlowTupleSet, false);
+        System.out.println("baseNodeSet=" + baseNodeSet);
 
         assert (baseNodeSet.size() == 1);
         NTuple<Descriptor> baseTuple = baseNodeSet.iterator().next();
+        if (baseTuple.get(0) instanceof InterDescriptor) {
+          if (baseTuple.size() > 1) {
+            throw new Error();
+          }
+          FlowNode interNode = getFlowGraph(mdCaller).getFlowNode(baseTuple);
+          baseTuple = translateBaseTuple(interNode, baseTuple);
+        }
         mapMethodInvokeNodeToBaseTuple.put(min, baseTuple);
 
         if (!min.getMethod().isStatic()) {
@@ -4788,19 +5148,31 @@ public class LocationInference {
               // the location type of the return value is started with 'this'
               // reference
               NTuple<Descriptor> inFlowTuple = new NTuple<Descriptor>(baseTuple.getList());
+
+              if (inFlowTuple.get(0) instanceof InterDescriptor) {
+                // min.getExpression()
+              } else {
+
+              }
+
               inFlowTuple.addAll(returnDescTuple.subList(1, returnDescTuple.size()));
               // nodeSet.addTuple(inFlowTuple);
-              tupleSet.addTuple(inFlowTuple);
+              System.out.println("1CREATE A NEW TUPLE=" + inFlowTuple + "  from="
+                  + mdCallee.getThis());
+              // tupleSet.addTuple(inFlowTuple);
+              tupleSet.addTuple(baseTuple);
             } else {
               // TODO
+              System.out.println("returnNode=" + returnNode);
               Set<FlowNode> inFlowSet = calleeFlowGraph.getIncomingFlowNodeSet(returnNode);
               // System.out.println("inFlowSet=" + inFlowSet + "   from retrunNode=" + returnNode);
               for (Iterator iterator2 = inFlowSet.iterator(); iterator2.hasNext();) {
                 FlowNode inFlowNode = (FlowNode) iterator2.next();
                 if (inFlowNode.getDescTuple().startsWith(mdCallee.getThis())) {
                   // nodeSet.addTupleSet(baseNodeSet);
+                  System.out.println("2CREATE A NEW TUPLE=" + baseNodeSet + "  from="
+                      + mdCallee.getThis());
                   tupleSet.addTupleSet(baseNodeSet);
-
                 }
               }
             }
@@ -4825,7 +5197,7 @@ public class LocationInference {
           NodeTupleSet argTupleSet = new NodeTupleSet();
           analyzeFlowExpressionNode(mdCaller, nametable, en, argTupleSet, false);
           // if argument is liternal node, argTuple is set to NULL
-          System.out.println("argTupleSet=" + argTupleSet);
+          System.out.println("---arg idx=" + idx + "   argTupleSet=" + argTupleSet);
           NTuple<Descriptor> argTuple = generateArgTuple(mdCaller, argTupleSet);
 
           // if an argument is literal value,
@@ -4866,6 +5238,7 @@ public class LocationInference {
               || mdCallee.getModifiers().isNative()) {
             addParamNodeFlowingToReturnValue(mdCallee, paramNode);
             // nodeSet.addTupleSet(argTupleSet);
+            System.out.println("3CREATE A NEW TUPLE=" + argTupleSet + "  from=" + paramNode);
             tupleSet.addTupleSet(argTupleSet);
           }
         }
@@ -4873,10 +5246,52 @@ public class LocationInference {
       }
 
       if (mdCallee.getReturnType() != null && !mdCallee.getReturnType().isVoid()) {
-        FlowReturnNode setNode = getFlowGraph(mdCaller).createReturnNode(min);
-        System.out.println("ADD TUPLESET=" + tupleSet + " to returnnode=" + setNode);
-        setNode.addTupleSet(tupleSet);
-        nodeSet.addTuple(setNode.getDescTuple());
+        FlowReturnNode returnHolderNode = getFlowGraph(mdCaller).createReturnNode(min);
+
+        if (needToGenerateInterLoc(tupleSet)) {
+          System.out.println("20");
+          FlowGraph fg = getFlowGraph(mdCaller);
+          FlowNode interNode = fg.createIntermediateNode();
+          interNode.setFormHolder(true);
+
+          NTuple<Descriptor> interTuple = interNode.getDescTuple();
+
+          for (Iterator iterator = tupleSet.iterator(); iterator.hasNext();) {
+            NTuple<Descriptor> tuple = (NTuple<Descriptor>) iterator.next();
+
+            Set<NTuple<Descriptor>> addSet = new HashSet<NTuple<Descriptor>>();
+            FlowNode node = fg.getFlowNode(tuple);
+            if (node instanceof FlowReturnNode) {
+              addSet.addAll(fg.getReturnTupleSet(((FlowReturnNode) node).getReturnTupleSet()));
+            } else {
+              addSet.add(tuple);
+            }
+            for (Iterator iterator2 = addSet.iterator(); iterator2.hasNext();) {
+              NTuple<Descriptor> higher = (NTuple<Descriptor>) iterator2.next();
+              addFlowGraphEdge(mdCaller, higher, interTuple);
+            }
+          }
+
+          returnHolderNode.addTuple(interTuple);
+          // TODO
+          nodeSet.addTuple(interTuple);
+          System.out.println("ADD TUPLESET=" + interTuple + " to returnnode=" + returnHolderNode);
+
+        } else {
+          returnHolderNode.addTupleSet(tupleSet);
+          System.out.println("ADD TUPLESET=" + tupleSet + " to returnnode=" + returnHolderNode);
+        }
+        // setNode.addTupleSet(tupleSet);
+        // NodeTupleSet setFromReturnNode=new NodeTupleSet();
+        // setFromReturnNode.addTuple(tuple);
+
+        NodeTupleSet holderTupleSet =
+            getNodeTupleSetFromReturnNode(getFlowGraph(mdCaller), returnHolderNode);
+
+        System.out.println("HOLDER TUPLe SET=" + holderTupleSet);
+        nodeSet.addTupleSet(holderTupleSet);
+
+        nodeSet.addTuple(returnHolderNode.getDescTuple());
       }
 
       // propagateFlowsFromCallee(min, md, min.getMethod());
@@ -4889,8 +5304,14 @@ public class LocationInference {
         NTuple<Location> calleeReturnLocTuple =
             translateToLocTuple(mdCallee, calleeReturnNode.getDescTuple());
         System.out.println("calleeReturnLocTuple=" + calleeReturnLocTuple);
-        nodeSet.addGlobalFlowTuple(translateToCallerLocTuple(min, mdCallee, mdCaller,
-            calleeReturnLocTuple));
+        NTuple<Location> transaltedToCaller =
+            translateToCallerLocTuple(min, mdCallee, mdCaller, calleeReturnLocTuple);
+        // System.out.println("translateToCallerLocTuple="
+        // + translateToCallerLocTuple(min, mdCallee, mdCaller, calleeReturnLocTuple));
+        if (transaltedToCaller.size() > 0) {
+          nodeSet.addGlobalFlowTuple(translateToCallerLocTuple(min, mdCallee, mdCaller,
+              calleeReturnLocTuple));
+        }
       }
 
       System.out.println("min nodeSet=" + nodeSet);
@@ -4899,6 +5320,47 @@ public class LocationInference {
 
   }
 
+  private NodeTupleSet getNodeTupleSetFromReturnNode(FlowGraph fg, FlowReturnNode node) {
+    NodeTupleSet nts = new NodeTupleSet();
+
+    Set<NTuple<Descriptor>> returnSet = node.getReturnTupleSet();
+
+    for (Iterator iterator = returnSet.iterator(); iterator.hasNext();) {
+      NTuple<Descriptor> tuple = (NTuple<Descriptor>) iterator.next();
+      FlowNode flowNode = fg.getFlowNode(tuple);
+      if (flowNode instanceof FlowReturnNode) {
+        returnSet.addAll(recurGetNode(fg, (FlowReturnNode) flowNode));
+      } else {
+        returnSet.add(tuple);
+      }
+    }
+
+    for (Iterator iterator = returnSet.iterator(); iterator.hasNext();) {
+      NTuple<Descriptor> nTuple = (NTuple<Descriptor>) iterator.next();
+      nts.addTuple(nTuple);
+    }
+
+    return nts;
+
+  }
+
+  private Set<NTuple<Descriptor>> recurGetNode(FlowGraph fg, FlowReturnNode rnode) {
+
+    Set<NTuple<Descriptor>> tupleSet = new HashSet<NTuple<Descriptor>>();
+
+    Set<NTuple<Descriptor>> returnSet = rnode.getReturnTupleSet();
+    for (Iterator iterator = returnSet.iterator(); iterator.hasNext();) {
+      NTuple<Descriptor> tuple = (NTuple<Descriptor>) iterator.next();
+      FlowNode flowNode = fg.getFlowNode(tuple);
+      if (flowNode instanceof FlowReturnNode) {
+        tupleSet.addAll(recurGetNode(fg, (FlowReturnNode) flowNode));
+      }
+      tupleSet.add(tuple);
+    }
+
+    return tupleSet;
+  }
+
   private NTuple<Descriptor> generateArgTuple(MethodDescriptor mdCaller, NodeTupleSet argTupleSet) {
 
     int size = 0;
@@ -4946,7 +5408,7 @@ public class LocationInference {
     }
     // Set<FlowNode> reachableSet = fg.getReachFlowNodeSetFrom(inNode);
     Set<FlowNode> reachableSet = fg.getReachableSetFrom(inNode.getDescTuple());
-    System.out.println("inNode=" + inNode + "  reachalbeSet=" + reachableSet);
+    // System.out.println("inNode=" + inNode + "  reachalbeSet=" + reachableSet);
 
     for (Iterator iterator = reachableSet.iterator(); iterator.hasNext();) {
       FlowNode fn = (FlowNode) iterator.next();
@@ -4983,14 +5445,16 @@ public class LocationInference {
   private void analyzeFlowArrayAccessNode(MethodDescriptor md, SymbolTable nametable,
       ArrayAccessNode aan, NodeTupleSet nodeSet, boolean isLHS) {
 
-    // System.out.println("analyzeFlowArrayAccessNode aan=" + aan.printNode(0));
+    System.out.println("analyzeFlowArrayAccessNode aan=" + aan.printNode(0));
     String currentArrayAccessNodeExpStr = aan.printNode(0);
     arrayAccessNodeStack.push(aan.printNode(0));
 
     NodeTupleSet expNodeTupleSet = new NodeTupleSet();
     NTuple<Descriptor> base =
         analyzeFlowExpressionNode(md, nametable, aan.getExpression(), expNodeTupleSet, isLHS);
+    System.out.println("-base=" + base);
 
+    nodeSet.setMethodInvokeBaseDescTuple(base);
     NodeTupleSet idxNodeTupleSet = new NodeTupleSet();
     analyzeFlowExpressionNode(md, nametable, aan.getIndex(), idxNodeTupleSet, isLHS);
 
@@ -5012,6 +5476,8 @@ public class LocationInference {
         NTuple<Location> calleeReturnLocTuple = iterator.next();
         for (Iterator<NTuple<Descriptor>> arrIter = expNodeTupleSet.iterator(); arrIter.hasNext();) {
           NTuple<Descriptor> arrTuple = arrIter.next();
+          System.out.println("B4");
+
           globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple, translateToLocTuple(md, arrTuple));
         }
       }
@@ -5029,7 +5495,8 @@ public class LocationInference {
 
         if (needToGenerateInterLoc(nodeSetArrayAccessExp)) {
           System.out.println("1");
-          NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+          FlowNode interNode = getFlowGraph(md).createIntermediateNode();
+          NTuple<Descriptor> interTuple = interNode.getDescTuple();
 
           for (Iterator<NTuple<Descriptor>> iter = nodeSetArrayAccessExp.iterator(); iter.hasNext();) {
             NTuple<Descriptor> higherTuple = iter.next();
@@ -5037,9 +5504,18 @@ public class LocationInference {
           }
           nodeSetArrayAccessExp.clear();
           nodeSetArrayAccessExp.addTuple(interTuple);
+          FlowGraph fg = getFlowGraph(md);
+
+          System.out.println("base=" + base);
+          if (base != null) {
+            fg.addMapInterLocNodeToEnclosingDescriptor(interTuple.get(0),
+                getClassTypeDescriptor(base.get(base.size() - 1)));
+            interNode.setBaseTuple(base);
+          }
         }
       }
 
+      System.out.println("A1");
       nodeSet.addGlobalFlowTupleSet(idxNodeTupleSet.getGlobalLocTupleSet());
       nodeSet.addTupleSet(nodeSetArrayAccessExp);
 
@@ -5059,15 +5535,19 @@ public class LocationInference {
     NodeTupleSet leftOpSet = new NodeTupleSet();
     NodeTupleSet rightOpSet = new NodeTupleSet();
 
+    System.out.println("analyzeFlowOpNode=" + on.printNode(0));
+
     // left operand
     analyzeFlowExpressionNode(md, nametable, on.getLeft(), leftOpSet, null, implicitFlowTupleSet,
         false);
+    System.out.println("--leftOpSet=" + leftOpSet);
 
     if (on.getRight() != null) {
       // right operand
       analyzeFlowExpressionNode(md, nametable, on.getRight(), rightOpSet, null,
           implicitFlowTupleSet, false);
     }
+    System.out.println("--rightOpSet=" + rightOpSet);
 
     Operation op = on.getOp();
 
@@ -5106,6 +5586,7 @@ public class LocationInference {
       nodeSet.addTupleSet(leftOpSet);
       nodeSet.addTupleSet(rightOpSet);
 
+      System.out.println("A6");
       nodeSet.addGlobalFlowTupleSet(leftOpSet.getGlobalLocTupleSet());
       nodeSet.addGlobalFlowTupleSet(rightOpSet.getGlobalLocTupleSet());
 
@@ -5266,6 +5747,8 @@ public class LocationInference {
         for (Iterator<NTuple<Location>> iterator = idxNodeTupleSet.globalIterator(); iterator
             .hasNext();) {
           NTuple<Location> calleeReturnLocTuple = iterator.next();
+          System.out.println("B9");
+
           globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple,
               translateToLocTuple(md, flowFieldTuple));
         }
@@ -5299,10 +5782,15 @@ public class LocationInference {
                 NTuple<Descriptor> higherTuple = iter.next();
                 addFlowGraphEdge(md, higherTuple, interTuple);
               }
+
+              FlowGraph fg = getFlowGraph(md);
+              fg.addMapInterLocNodeToEnclosingDescriptor(interTuple.get(0),
+                  getClassTypeDescriptor(base.get(base.size() - 1)));
+
               nodeSet.clear();
               flowFieldTuple = interTuple;
             }
-
+            System.out.println("A3");
             nodeSet.addGlobalFlowTupleSet(idxNodeTupleSet.getGlobalLocTupleSet());
           }
 
@@ -5391,10 +5879,12 @@ public class LocationInference {
         NTuple<Location> calleeReturnLocTuple = iterator.next();
         for (Iterator<NTuple<Descriptor>> iter2 = nodeSetLHS.iterator(); iter2.hasNext();) {
           NTuple<Descriptor> callerLHSTuple = iter2.next();
-          globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple,
-              translateToLocTuple(md, callerLHSTuple));
           System.out.println("$$$ GLOBAL FLOW ADD=" + calleeReturnLocTuple + " -> "
               + translateToLocTuple(md, callerLHSTuple));
+          System.out.println("B5");
+
+          globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple,
+              translateToLocTuple(md, callerLHSTuple));
         }
       }
 
@@ -5403,6 +5893,8 @@ public class LocationInference {
         NTuple<Location> calleeReturnLocTuple = iterator.next();
         for (Iterator<NTuple<Descriptor>> iter2 = nodeSetLHS.iterator(); iter2.hasNext();) {
           NTuple<Descriptor> callerLHSTuple = iter2.next();
+          System.out.println("B6");
+
           globalFlowGraph.addValueFlowEdge(calleeReturnLocTuple,
               translateToLocTuple(md, callerLHSTuple));
           System.out.println("$$$ GLOBAL FLOW PCLOC ADD=" + calleeReturnLocTuple + " -> "
@@ -5444,6 +5936,7 @@ public class LocationInference {
 
     if (nodeSet != null) {
       nodeSet.addTupleSet(nodeSetLHS);
+      System.out.println("A2");
       nodeSet.addGlobalFlowTupleSet(nodeSetLHS.getGlobalLocTupleSet());
     }
   }