changes.
[IRC.git] / Robust / src / Analysis / SSJava / LocationInference.java
index 4cca1c49dcbb9dcf65612b81abbe313a4507f1f9..6594444c987a90ec76aef8c5baf42b6c875cae56 100644 (file)
@@ -120,15 +120,25 @@ public class LocationInference {
 
   public static final String GLOBALLOC = "GLOBALLOC";
 
-  public static final String TOPLOC = "TOPLOC";
-
   public static final String INTERLOC = "INTERLOC";
 
-  public static final String PCLOC = "PCLOC";
+  public static final String PCLOC = "_PCLOC_";
+
+  public static final String RLOC = "_RLOC_";
 
   public static final Descriptor GLOBALDESC = new NameDescriptor(GLOBALLOC);
 
-  public static final Descriptor TOPDESC = new NameDescriptor(TOPLOC);
+  public static final Descriptor TOPDESC = new NameDescriptor(SSJavaAnalysis.TOP);
+
+  public static final Descriptor BOTTOMDESC = new NameDescriptor(SSJavaAnalysis.BOTTOM);
+
+  public static final Descriptor RETURNLOC = new NameDescriptor(RLOC);
+
+  public static final Descriptor LITERALDESC = new NameDescriptor("LITERAL");
+
+  public static final HNode TOPHNODE = new HNode(TOPDESC);
+
+  public static final HNode BOTTOMHNODE = new HNode(BOTTOMDESC);
 
   public static String newline = System.getProperty("line.separator");
 
@@ -136,7 +146,7 @@ public class LocationInference {
 
   boolean debug = true;
 
-  private static int locSeed = 0;
+  public static int locSeed = 0;
 
   public LocationInference(SSJavaAnalysis ssjava, State state) {
     this.ssjava = ssjava;
@@ -219,20 +229,24 @@ public class LocationInference {
 
   public void inference() {
 
-    // 1) construct value flow graph
+    ssjava.init();
+
+    // construct value flow graph
     constructFlowGraph();
 
     assignCompositeLocation();
 
-    // constructGlobalFlowGraph();
+    // calculate RETURNLOC,PCLOC
+    calculateExtraLocations();
+
+    _debug_writeFlowGraph();
+
+    // System.exit(0);
 
     constructHierarchyGraph();
 
     debug_writeHierarchyDotFiles();
 
-    // calculate RETURNLOC,PCLOC
-    calculateExtraLocations();
-
     simplifyHierarchyGraph();
 
     debug_writeSimpleHierarchyDotFiles();
@@ -245,8 +259,6 @@ public class LocationInference {
 
     debug_writeSkeletonCombinationHierarchyDotFiles();
 
-    // System.exit(0);
-
     buildLattice();
 
     debug_writeLattices();
@@ -255,22 +267,10 @@ public class LocationInference {
 
     generateMethodSummary();
 
-    System.exit(0);
-
-    // 2) construct lattices
-    // inferLattices();
-    // simplifyLattices();
-    // 3) check properties
-    // checkLattices();
-
-    // calculate RETURNLOC,PCLOC
-    calculateExtraLocations();
-
-    debug_writeLatticeDotFile();
-
-    // 4) generate annotated source codes
     generateAnnoatedCode();
 
+    System.exit(0);
+
   }
 
   public Map<NTuple<Descriptor>, NTuple<Descriptor>> getMapCallerArgToCalleeParam(
@@ -295,9 +295,9 @@ public class LocationInference {
   }
 
   private void translateCompositeLocationAssignmentToFlowGraph() {
+    System.out.println("\nSSJAVA: Translate composite location assignments to flow graphs:");
     MethodDescriptor methodEventLoopDesc = ssjava.getMethodContainingSSJavaLoop();
     translateCompositeLocationAssignmentToFlowGraph(methodEventLoopDesc);
-    _debug_printGraph();
   }
 
   private void updateCompositeLocationAssignments() {
@@ -307,23 +307,46 @@ public class LocationInference {
 
     while (!methodDescList.isEmpty()) {
       MethodDescriptor md = methodDescList.removeLast();
-      GlobalFlowGraph globalFlowGraph = getSubGlobalFlowGraph(md);
+
+      System.out.println("\n#updateCompositeLocationAssignments=" + md);
+
       FlowGraph flowGraph = getFlowGraph(md);
 
+      MethodSummary methodSummary = getMethodSummary(md);
+
       Set<FlowNode> nodeSet = flowGraph.getNodeSet();
       for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
         FlowNode node = (FlowNode) iterator.next();
+        System.out.println("-node=" + node + "   node.getDescTuple=" + node.getDescTuple());
         if (node.getCompositeLocation() != null) {
           CompositeLocation compLoc = node.getCompositeLocation();
           CompositeLocation updatedCompLoc = updateCompositeLocation(compLoc);
           node.setCompositeLocation(updatedCompLoc);
+          System.out.println("---updatedCompLoc1=" + updatedCompLoc);
         } else {
           NTuple<Descriptor> descTuple = node.getDescTuple();
+          System.out.println("update desc=" + descTuple);
           CompositeLocation compLoc = convertToCompositeLocation(md, descTuple);
+          compLoc = updateCompositeLocation(compLoc);
           node.setCompositeLocation(compLoc);
+          System.out.println("---updatedCompLoc2=" + compLoc);
+        }
+
+        if (node.isDeclaratonNode()) {
+          Descriptor localVarDesc = node.getDescTuple().get(0);
+          CompositeLocation compLoc = updateCompositeLocation(node.getCompositeLocation());
+          methodSummary.addMapVarNameToInferCompLoc(localVarDesc, compLoc);
         }
       }
 
+      // update PCLOC and RETURNLOC if they have a composite location assignment
+      if (methodSummary.getRETURNLoc() != null) {
+        methodSummary.setRETURNLoc(updateCompositeLocation(methodSummary.getRETURNLoc()));
+      }
+      if (methodSummary.getPCLoc() != null) {
+        methodSummary.setPCLoc(updateCompositeLocation(methodSummary.getPCLoc()));
+      }
+
     }
 
   }
@@ -334,8 +357,20 @@ public class LocationInference {
       Location loc = compLoc.get(i);
       String nodeIdentifier = loc.getLocIdentifier();
       Descriptor enclosingDesc = loc.getDescriptor();
-      LocationSummary locSummary = getLocationSummary(enclosingDesc);
-      String locName = locSummary.getLocationName(nodeIdentifier);
+      String locName;
+      if (!enclosingDesc.equals(GLOBALDESC)) {
+        LocationSummary locSummary = getLocationSummary(enclosingDesc);
+        HierarchyGraph scGraph = getSkeletonCombinationHierarchyGraph(enclosingDesc);
+        if (scGraph != null) {
+          HNode curNode = scGraph.getCurrentHNode(nodeIdentifier);
+          if (curNode != null) {
+            nodeIdentifier = curNode.getName();
+          }
+        }
+        locName = locSummary.getLocationName(nodeIdentifier);
+      } else {
+        locName = nodeIdentifier;
+      }
       Location updatedLoc = new Location(enclosingDesc, locName);
       updatedCompLoc.addLocation(updatedLoc);
     }
@@ -345,15 +380,12 @@ public class LocationInference {
 
   private void translateCompositeLocationAssignmentToFlowGraph(MethodDescriptor mdCaller) {
 
-    System.out.println("\n#translateCompositeLocationAssignmentToFlowGraph=" + mdCaller);
-
     // First, assign a composite location to a node in the flow graph
     GlobalFlowGraph callerGlobalFlowGraph = getSubGlobalFlowGraph(mdCaller);
 
     FlowGraph callerFlowGraph = getFlowGraph(mdCaller);
     Map<Location, CompositeLocation> callerMapLocToCompLoc =
         callerGlobalFlowGraph.getMapLocationToInferCompositeLocation();
-    System.out.println("---callerMapLocToCompLoc=" + callerMapLocToCompLoc);
     Set<Location> methodLocSet = callerMapLocToCompLoc.keySet();
     for (Iterator iterator = methodLocSet.iterator(); iterator.hasNext();) {
       Location methodLoc = (Location) iterator.next();
@@ -370,12 +402,7 @@ public class LocationInference {
       MethodInvokeNode min = (MethodInvokeNode) iterator.next();
       // need to translate a composite location that is started with the base
       // tuple of 'min'.
-      if (mapMethodInvokeNodeToBaseTuple.get(min) != null) {
-        // if mapMethodInvokeNodeToBaseTuple doesn't have a mapping
-        // it means that the corresponding callee method does not cause any
-        // flows
-        translateMapLocationToInferCompositeLocationToCalleeGraph(callerGlobalFlowGraph, min);
-      }
+      translateMapLocationToInferCompositeLocationToCalleeGraph(callerGlobalFlowGraph, min);
       calleeSet.add(min.getMethod());
     }
 
@@ -393,7 +420,8 @@ public class LocationInference {
     Set<FlowNode> nodeSet = flowGraph.getNodeSet();
     for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
       FlowNode node = (FlowNode) iterator.next();
-      if (node.getDescTuple().startsWith(localDesc)) {
+      if (node.getDescTuple().startsWith(localDesc)
+          && !node.getDescTuple().get(0).equals(LITERALDESC)) {
         // need to assign the inferred composite location to this node
         CompositeLocation newCompLoc = generateCompositeLocation(node.getDescTuple(), inferCompLoc);
         node.setCompositeLocation(newCompLoc);
@@ -443,43 +471,58 @@ public class LocationInference {
     FlowGraph calleeFlowGraph = getFlowGraph(mdCallee);
     GlobalFlowGraph calleeGlobalGraph = getSubGlobalFlowGraph(mdCallee);
 
-    NTuple<Location> baseLocTuple =
-        translateToLocTuple(mdCaller, mapMethodInvokeNodeToBaseTuple.get(min));
+    NTuple<Location> baseLocTuple = null;
+    if (mapMethodInvokeNodeToBaseTuple.containsKey(min)) {
+      baseLocTuple = translateToLocTuple(mdCaller, mapMethodInvokeNodeToBaseTuple.get(min));
+    }
 
-    System.out.println("\n-translate caller infer composite loc to callee=" + mdCallee
-        + " baseLocTuple=" + baseLocTuple);
+    // System.out.println("\n-translate caller infer composite loc to callee=" + mdCallee
+    // + " baseLocTuple=" + baseLocTuple);
     Set<Location> keySet = callerMapLocToCompLoc.keySet();
     for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
       Location key = (Location) iterator.next();
       CompositeLocation callerCompLoc = callerMapLocToCompLoc.get(key);
 
       if (!key.getDescriptor().equals(mdCaller)) {
-        System.out.println("--- caller key=" + key + "  callerCompLoc=" + callerCompLoc);
-
-        // && callerCompLoc.getTuple().startsWith(baseLocTuple)) {
-        // need to translate to the callee side
 
-        // TODO
         CompositeLocation newCalleeCompLoc;
-        if (callerCompLoc.getTuple().startsWith(baseLocTuple)) {
-          System.out.println("---need to translate callerCompLoc=" + callerCompLoc
-              + " with baseTuple=" + baseLocTuple);
+        if (baseLocTuple != null && callerCompLoc.getTuple().startsWith(baseLocTuple)) {
+          // System.out.println("---need to translate callerCompLoc=" + callerCompLoc
+          // + " with baseTuple=" + baseLocTuple);
           newCalleeCompLoc =
               translateCompositeLocationToCallee(callerCompLoc, baseLocTuple, mdCallee);
 
           calleeGlobalGraph.addMapLocationToInferCompositeLocation(key, newCalleeCompLoc);
-          System.out.println("---callee loc=" + key + "  newCalleeCompLoc=" + newCalleeCompLoc);
+          // System.out.println("---callee loc=" + key + "  newCalleeCompLoc=" + newCalleeCompLoc);
         } else {
-          // newCalleeCompLoc = callerCompLoc.clone();
+          // check if it is the global access
+          Location compLocFirstElement = callerCompLoc.getTuple().get(0);
+          if (compLocFirstElement.getDescriptor().equals(mdCallee)
+              && compLocFirstElement.getLocDescriptor().equals(GLOBALDESC)) {
+
+            newCalleeCompLoc = new CompositeLocation();
+            Location newMethodLoc = new Location(mdCallee, GLOBALDESC);
+
+            newCalleeCompLoc.addLocation(newMethodLoc);
+            for (int i = 1; i < callerCompLoc.getSize(); i++) {
+              newCalleeCompLoc.addLocation(callerCompLoc.get(i));
+            }
+            calleeGlobalGraph.addMapLocationToInferCompositeLocation(key, newCalleeCompLoc);
+
+          }
+
         }
 
       }
     }
 
+    // System.out.println("-----*AFTER TRANSLATING COMP LOC MAPPING, CALLEE MAPPING="
+    // + calleeGlobalGraph.getMapLocationToInferCompositeLocation());
+
     // If the location of an argument has a composite location
     // need to assign a proper composite location to the corresponding callee parameter
-    System.out.println("\n-translate arg composite location to callee param. min="
-        + min.printNode(0));
+    // System.out.println("---translate arg composite location to callee param. min="
+    // + min.printNode(0));
     Map<Integer, NTuple<Descriptor>> mapIdxToArgTuple = mapMethodInvokeNodeToArgIdxMap.get(min);
     Set<Integer> idxSet = mapIdxToArgTuple.keySet();
     for (Iterator iterator = idxSet.iterator(); iterator.hasNext();) {
@@ -503,7 +546,7 @@ public class LocationInference {
             callerCompLoc.addLocation(argLocTuple.get(i));
           }
 
-          if (callerCompLoc.getTuple().startsWith(baseLocTuple)) {
+          if (baseLocTuple != null && callerCompLoc.getTuple().startsWith(baseLocTuple)) {
 
             FlowNode calleeParamFlowNode = calleeFlowGraph.getParamFlowNode(idx);
             NTuple<Descriptor> calleeParamDescTuple = calleeParamFlowNode.getDescTuple();
@@ -566,55 +609,6 @@ public class LocationInference {
 
   }
 
-  private void constructGlobalFlowGraph() {
-
-    System.out.println("");
-    LinkedList<MethodDescriptor> methodDescList =
-        (LinkedList<MethodDescriptor>) toanalyze_methodDescList.clone();
-
-    System.out.println("@@@methodDescList=" + methodDescList);
-    // System.exit(0);
-
-    while (!methodDescList.isEmpty()) {
-      MethodDescriptor md = methodDescList.removeLast();
-      if (state.SSJAVADEBUG) {
-        System.out.println();
-        System.out.println("SSJAVA: Constructing a global flow graph: " + md);
-
-        FlowGraph flowGraph = getFlowGraph(md);
-        FlowGraph subGlobalFlowGraph = flowGraph.clone();
-
-        // mapMethodDescriptorToSubGlobalFlowGraph.put(md, subGlobalFlowGraph);
-
-        // addValueFlowsFromCalleeSubGlobalFlowGraph(md, subGlobalFlowGraph);
-
-        // try {
-        // subGlobalFlowGraph.writeGraph("_SUBGLOBAL");
-        // } catch (IOException e) {
-        // e.printStackTrace();
-        // }
-        // FlowGraph fg = new FlowGraph(md, mapParamDescToIdx);
-        // mapMethodDescriptorToFlowGraph.put(md, fg);
-        // analyzeMethodBody(md.getClassDesc(), md);
-      }
-
-    }
-
-    // DEBUG: write a global flow graph
-    MethodDescriptor mdContainingSSJavaLoop = ssjava.getMethodContainingSSJavaLoop();
-    // FlowGraph globalFlowGraph =
-    // getSubGlobalFlowGraph(mdContainingSSJavaLoop);
-    // System.out.println("GLOBAL NODE SET=" + globalFlowGraph.getNodeSet());
-    // assignCompositeLocation(globalFlowGraph);
-    // try {
-    // globalFlowGraph.writeGraph("_GLOBAL");
-    // } catch (IOException e) {
-    // e.printStackTrace();
-    // }
-    // _debug_printGraph();
-
-  }
-
   private void calculateGlobalValueFlowCompositeLocation() {
 
     System.out.println("SSJAVA: Calculate composite locations in the global value flow graph");
@@ -723,8 +717,6 @@ public class LocationInference {
 
     System.out.println("\n##### calculatePrefixList node=" + node);
 
-    MethodDescriptor md = graph.getMethodDescriptor();
-
     Set<GlobalFlowNode> incomingNodeSetPrefix =
         graph.getIncomingNodeSetByPrefix(node.getLocTuple().get(0));
     // System.out.println("incomingNodeSetPrefix=" + incomingNodeSetPrefix);
@@ -760,6 +752,24 @@ public class LocationInference {
         }
       }
     });
+
+    // remove a prefix which is not suitable for generating composite location
+    Location localVarLoc = node.getLocTuple().get(0);
+    MethodDescriptor md = (MethodDescriptor) localVarLoc.getDescriptor();
+    ClassDescriptor cd = md.getClassDesc();
+
+    int idx = 0;
+
+    Set<NTuple<Location>> toberemoved = new HashSet<NTuple<Location>>();
+    for (int i = 0; i < prefixList.size(); i++) {
+      NTuple<Location> prefixLocTuple = prefixList.get(i);
+      if (!containsClassDesc(cd, prefixLocTuple)) {
+        toberemoved.add(prefixLocTuple);
+      }
+    }
+
+    prefixList.removeAll(toberemoved);
+
     return prefixList;
 
     // List<NTuple<Location>> prefixList = new ArrayList<NTuple<Location>>();
@@ -792,6 +802,20 @@ public class LocationInference {
     // return prefixList;
   }
 
+  private boolean containsClassDesc(ClassDescriptor cd, NTuple<Location> prefixLocTuple) {
+    for (int i = 0; i < prefixLocTuple.size(); i++) {
+      Location loc = prefixLocTuple.get(i);
+      Descriptor locDesc = loc.getLocDescriptor();
+      if (locDesc != null) {
+        ClassDescriptor type = getClassTypeDescriptor(locDesc);
+        if (type != null && type.equals(cd)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
   private GlobalFlowGraph constructSubGlobalFlowGraph(FlowGraph flowGraph) {
 
     MethodDescriptor md = flowGraph.getMethodDescriptor();
@@ -897,12 +921,11 @@ public class LocationInference {
   private void propagateValueFlowsToCallerFromSubGlobalFlowGraph(MethodInvokeNode min,
       MethodDescriptor mdCaller, MethodDescriptor possibleMdCallee) {
 
-    System.out.println("propagateValueFlowsToCallerFromSubGlobalFlowGraph=" + min.printNode(0)
-        + " by caller=" + mdCaller);
+    System.out.println("---propagate from " + min.printNode(0) + " to caller=" + mdCaller);
     FlowGraph calleeFlowGraph = getFlowGraph(possibleMdCallee);
     Map<Integer, NTuple<Descriptor>> mapIdxToArg = mapMethodInvokeNodeToArgIdxMap.get(min);
 
-    System.out.println("mapMethodInvokeNodeToArgIdxMap.get(min)="
+    System.out.println("-----mapMethodInvokeNodeToArgIdxMap.get(min)="
         + mapMethodInvokeNodeToArgIdxMap.get(min));
     Set<Integer> keySet = mapIdxToArg.keySet();
     for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
@@ -914,13 +937,11 @@ public class LocationInference {
         NTuple<Location> paramLocTuple = translateToLocTuple(possibleMdCallee, paramDescTuple);
         addMapCallerArgToCalleeParam(min, argDescTuple, paramDescTuple);
       }
-
     }
 
     NTuple<Descriptor> baseTuple = mapMethodInvokeNodeToBaseTuple.get(min);
     GlobalFlowGraph calleeSubGlobalGraph = getSubGlobalFlowGraph(possibleMdCallee);
     Set<GlobalFlowNode> calleeNodeSet = calleeSubGlobalGraph.getNodeSet();
-    System.out.println("#calleeNodeSet=" + calleeNodeSet);
     for (Iterator iterator = calleeNodeSet.iterator(); iterator.hasNext();) {
       GlobalFlowNode calleeNode = (GlobalFlowNode) iterator.next();
       addValueFlowFromCalleeNode(min, mdCaller, possibleMdCallee, calleeNode);
@@ -999,13 +1020,8 @@ public class LocationInference {
 
   private NTuple<Location> translateToCallerLocTuple(MethodInvokeNode min,
       MethodDescriptor mdCallee, MethodDescriptor mdCaller, NTuple<Location> nodeLocTuple) {
-    // this method will return NULL if the corresponding argument is literal
+    // this method will return the same nodeLocTuple if the corresponding argument is literal
     // value.
-    // assumes that we don't need to propagate callee flows to the argument
-    // which is literal.
-
-    System.out.println("---translateToCallerLocTuple=" + min.printNode(0)
-        + "  callee nodeLocTuple=" + nodeLocTuple);
 
     FlowGraph calleeFlowGraph = getFlowGraph(mdCallee);
 
@@ -1013,12 +1029,10 @@ public class LocationInference {
     if (calleeFlowGraph.isParameter(nodeDescTuple)) {
       int paramIdx = calleeFlowGraph.getParamIdx(nodeDescTuple);
       NTuple<Descriptor> argDescTuple = mapMethodInvokeNodeToArgIdxMap.get(min).get(paramIdx);
-      // System.out.println(" mapMethodInvokeNodeToArgIdxMap.get(min)="
-      // + mapMethodInvokeNodeToArgIdxMap.get(min));
 
-      if (argDescTuple.size() == 0) {
-        // argument is literal
-        return null;
+      if (isPrimitive(nodeLocTuple.get(0).getLocDescriptor())) {
+        // the type of argument is primitive.
+        return nodeLocTuple.clone();
       }
       NTuple<Location> argLocTuple = translateToLocTuple(mdCaller, argDescTuple);
 
@@ -1035,6 +1049,19 @@ public class LocationInference {
 
   }
 
+  public static boolean isPrimitive(Descriptor desc) {
+
+    if (desc instanceof FieldDescriptor) {
+      return ((FieldDescriptor) desc).getType().isPrimitive();
+    } else if (desc instanceof VarDescriptor) {
+      return ((VarDescriptor) desc).getType().isPrimitive();
+    } else if (desc instanceof InterDescriptor) {
+      return true;
+    }
+
+    return false;
+  }
+
   private NTuple<Descriptor> translateToDescTuple(NTuple<Location> locTuple) {
 
     NTuple<Descriptor> descTuple = new NTuple<Descriptor>();
@@ -1245,13 +1272,25 @@ public class LocationInference {
       FlowGraph flowGraph = getFlowGraph(md);
       MethodSummary methodSummary = getMethodSummary(md);
 
-      // construct a parameter mapping that maps a parameter descriptor to an
-      // inferred composite
-      // location
+      HierarchyGraph scGraph = getSkeletonCombinationHierarchyGraph(md);
+
+      // set the 'this' reference location
+      if (!md.isStatic()) {
+        System.out.println("setThisLocName=" + scGraph.getHNode(md.getThis()).getName());
+        methodSummary.setThisLocName(scGraph.getHNode(md.getThis()).getName());
+      }
 
+      // set the 'global' reference location if needed
+      if (methodSummary.hasGlobalAccess()) {
+        methodSummary.setGlobalLocName(scGraph.getHNode(GLOBALDESC).getName());
+      }
+
+      // construct a parameter mapping that maps a parameter descriptor to an
+      // inferred composite location
       for (int paramIdx = 0; paramIdx < flowGraph.getNumParameters(); paramIdx++) {
         FlowNode flowNode = flowGraph.getParamFlowNode(paramIdx);
-        CompositeLocation inferredCompLoc = flowNode.getCompositeLocation();
+        CompositeLocation inferredCompLoc =
+            updateCompositeLocation(flowNode.getCompositeLocation());
         // NTuple<Descriptor> descTuple = flowNode.getDescTuple();
         //
         // CompositeLocation assignedCompLoc = flowNode.getCompositeLocation();
@@ -1264,8 +1303,11 @@ public class LocationInference {
         // loc.setLocDescriptor(locDesc);
         // inferredCompLoc = new CompositeLocation(loc);
         // }
-        System.out.println("-paramIdx=" + paramIdx + "   infer=" + inferredCompLoc);
-        System.out.println("-flowNode inferLoc=" + flowNode.getCompositeLocation());
+        System.out.println("-paramIdx=" + paramIdx + "   infer=" + inferredCompLoc + " original="
+            + flowNode.getCompositeLocation());
+
+        Descriptor localVarDesc = flowNode.getDescTuple().get(0);
+        methodSummary.addMapVarNameToInferCompLoc(localVarDesc, inferredCompLoc);
         methodSummary.addMapParamIdxToInferLoc(paramIdx, inferredCompLoc);
       }
 
@@ -1476,10 +1518,10 @@ public class LocationInference {
     Set<Descriptor> keySet = mapDescriptorToHierarchyGraph.keySet();
     for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
       Descriptor desc = (Descriptor) iterator.next();
+      System.out.println("SSJAVA: remove redundant edges: " + desc);
       HierarchyGraph simpleHierarchyGraph = getHierarchyGraph(desc).clone();
       simpleHierarchyGraph.setName(desc + "_SIMPLE");
       simpleHierarchyGraph.removeRedundantEdges();
-      // simpleHierarchyGraph.simplifyHierarchyGraph();
       mapDescriptorToSimpleHierarchyGraph.put(desc, simpleHierarchyGraph);
     }
   }
@@ -1505,6 +1547,7 @@ public class LocationInference {
     Set<Descriptor> keySet = mapDescriptorToHierarchyGraph.keySet();
     for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
       Descriptor desc = (Descriptor) iterator.next();
+      System.out.println("SSJAVA: Constructing Skeleton Hierarchy Graph: " + desc);
       HierarchyGraph simpleGraph = getSimpleHierarchyGraph(desc);
       HierarchyGraph skeletonGraph = simpleGraph.generateSkeletonGraph();
       skeletonGraph.setMapDescToHNode(simpleGraph.getMapDescToHNode());
@@ -1579,7 +1622,6 @@ public class LocationInference {
 
     // do fixed-point analysis
 
-    ssjava.init();
     LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
 
     // Collections.sort(descriptorListToAnalyze, new
@@ -1640,6 +1682,41 @@ public class LocationInference {
 
     }
 
+    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 HierarchyGraph getHierarchyGraph(Descriptor d) {
@@ -1663,9 +1740,16 @@ public class LocationInference {
 
     // for the method lattice, we need to look at the first element of
     // NTuple<Descriptor>
+    boolean hasGlobalAccess = false;
     for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
       FlowNode srcNode = (FlowNode) iterator.next();
 
+      // if the srcNode is started with the global descriptor
+      // need to set as a skeleton node
+      if (!hasGlobalAccess && srcNode.getDescTuple().startsWith(GLOBALDESC)) {
+        hasGlobalAccess = true;
+      }
+
       Set<FlowEdge> outEdgeSet = fg.getOutEdgeSet(srcNode);
       for (Iterator iterator2 = outEdgeSet.iterator(); iterator2.hasNext();) {
         FlowEdge outEdge = (FlowEdge) iterator2.next();
@@ -1716,6 +1800,23 @@ public class LocationInference {
       }
     }
 
+    // If the method accesses static fields
+    // set hasGloabalAccess true in the method summary.
+    if (hasGlobalAccess) {
+      getMethodSummary(md).setHasGlobalAccess();
+    }
+    methodGraph.getHNode(GLOBALDESC).setSkeleton(true);
+
+    if (ssjava.getMethodContainingSSJavaLoop().equals(md)) {
+      // if the current method contains the event loop
+      // we need to set all nodes of the hierarchy graph as a skeleton node
+      Set<HNode> hnodeSet = methodGraph.getNodeSet();
+      for (Iterator iterator = hnodeSet.iterator(); iterator.hasNext();) {
+        HNode hnode = (HNode) iterator.next();
+        hnode.setSkeleton(true);
+      }
+    }
+
   }
 
   private MethodSummary getMethodSummary(MethodDescriptor md) {
@@ -1850,22 +1951,27 @@ public class LocationInference {
     rtr += "\")";
 
     if (desc instanceof MethodDescriptor) {
-      TypeDescriptor returnType = ((MethodDescriptor) desc).getReturnType();
+      System.out.println("#EXTRA LOC DECLARATION GEN=" + desc);
 
-      MethodLocationInfo methodLocInfo = getMethodLocationInfo((MethodDescriptor) desc);
+      MethodDescriptor md = (MethodDescriptor) desc;
+      MethodSummary methodSummary = getMethodSummary(md);
 
-      if (returnType != null && (!returnType.isVoid())) {
-        rtr +=
-            "\n@RETURNLOC(\"" + generateLocationAnnoatation(methodLocInfo.getReturnLoc()) + "\")";
+      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) + "\")";
+        }
       }
 
-      rtr += "\n@THISLOC(\"this\")";
-      rtr += "\n@GLOBALLOC(\"GLOBALLOC\")";
-
-      CompositeLocation pcLoc = methodLocInfo.getPCLoc();
-      if ((pcLoc != null) && (!pcLoc.get(0).isTop())) {
-        rtr += "\n@PCLOC(\"" + generateLocationAnnoatation(pcLoc) + "\")";
+      if (!md.isStatic()) {
+        rtr += "\n@THISLOC(\"" + methodSummary.getThisLocName() + "\")";
       }
+      rtr += "\n@GLOBALLOC(\"" + methodSummary.getGlobalLocName() + "\")";
 
     }
 
@@ -1882,7 +1988,6 @@ public class LocationInference {
 
       setupToAnalazeMethod(cd);
 
-      LocationInfo locInfo = mapClassToLocationInfo.get(cd);
       String sourceFileName = cd.getSourceFileName();
 
       if (cd.isInterface()) {
@@ -1892,37 +1997,27 @@ public class LocationInference {
       int classDefLine = mapDescToDefinitionLine.get(cd);
       Vector<String> sourceVec = mapFileNameToLineVector.get(sourceFileName);
 
-      if (locInfo == null) {
-        locInfo = getLocationInfo(cd);
-      }
-
-      for (Iterator iter = cd.getFields(); iter.hasNext();) {
-        FieldDescriptor fieldDesc = (FieldDescriptor) iter.next();
-        if (!(fieldDesc.isStatic() && fieldDesc.isFinal())) {
-          String locIdentifier = locInfo.getFieldInferLocation(fieldDesc).getLocIdentifier();
-          if (!getLattice(cd).getElementSet().contains(locIdentifier)) {
-            getLattice(cd).put(locIdentifier);
-          }
-        }
-      }
+      LocationSummary fieldLocSummary = getLocationSummary(cd);
 
       String fieldLatticeDefStr = generateLatticeDefinition(cd);
       String annoatedSrc = fieldLatticeDefStr + newline + sourceVec.get(classDefLine);
       sourceVec.set(classDefLine, annoatedSrc);
 
       // generate annotations for field declarations
-      LocationInfo fieldLocInfo = getLocationInfo(cd);
-      Map<Descriptor, CompositeLocation> inferLocMap = fieldLocInfo.getMapDescToInferLocation();
+      // Map<Descriptor, CompositeLocation> inferLocMap = fieldLocInfo.getMapDescToInferLocation();
+      Map<String, String> mapFieldNameToLocName = fieldLocSummary.getMapHNodeNameToLocationName();
 
       for (Iterator iter = cd.getFields(); iter.hasNext();) {
         FieldDescriptor fd = (FieldDescriptor) iter.next();
 
         String locAnnotationStr;
-        CompositeLocation inferLoc = inferLocMap.get(fd);
+        // CompositeLocation inferLoc = inferLocMap.get(fd);
+        String locName = mapFieldNameToLocName.get(fd.getSymbol());
 
-        if (inferLoc != null) {
+        if (locName != null) {
           // infer loc is null if the corresponding field is static and final
-          locAnnotationStr = "@LOC(\"" + generateLocationAnnoatation(inferLoc) + "\")";
+          // locAnnotationStr = "@LOC(\"" + generateLocationAnnoatation(inferLoc) + "\")";
+          locAnnotationStr = "@LOC(\"" + locName + "\")";
           int fdLineNum = fd.getLineNum();
           String orgFieldDeclarationStr = sourceVec.get(fdLineNum);
           String fieldDeclaration = fd.toString();
@@ -1945,17 +2040,25 @@ public class LocationInference {
 
           int methodDefLine = md.getLineNum();
 
-          MethodLocationInfo methodLocInfo = getMethodLocationInfo(md);
+          // MethodLocationInfo methodLocInfo = getMethodLocationInfo(md);
+          // Map<Descriptor, CompositeLocation> methodInferLocMap =
+          // methodLocInfo.getMapDescToInferLocation();
+
+          MethodSummary methodSummary = getMethodSummary(md);
 
-          Map<Descriptor, CompositeLocation> methodInferLocMap =
-              methodLocInfo.getMapDescToInferLocation();
-          Set<Descriptor> localVarDescSet = methodInferLocMap.keySet();
+          Map<Descriptor, CompositeLocation> mapVarDescToInferLoc =
+              methodSummary.getMapVarDescToInferCompositeLocation();
+          System.out.println("-----md=" + md);
+          System.out.println("-----mapVarDescToInferLoc=" + mapVarDescToInferLoc);
+
+          Set<Descriptor> localVarDescSet = mapVarDescToInferLoc.keySet();
 
           Set<String> localLocElementSet = methodLattice.getElementSet();
 
           for (Iterator iterator = localVarDescSet.iterator(); iterator.hasNext();) {
             Descriptor localVarDesc = (Descriptor) iterator.next();
-            CompositeLocation inferLoc = methodInferLocMap.get(localVarDesc);
+            System.out.println("-------localVarDesc=" + localVarDesc);
+            CompositeLocation inferLoc = mapVarDescToInferLoc.get(localVarDesc);
 
             String localLocIdentifier = inferLoc.get(0).getLocIdentifier();
             if (!localLocElementSet.contains(localLocIdentifier)) {
@@ -1982,7 +2085,8 @@ public class LocationInference {
               int idx =
                   getParamLocation(methodDefStr,
                       generateVarDeclaration((VarDescriptor) localVarDesc));
-
+              System.out.println("methodDefStr=" + methodDefStr + " localVarDesc=" + localVarDesc
+                  + " idx=" + idx);
               assert (idx != -1);
 
               String annoatedStr =
@@ -1997,9 +2101,9 @@ public class LocationInference {
           // reference...
 
           // boolean needToAddthisRef = hasThisReference(md);
-          if (localLocElementSet.contains("this")) {
-            methodLattice.put("this");
-          }
+          // if (localLocElementSet.contains("this")) {
+          // methodLattice.put("this");
+          // }
 
           String methodLatticeDefStr = generateLatticeDefinition(md);
           String annoatedStr = methodLatticeDefStr + newline + sourceVec.get(methodDefLine);
@@ -2056,6 +2160,7 @@ public class LocationInference {
   }
 
   private String generateLocationAnnoatation(CompositeLocation loc) {
+    System.out.println("loc=" + loc);
     String rtr = "";
     // method location
     Location methodLoc = loc.get(0);
@@ -2170,27 +2275,16 @@ public class LocationInference {
 
   }
 
-  private void inferLattices() {
-  }
-
   private void calculateExtraLocations() {
-    LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
-    for (Iterator iterator = descriptorListToAnalyze.iterator(); iterator.hasNext();) {
-      MethodDescriptor md = (MethodDescriptor) iterator.next();
-      calculateExtraLocations(md);
-    }
-  }
 
-  private void calculateExtraLocations2() {
-    LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
-    for (Iterator iterator = descriptorListToAnalyze.iterator(); iterator.hasNext();) {
+    LinkedList<MethodDescriptor> methodDescList = ssjava.getSortedDescriptors();
+    for (Iterator iterator = methodDescList.iterator(); iterator.hasNext();) {
       MethodDescriptor md = (MethodDescriptor) iterator.next();
-      calculateExtraLocations(md);
+      if (!ssjava.getMethodContainingSSJavaLoop().equals(md)) {
+        calculateExtraLocations(md);
+      }
     }
-  }
 
-  private void setMethodLocInfo(MethodDescriptor md, MethodLocationInfo methodInfo) {
-    mapMethodDescToMethodLocationInfo.put(md, methodInfo);
   }
 
   private void checkLatticesOfVirtualMethods(MethodDescriptor md) {
@@ -2286,179 +2380,238 @@ public class LocationInference {
     return desc;
   }
 
-  private void calculateExtraLocations(MethodDescriptor md) {
-    // calcualte pcloc, returnloc,...
+  private void calculatePCLOC(MethodDescriptor md) {
 
-    System.out.println("\nSSJAVA:Calculate extra locations: " + md);
+    System.out.println("#calcualtePCLOC");
+    MethodSummary methodSummary = getMethodSummary(md);
+    FlowGraph fg = getFlowGraph(md);
+    Map<Integer, CompositeLocation> mapParamToLoc = methodSummary.getMapParamIdxToInferLoc();
 
-    SSJavaLattice<String> methodLattice = getMethodLattice(md);
+    // calculate the initial program counter location
+    // PC location is higher than location types of parameters which has incoming flows.
 
-    MethodSummary methodSummary = getMethodSummary(md);
+    Set<NTuple<Location>> paramLocTupleHavingInFlowSet = new HashSet<NTuple<Location>>();
+    Set<Descriptor> paramDescNOTHavingInFlowSet = new HashSet<Descriptor>();
+    // Set<FlowNode> paramNodeNOThavingInFlowSet = new HashSet<FlowNode>();
 
-    FlowGraph fg = getFlowGraph(md);
-    Set<FlowNode> nodeSet = fg.getNodeSet();
+    int numParams = fg.getNumParameters();
+    for (int i = 0; i < numParams; i++) {
+      FlowNode paramFlowNode = fg.getParamFlowNode(i);
+      Descriptor prefix = paramFlowNode.getDescTuple().get(0);
+      NTuple<Descriptor> paramDescTuple = paramFlowNode.getCurrentDescTuple();
+      NTuple<Location> paramLocTuple = translateToLocTuple(md, paramDescTuple);
 
-    // for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) {
-    // FlowNode flowNode = (FlowNode) iterator.next();
-    // if (flowNode.isDeclaratonNode()) {
-    // CompositeLocation inferLoc = methodInfo.getInferLocation(flowNode.getDescTuple().get(0));
-    // String locIdentifier = inferLoc.get(0).getLocIdentifier();
-    // if (!methodLattice.containsKey(locIdentifier)) {
-    // methodLattice.put(locIdentifier);
-    // }
-    // }
-    // }
-    MethodLocationInfo methodInfo = getMethodLocationInfo(md);
+      if (fg.getIncomingNodeSetByPrefix(prefix).size() > 0) {
+        // parameter has in-value flows
+        paramLocTupleHavingInFlowSet.add(paramLocTuple);
+      } else {
+        // paramNodeNOThavingInFlowSet.add(fg.getFlowNode(paramDescTuple));
+        paramDescNOTHavingInFlowSet.add(prefix);
+      }
+    }
 
-    Map<Integer, CompositeLocation> mapParamToLoc = methodSummary.getMapParamIdxToInferLoc();
-    Set<Integer> paramIdxSet = mapParamToLoc.keySet();
+    System.out.println("paramNodeNOThavingInFlowSet=" + paramDescNOTHavingInFlowSet);
 
-    if (!ssjava.getMethodContainingSSJavaLoop().equals(md)) {
-      // calculate the initial program counter location
-      // PC location is higher than location types of parameters which has incoming flows.
-      String pcLocSymbol = "PCLOC";
+    if (paramLocTupleHavingInFlowSet.size() > 0
+        && !coversAllParamters(md, fg, paramLocTupleHavingInFlowSet)) {
 
-      Set<NTuple<Location>> paramLocTupleHavingInFlowSet = new HashSet<NTuple<Location>>();
+      // Here, generates a location in the method lattice that is higher than the
+      // paramLocTupleHavingInFlowSet
+      NTuple<Location> pcLocTuple =
+          generateLocTupleRelativeTo(md, paramLocTupleHavingInFlowSet, PCLOC);
 
-      int numParams = fg.getNumParameters();
-      for (int i = 0; i < numParams; i++) {
-        FlowNode paramFlowNode = fg.getParamFlowNode(i);
+      NTuple<Descriptor> pcDescTuple = translateToDescTuple(pcLocTuple);
 
-        Descriptor prefix = paramFlowNode.getDescTuple().get(0);
+      // add ordering relations s.t. PCLOC is higher than all flow nodes except the set of
+      // parameters that do not have incoming flows
 
-        // if (fg.getIncomingFlowNodeSet(paramFlowNode).size() > 0) {
-        if (fg.getIncomingNodeSetByPrefix(prefix).size() > 0) {
-          // parameter has in-value flows
-          NTuple<Descriptor> paramDescTuple = paramFlowNode.getCurrentDescTuple();
-          NTuple<Location> paramLocTuple = translateToLocTuple(md, paramDescTuple);
+      for (Iterator iterator = fg.getNodeSet().iterator(); iterator.hasNext();) {
+        FlowNode node = (FlowNode) iterator.next();
 
-          paramLocTupleHavingInFlowSet.add(paramLocTuple);
-          // CompositeLocation inferLoc = mapParamToLoc.get(paramIdx);
-          // paramInFlowSet.add(inferLoc);
+        if (!paramDescNOTHavingInFlowSet.contains(node.getCurrentDescTuple().get(0))) {
+          fg.addValueFlowEdge(pcDescTuple, node.getDescTuple());
         }
       }
 
-      System.out.println("paramLocTupleHavingInFlowSet=" + paramLocTupleHavingInFlowSet);
+      System.out.println("pcLoc=" + pcLocTuple);
+
+      methodSummary.setPCLoc(new CompositeLocation(pcLocTuple));
+    }
+  }
+
+  private boolean coversAllParamters(MethodDescriptor md, FlowGraph fg,
+      Set<NTuple<Location>> paramLocTupleHavingInFlowSet) {
 
-      int numParamsWithIncomingValue = paramLocTupleHavingInFlowSet.size();
+    int numParam = fg.getNumParameters();
+    int size = paramLocTupleHavingInFlowSet.size();
 
-      if (paramLocTupleHavingInFlowSet.size() > 0
-          && numParamsWithIncomingValue == fg.getNumParameters()) {
-        // If the PC loc is going to be higher than all paramters, we dont' need to do anything
+    if (!md.isStatic()) {
 
-        // Generates a location in the method lattice that is higher than the
-        // paramLocTupleHavingInFlowSet
-        NTuple<Location> pcLocTuple = generateLocTupleHigherThan(md, paramLocTupleHavingInFlowSet);
+      // if the method is not static && there is a parameter composite location &&
+      // it is started with 'this',
+      // paramLocTupleHavingInFlowSet need to have 'this' parameter.
 
-        int pcLocTupleIdx = pcLocTuple.size() - 1;
-        Location pcLoc = pcLocTuple.get(pcLocTupleIdx);
-        Descriptor pcDesc = pcLoc.getLocDescriptor();
-        Descriptor enclosingDesc = pcLocTuple.get(pcLocTupleIdx).getDescriptor();
+      FlowNode thisParamNode = fg.getParamFlowNode(0);
+      NTuple<Location> thisParamLocTuple =
+          translateToLocTuple(md, thisParamNode.getCurrentDescTuple());
 
-        HierarchyGraph hierarchyGraph = getHierarchyGraph(enclosingDesc);
-        HNode pcNode = hierarchyGraph.getHNode(pcDesc);
-        pcNode.setSkeleton(true);
+      if (!paramLocTupleHavingInFlowSet.contains(thisParamLocTuple)) {
 
         for (Iterator iterator = paramLocTupleHavingInFlowSet.iterator(); iterator.hasNext();) {
-          NTuple<Location> paramLocTuple = (NTuple<Location>) iterator.next();
-          Descriptor lowerDesc = paramLocTuple.get(pcLocTupleIdx).getLocDescriptor();
-          hierarchyGraph.addEdge(pcDesc, lowerDesc);
+          NTuple<Location> paramTuple = (NTuple<Location>) iterator.next();
+          if (paramTuple.size() > 1 && paramTuple.get(0).getLocDescriptor().equals(md.getThis())) {
+            // paramLocTupleHavingInFlowSet.add(thisParamLocTuple);
+            // break;
+            size++;
+          }
         }
 
       }
+    }
 
+    if (size == numParam) {
+      return true;
+    } else {
+      return false;
     }
 
-    // calculate a return location
-    // the return location type is lower than all parameters and location
-    // types of return values
+  }
+
+  private void calculateRETURNLOC(MethodDescriptor md) {
+
+    System.out.println("#calculateRETURNLOC= " + md);
+    // calculate a return location:
+    // the return location type is lower than all parameters and the location of return values
+    MethodSummary methodSummary = getMethodSummary(md);
+    FlowGraph fg = getFlowGraph(md);
+    Map<Integer, CompositeLocation> mapParamToLoc = methodSummary.getMapParamIdxToInferLoc();
+    Set<Integer> paramIdxSet = mapParamToLoc.keySet();
+
     if (!md.getReturnType().isVoid()) {
       // first, generate the set of return value location types that starts
       // with 'this' reference
 
-      Set<CompositeLocation> inferFieldReturnLocSet = new HashSet<CompositeLocation>();
-
       Set<FlowNode> paramFlowNodeFlowingToReturnValueSet = getParamNodeFlowingToReturnValue(md);
-      Set<CompositeLocation> inferParamLocSet = new HashSet<CompositeLocation>();
+      System.out.println("paramFlowNodeFlowingToReturnValueSet="
+          + paramFlowNodeFlowingToReturnValueSet);
+
+      Set<NTuple<Location>> tupleToBeHigherThanReturnLocSet = new HashSet<NTuple<Location>>();
       for (Iterator iterator = paramFlowNodeFlowingToReturnValueSet.iterator(); iterator.hasNext();) {
         FlowNode fn = (FlowNode) iterator.next();
-        CompositeLocation inferLoc =
-            generateInferredCompositeLocation(methodInfo, getFlowGraph(md).getLocationTuple(fn));
-        inferParamLocSet.add(inferLoc);
+        NTuple<Descriptor> paramDescTuple = fn.getCurrentDescTuple();
+        tupleToBeHigherThanReturnLocSet.add(translateToLocTuple(md, paramDescTuple));
       }
 
       Set<FlowNode> returnNodeSet = fg.getReturnNodeSet();
-
-      skip: for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
+      for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
         FlowNode returnNode = (FlowNode) iterator.next();
-        CompositeLocation inferReturnLoc =
-            generateInferredCompositeLocation(methodInfo, fg.getLocationTuple(returnNode));
-        if (inferReturnLoc.get(0).getLocIdentifier().equals("this")) {
-          // if the location type of the return value matches "this" reference
-          // then, check whether this return value is equal to/lower than all
-          // of parameters that possibly flow into the return values
-          for (Iterator iterator2 = inferParamLocSet.iterator(); iterator2.hasNext();) {
-            CompositeLocation paramInferLoc = (CompositeLocation) iterator2.next();
+        NTuple<Descriptor> returnDescTuple = returnNode.getCurrentDescTuple();
+        tupleToBeHigherThanReturnLocSet.add(translateToLocTuple(md, returnDescTuple));
+      }
+      System.out.println("-flow graph's returnNodeSet=" + returnNodeSet);
+      System.out.println("tupleSetToBeHigherThanReturnLoc=" + tupleToBeHigherThanReturnLocSet);
 
-            if ((!paramInferLoc.equals(inferReturnLoc))
-                && !isGreaterThan(methodLattice, paramInferLoc, inferReturnLoc)) {
-              continue skip;
-            }
-          }
-          inferFieldReturnLocSet.add(inferReturnLoc);
+      // Here, generates a return location in the method lattice that is lower than the
+      // locFlowingToReturnValueSet
+      NTuple<Location> returnLocTuple =
+          generateLocTupleRelativeTo(md, tupleToBeHigherThanReturnLocSet, RLOC);
 
-        }
+      System.out.println("returnLocTuple=" + returnLocTuple);
+
+      NTuple<Descriptor> returnDescTuple = translateToDescTuple(returnLocTuple);
+      for (Iterator iterator = tupleToBeHigherThanReturnLocSet.iterator(); iterator.hasNext();) {
+        NTuple<Location> higherTuple = (NTuple<Location>) iterator.next();
+        fg.addValueFlowEdge(translateToDescTuple(higherTuple), returnDescTuple);
       }
 
-      if (inferFieldReturnLocSet.size() > 0) {
+      fg.getFlowNode(returnDescTuple).setSkeleton(true);
+      System.out.println("fg node set=" + fg.getNodeSet());
 
-        CompositeLocation returnLoc = getLowest(methodLattice, inferFieldReturnLocSet);
-        if (returnLoc == null) {
-          // in this case, assign <'this',bottom> to the RETURNLOC
-          returnLoc = new CompositeLocation(new Location(md, md.getThis().getSymbol()));
-          returnLoc.addLocation(new Location(md.getClassDesc(), getLattice(md.getClassDesc())
-              .getBottomItem()));
-        }
-        methodInfo.setReturnLoc(returnLoc);
+      methodSummary.setRETURNLoc(new CompositeLocation(returnLocTuple));
 
-      } else {
-        String returnLocSymbol = "RETURNLOC";
-        CompositeLocation returnLocInferLoc =
-            new CompositeLocation(new Location(md, returnLocSymbol));
-        methodInfo.setReturnLoc(returnLocInferLoc);
+      // skip: for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
+      // FlowNode returnNode = (FlowNode) iterator.next();
+      //
+      // NTuple<Descriptor> returnDescTuple = returnNode.getCurrentDescTuple();
+      // NTuple<Location> returnLocTuple = translateToLocTuple(md, returnDescTuple);
+      //
+      // if (returnLocTuple.get(0).getLocDescriptor().equals(md.getThis())) {
+      // // if the location type of the return value matches "this" reference
+      // // then, check whether this return value is equal to/lower than all
+      // // of parameters that possibly flow into the return values
+      // for (Iterator iterator2 = inferParamLocSet.iterator(); iterator2.hasNext();) {
+      // CompositeLocation paramInferLoc = (CompositeLocation) iterator2.next();
+      //
+      // if ((!paramInferLoc.equals(returnLocTuple))
+      // && !isGreaterThan(methodLattice, paramInferLoc, inferReturnLoc)) {
+      // continue skip;
+      // }
+      // }
+      // inferFieldReturnLocSet.add(returnLocTuple);
+      //
+      // }
+      // }
 
-        for (Iterator iterator = paramIdxSet.iterator(); iterator.hasNext();) {
-          Integer paramIdx = (Integer) iterator.next();
-          CompositeLocation inferLoc = mapParamToLoc.get(paramIdx);
-          String paramLocLocalSymbol = inferLoc.get(0).getLocIdentifier();
-          if (!methodLattice.isGreaterThan(paramLocLocalSymbol, returnLocSymbol)) {
-            // TODO
-            // addRelationHigherToLower(methodLattice, methodInfo,
-            // paramLocLocalSymbol,
-            // returnLocSymbol);
-          }
-        }
+      // if (inferFieldReturnLocSet.size() > 0) {
+      //
+      // // CompositeLocation returnLoc = getLowest(methodLattice, inferFieldReturnLocSet);
+      // CompositeLocation returnLoc = null;
+      // if (returnLoc == null) {
+      // // in this case, assign <'this',bottom> to the RETURNLOC
+      // returnLoc = new CompositeLocation(new Location(md, md.getThis().getSymbol()));
+      // returnLoc.addLocation(new Location(md.getClassDesc(), getLattice(md.getClassDesc())
+      // .getBottomItem()));
+      // }
+      // methodInfo.setReturnLoc(returnLoc);
+      //
+      // } else {
+      // String returnLocSymbol = "RETURNLOC";
+      // CompositeLocation returnLocInferLoc =
+      // new CompositeLocation(new Location(md, returnLocSymbol));
+      // methodInfo.setReturnLoc(returnLocInferLoc);
+      //
+      // for (Iterator iterator = paramIdxSet.iterator(); iterator.hasNext();) {
+      // Integer paramIdx = (Integer) iterator.next();
+      // CompositeLocation inferLoc = mapParamToLoc.get(paramIdx);
+      // String paramLocLocalSymbol = inferLoc.get(0).getLocIdentifier();
+      // if (!methodLattice.isGreaterThan(paramLocLocalSymbol, returnLocSymbol)) {
+      // // TODO
+      // // addRelationHigherToLower(methodLattice, methodInfo,
+      // // paramLocLocalSymbol,
+      // // returnLocSymbol);
+      // }
+      // }
+      //
+      // for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
+      // FlowNode returnNode = (FlowNode) iterator.next();
+      // CompositeLocation inferLoc =
+      // generateInferredCompositeLocation(methodInfo, fg.getLocationTuple(returnNode));
+      // if (!isGreaterThan(methodLattice, inferLoc, returnLocInferLoc)) {
+      // // TODO
+      // // addRelation(methodLattice, methodInfo, inferLoc,
+      // // returnLocInferLoc);
+      // }
+      // }
+      //
+      // }
 
-        for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
-          FlowNode returnNode = (FlowNode) iterator.next();
-          CompositeLocation inferLoc =
-              generateInferredCompositeLocation(methodInfo, fg.getLocationTuple(returnNode));
-          if (!isGreaterThan(methodLattice, inferLoc, returnLocInferLoc)) {
-            // TODO
-            // addRelation(methodLattice, methodInfo, inferLoc,
-            // returnLocInferLoc);
-          }
-        }
+    }
+  }
 
-      }
+  private void calculateExtraLocations(MethodDescriptor md) {
+    // calcualte pcloc, returnloc,...
+
+    System.out.println("\nSSJAVA:Calculate PCLOC/RETURNLOC locations: " + md);
+
+    calculatePCLOC(md);
+    calculateRETURNLOC(md);
 
-    }
   }
 
-  private NTuple<Location> generateLocTupleHigherThan(MethodDescriptor md,
-      Set<NTuple<Location>> paramLocTupleHavingInFlowSet) {
+  private NTuple<Location> generateLocTupleRelativeTo(MethodDescriptor md,
+      Set<NTuple<Location>> paramLocTupleHavingInFlowSet, String locNamePrefix) {
 
-    System.out.println("-generateLocTupleHigherThan=" + paramLocTupleHavingInFlowSet);
+    System.out.println("-generateLocTupleRelativeTo=" + paramLocTupleHavingInFlowSet);
 
     NTuple<Location> higherLocTuple = new NTuple<Location>();
 
@@ -2466,7 +2619,7 @@ public class LocationInference {
     // check if all paramter loc tuple is started with 'this' reference
     boolean hasParamNotStartedWithThisRef = false;
 
-    int maxSize = 0;
+    int minSize = 0;
 
     Set<NTuple<Location>> paramLocTupleStartedWithThis = new HashSet<NTuple<Location>>();
 
@@ -2476,28 +2629,31 @@ public class LocationInference {
         hasParamNotStartedWithThisRef = true;
       } else if (paramLocTuple.size() > 1) {
         paramLocTupleStartedWithThis.add(paramLocTuple);
-        if (maxSize < paramLocTuple.size()) {
-          maxSize = paramLocTuple.size();
+        if (minSize == 0 || minSize > paramLocTuple.size()) {
+          minSize = paramLocTuple.size();
         }
       }
     }
 
+    System.out.println("---paramLocTupleStartedWithThis=" + paramLocTupleStartedWithThis);
     Descriptor enclosingDesc = md;
     if (hasParamNotStartedWithThisRef) {
       // in this case, PCLOC will be the local location
     } else {
       // all parameter is started with 'this', so PCLOC will be set relative to the composite
       // location started with 'this'.
-      for (int idx = 0; idx < maxSize - 1; idx++) {
+      for (int idx = 0; idx < minSize - 1; idx++) {
         Set<Descriptor> locDescSet = new HashSet<Descriptor>();
         Location curLoc = null;
-        for (Iterator iterator = paramLocTupleHavingInFlowSet.iterator(); iterator.hasNext();) {
-          NTuple<Location> paramLocTuple = (NTuple<Location>) iterator.next();
+        NTuple<Location> paramLocTuple = null;
+        for (Iterator iterator = paramLocTupleStartedWithThis.iterator(); iterator.hasNext();) {
+          paramLocTuple = (NTuple<Location>) iterator.next();
+          System.out.println("-----paramLocTuple=" + paramLocTuple + "  idx=" + idx);
           curLoc = paramLocTuple.get(idx);
           Descriptor locDesc = curLoc.getLocDescriptor();
           locDescSet.add(locDesc);
         }
-        System.out.println("locDescSet=" + locDescSet + " idx=" + idx);
+        System.out.println("-----locDescSet=" + locDescSet + " idx=" + idx);
         if (locDescSet.size() != 1) {
           break;
         }
@@ -2508,12 +2664,12 @@ public class LocationInference {
 
     }
 
-    String pcLocIdentifier = PCLOC + (locSeed++);
+    String pcLocIdentifier = locNamePrefix + (locSeed++);
     NameDescriptor pcLocDesc = new NameDescriptor(pcLocIdentifier);
     Location newLoc = new Location(enclosingDesc, pcLocDesc);
     higherLocTuple.add(newLoc);
 
-    System.out.println("---higherLocTuple=" + higherLocTuple);
+    System.out.println("---new loc tuple=" + higherLocTuple);
 
     return higherLocTuple;
 
@@ -2523,9 +2679,17 @@ public class LocationInference {
 
     if (in instanceof VarDescriptor) {
       return ((VarDescriptor) in).getType().getClassDesc();
-    } else {/* if (desc instanceof FieldDescriptor) { */
+    } else if (in instanceof FieldDescriptor) {
       return ((FieldDescriptor) in).getType().getClassDesc();
     }
+    // else if (in instanceof LocationDescriptor) {
+    // // here is the case that the descriptor 'in' is the last element of the assigned composite
+    // // location
+    // return ((VarDescriptor) locTuple.get(0).getLocDescriptor()).getType().getClassDesc();
+    // }
+    else {
+      return null;
+    }
 
   }
 
@@ -2838,8 +3002,6 @@ public class LocationInference {
   private void propagateFlowsToCallerWithNoCompositeLocation(MethodInvokeNode min,
       MethodDescriptor mdCaller, MethodDescriptor mdCallee) {
 
-    System.out.println("\n##PROPAGATE callee=" + mdCallee + "TO caller=" + mdCaller);
-
     // if the parameter A reaches to the parameter B
     // then, add an edge the argument A -> the argument B to the caller's flow
     // graph
@@ -2863,19 +3025,19 @@ public class LocationInference {
           // parameters
 
           Set<FlowNode> localReachSet = calleeFlowGraph.getLocalReachFlowNodeSetFrom(paramNode1);
-          System.out.println("-param1=" + paramNode1 + " is higher than param2=" + paramNode2);
-          System.out.println("-- localReachSet from param1=" + localReachSet);
+          // System.out.println("-param1=" + paramNode1 + " is higher than param2=" + paramNode2);
+          // System.out.println("-- localReachSet from param1=" + localReachSet);
 
           if (arg1Tuple.size() > 0 && arg2Tuple.size() > 0 && localReachSet.contains(paramNode2)) {
             // need to propagate an ordering relation s.t. arg1 is higher
             // than arg2
 
-            System.out
-                .println("-arg1Tuple=" + arg1Tuple + " is higher than arg2Tuple=" + arg2Tuple);
+            // System.out
+            // .println("-arg1Tuple=" + arg1Tuple + " is higher than arg2Tuple=" + arg2Tuple);
 
             // otherwise, flows between method/field locations...
             callerFlowGraph.addValueFlowEdge(arg1Tuple, arg2Tuple);
-            System.out.println("arg1=" + arg1Tuple + "   arg2=" + arg2Tuple);
+            // System.out.println("arg1=" + arg1Tuple + "   arg2=" + arg2Tuple);
 
           }
 
@@ -2883,7 +3045,7 @@ public class LocationInference {
         }
       }
     }
-    System.out.println("##\n");
+    // System.out.println("##\n");
 
   }
 
@@ -3105,6 +3267,9 @@ public class LocationInference {
     if (lastDescOfPrefix instanceof FieldDescriptor) {
       enclosingDescriptor = ((FieldDescriptor) lastDescOfPrefix).getType().getClassDesc();
       // System.out.println("enclosingDescriptor0=" + enclosingDescriptor);
+    } else if (lastDescOfPrefix.equals(GLOBALDESC)) {
+      MethodDescriptor currentMethodDesc = (MethodDescriptor) prefixLocTuple.get(0).getDescriptor();
+      enclosingDescriptor = currentMethodDesc.getClassDesc();
     } else {
       // var descriptor case
       enclosingDescriptor = ((VarDescriptor) lastDescOfPrefix).getType().getClassDesc();
@@ -3279,13 +3444,13 @@ public class LocationInference {
 
       if (curDescriptor instanceof VarDescriptor) {
         enclosingDescriptor = md.getClassDesc();
+      } else if (curDescriptor instanceof FieldDescriptor) {
+        enclosingDescriptor = ((FieldDescriptor) curDescriptor).getClassDescriptor();
       } else if (curDescriptor instanceof NameDescriptor) {
         // it is "GLOBAL LOC" case!
         enclosingDescriptor = GLOBALDESC;
-      } else if (curDescriptor instanceof InterDescriptor) {
-        enclosingDescriptor = null;
       } else {
-        enclosingDescriptor = ((FieldDescriptor) curDescriptor).getClassDescriptor();
+        enclosingDescriptor = null;
       }
 
     }
@@ -3609,17 +3774,17 @@ public class LocationInference {
       MethodDescriptor md = methodDescList.removeLast();
       if (state.SSJAVADEBUG) {
         System.out.println();
-        System.out.println("SSJAVA: Constructing a flow graph2: " + md);
+        System.out.println("SSJAVA: Constructing a sub global flow graph: " + md);
 
-        System.out.println("##constructSubGlobalFlowGraph");
         GlobalFlowGraph subGlobalFlowGraph = constructSubGlobalFlowGraph(getFlowGraph(md));
         mapMethodDescriptorToSubGlobalFlowGraph.put(md, subGlobalFlowGraph);
 
         // TODO
-        System.out.println("##addValueFlowsFromCalleeSubGlobalFlowGraph");
+        System.out.println("-add Value Flows From CalleeSubGlobalFlowGraph");
         addValueFlowsFromCalleeSubGlobalFlowGraph(md, subGlobalFlowGraph);
         subGlobalFlowGraph.writeGraph("_SUBGLOBAL");
 
+        System.out.println("-propagate Flows From Callees With No CompositeLocation");
         propagateFlowsFromCalleesWithNoCompositeLocation(md);
 
       }
@@ -3854,7 +4019,7 @@ public class LocationInference {
     newImplicitTupleSet.addTupleSet(implicitFlowTupleSet);
     newImplicitTupleSet.addTupleSet(condTupleNode);
 
-    if (newImplicitTupleSet.size() > 1) {
+    if (needToGenerateInterLoc(newImplicitTupleSet)) {
       // need to create an intermediate node for the GLB of conditional
       // locations & implicit flows
       NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
@@ -3881,6 +4046,7 @@ public class LocationInference {
   private void analyzeFlowReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode rn,
       NodeTupleSet implicitFlowTupleSet) {
 
+    System.out.println("-analyzeFlowReturnNode=" + rn.printNode(0));
     ExpressionNode returnExp = rn.getReturnExpression();
 
     if (returnExp != null) {
@@ -3918,22 +4084,54 @@ public class LocationInference {
       // add tuples corresponding to the current implicit flows
       currentFlowTupleSet.addTupleSet(implicitFlowTupleSet);
 
-      if (currentFlowTupleSet.size() > 1) {
+      System.out.println("---currentFlowTupleSet=" + currentFlowTupleSet);
+
+      if (needToGenerateInterLoc(currentFlowTupleSet)) {
+        System.out.println("---needToGenerateInterLoc");
         FlowNode meetNode = fg.createIntermediateNode();
         for (Iterator iterator = currentFlowTupleSet.iterator(); iterator.hasNext();) {
           NTuple<Descriptor> currentFlowTuple = (NTuple<Descriptor>) iterator.next();
           fg.addValueFlowEdge(currentFlowTuple, meetNode.getDescTuple());
         }
         fg.addReturnFlowNode(meetNode.getDescTuple());
-      } else if (currentFlowTupleSet.size() == 1) {
-        NTuple<Descriptor> tuple = currentFlowTupleSet.iterator().next();
-        fg.addReturnFlowNode(tuple);
+      } else {
+        // currentFlowTupleSet = removeLiteralTuple(currentFlowTupleSet);
+        for (Iterator iterator = currentFlowTupleSet.iterator(); iterator.hasNext();) {
+          NTuple<Descriptor> currentFlowTuple = (NTuple<Descriptor>) iterator.next();
+          fg.addReturnFlowNode(currentFlowTuple);
+        }
       }
 
     }
 
   }
 
+  private NodeTupleSet removeLiteralTuple(NodeTupleSet inSet) {
+    NodeTupleSet tupleSet = new NodeTupleSet();
+    for (Iterator<NTuple<Descriptor>> iter = inSet.iterator(); iter.hasNext();) {
+      NTuple<Descriptor> tuple = iter.next();
+      if (!tuple.get(0).equals(LITERALDESC)) {
+        tupleSet.addTuple(tuple);
+      }
+    }
+    return tupleSet;
+  }
+
+  private boolean needToGenerateInterLoc(NodeTupleSet tupleSet) {
+    int size = 0;
+    for (Iterator<NTuple<Descriptor>> iter = tupleSet.iterator(); iter.hasNext();) {
+      NTuple<Descriptor> descTuple = iter.next();
+      if (!descTuple.get(0).equals(LITERALDESC)) {
+        size++;
+      }
+    }
+    if (size > 1) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   private void analyzeFlowLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln,
       NodeTupleSet implicitFlowTupleSet) {
 
@@ -3948,7 +4146,7 @@ public class LocationInference {
       newImplicitTupleSet.addTupleSet(implicitFlowTupleSet);
       newImplicitTupleSet.addTupleSet(condTupleNode);
 
-      if (newImplicitTupleSet.size() > 1) {
+      if (needToGenerateInterLoc(newImplicitTupleSet)) {
         // need to create an intermediate node for the GLB of conditional
         // locations & implicit flows
         NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
@@ -4003,24 +4201,42 @@ public class LocationInference {
       analyzeFlowExpressionNode(md, bn.getVarTable(), ln.getCondition(), condTupleNode, null,
           implicitFlowTupleSet, false);
 
-      // ///////////
-      NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+      NodeTupleSet newImplicitTupleSet = new NodeTupleSet();
+      newImplicitTupleSet.addTupleSet(implicitFlowTupleSet);
+      newImplicitTupleSet.addTupleSet(condTupleNode);
 
-      for (Iterator<NTuple<Descriptor>> idxIter = condTupleNode.iterator(); idxIter.hasNext();) {
-        NTuple<Descriptor> tuple = idxIter.next();
-        addFlowGraphEdge(md, tuple, interTuple);
-      }
+      if (needToGenerateInterLoc(newImplicitTupleSet)) {
+        // need to create an intermediate node for the GLB of conditional
+        // locations & implicit flows
+        NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+        for (Iterator<NTuple<Descriptor>> idxIter = newImplicitTupleSet.iterator(); idxIter
+            .hasNext();) {
+          NTuple<Descriptor> tuple = idxIter.next();
+          addFlowGraphEdge(md, tuple, interTuple);
+        }
+        newImplicitTupleSet.clear();
+        newImplicitTupleSet.addTuple(interTuple);
 
-      for (Iterator<NTuple<Descriptor>> idxIter = implicitFlowTupleSet.iterator(); idxIter
-          .hasNext();) {
-        NTuple<Descriptor> tuple = idxIter.next();
-        addFlowGraphEdge(md, tuple, interTuple);
       }
 
-      NodeTupleSet newImplicitSet = new NodeTupleSet();
-      newImplicitSet.addTuple(interTuple);
-      analyzeFlowBlockNode(md, bn.getVarTable(), ln.getUpdate(), newImplicitSet);
-      analyzeFlowBlockNode(md, bn.getVarTable(), ln.getBody(), newImplicitSet);
+      // ///////////
+      // NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+      //
+      // for (Iterator<NTuple<Descriptor>> idxIter = condTupleNode.iterator(); idxIter.hasNext();) {
+      // NTuple<Descriptor> tuple = idxIter.next();
+      // addFlowGraphEdge(md, tuple, interTuple);
+      // }
+      //
+      // for (Iterator<NTuple<Descriptor>> idxIter = implicitFlowTupleSet.iterator(); idxIter
+      // .hasNext();) {
+      // NTuple<Descriptor> tuple = idxIter.next();
+      // addFlowGraphEdge(md, tuple, interTuple);
+      // }
+      //
+      // NodeTupleSet newImplicitSet = new NodeTupleSet();
+      // newImplicitSet.addTuple(interTuple);
+      analyzeFlowBlockNode(md, bn.getVarTable(), ln.getUpdate(), newImplicitTupleSet);
+      analyzeFlowBlockNode(md, bn.getVarTable(), ln.getBody(), newImplicitTupleSet);
       // ///////////
 
       // condTupleNode.addTupleSet(implicitFlowTupleSet);
@@ -4037,7 +4253,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,
@@ -4048,11 +4264,11 @@ public class LocationInference {
     newImplicitTupleSet.addTupleSet(implicitFlowTupleSet);
     newImplicitTupleSet.addTupleSet(condTupleNode);
 
-    System.out.println("condTupleNode=" + condTupleNode);
-    System.out.println("implicitFlowTupleSet=" + implicitFlowTupleSet);
-    System.out.println("newImplicitTupleSet=" + newImplicitTupleSet);
+    // System.out.println("condTupleNode=" + condTupleNode);
+    // System.out.println("implicitFlowTupleSet=" + implicitFlowTupleSet);
+    // System.out.println("newImplicitTupleSet=" + newImplicitTupleSet);
 
-    if (newImplicitTupleSet.size() > 1) {
+    if (needToGenerateInterLoc(newImplicitTupleSet)) {
 
       // need to create an intermediate node for the GLB of conditional locations & implicit flows
       NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
@@ -4090,7 +4306,7 @@ public class LocationInference {
 
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
-      if (nodeSetRHS.size() > 1) {
+      if (needToGenerateInterLoc(nodeSetRHS)) {
         interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
       }
 
@@ -4168,7 +4384,7 @@ public class LocationInference {
       break;
 
     case Kind.LiteralNode:
-      analyzeLiteralNode(md, nametable, (LiteralNode) en);
+      analyzeFlowLiteralNode(md, nametable, (LiteralNode) en, nodeSet);
       break;
 
     case Kind.MethodInvokeNode:
@@ -4286,6 +4502,8 @@ public class LocationInference {
       FlowGraph calleeFlowGraph = getFlowGraph(calleeMethodDesc);
       Set<FlowNode> calleeReturnSet = calleeFlowGraph.getReturnNodeSet();
 
+      // System.out.println("-calleeReturnSet=" + calleeReturnSet);
+
       if (min.getExpression() != null) {
 
         NodeTupleSet baseNodeSet = new NodeTupleSet();
@@ -4311,7 +4529,7 @@ public class LocationInference {
             } else {
               // TODO
               Set<FlowNode> inFlowSet = calleeFlowGraph.getIncomingFlowNodeSet(returnNode);
-              System.out.println("inFlowSet=" + inFlowSet + "   from retrunNode=" + 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(calleeMethodDesc.getThis())) {
@@ -4343,8 +4561,7 @@ public class LocationInference {
           // if argument is liternal node, argTuple is set to NULL
 
           NTuple<Descriptor> argTuple = new NTuple<Descriptor>();
-          System.out.println("-argTupleSet=" + argTupleSet + "  from en=" + en.printNode(0));
-          if (argTupleSet.size() > 1) {
+          if (needToGenerateInterLoc(argTupleSet)) {
             NTuple<Descriptor> interTuple =
                 getFlowGraph(md).createIntermediateNode().getDescTuple();
             for (Iterator<NTuple<Descriptor>> idxIter = argTupleSet.iterator(); idxIter.hasNext();) {
@@ -4409,8 +4626,11 @@ public class LocationInference {
     mapIdxToTuple.put(new Integer(idx), argTuple);
   }
 
-  private void analyzeLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode en) {
-
+  private void analyzeFlowLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode en,
+      NodeTupleSet nodeSet) {
+    NTuple<Descriptor> tuple = new NTuple<Descriptor>();
+    tuple.add(LITERALDESC);
+    nodeSet.addTuple(tuple);
   }
 
   private void analyzeFlowArrayAccessNode(MethodDescriptor md, SymbolTable nametable,
@@ -4435,8 +4655,24 @@ public class LocationInference {
 
       nodeSet.addTupleSet(expNodeTupleSet);
     } else {
-      nodeSet.addTupleSet(expNodeTupleSet);
-      nodeSet.addTupleSet(idxNodeTupleSet);
+
+      NodeTupleSet nodeSetArrayAccessExp = new NodeTupleSet();
+
+      nodeSetArrayAccessExp.addTupleSet(expNodeTupleSet);
+      nodeSetArrayAccessExp.addTupleSet(idxNodeTupleSet);
+
+      if (needToGenerateInterLoc(nodeSetArrayAccessExp)) {
+        NTuple<Descriptor> interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
+
+        for (Iterator<NTuple<Descriptor>> iter = nodeSetArrayAccessExp.iterator(); iter.hasNext();) {
+          NTuple<Descriptor> higherTuple = iter.next();
+          addFlowGraphEdge(md, higherTuple, interTuple);
+        }
+        nodeSetArrayAccessExp.clear();
+        nodeSetArrayAccessExp.addTuple(interTuple);
+      }
+
+      nodeSet.addTupleSet(nodeSetArrayAccessExp);
     }
   }
 
@@ -4509,7 +4745,7 @@ public class LocationInference {
   private NTuple<Descriptor> analyzeFlowNameNode(MethodDescriptor md, SymbolTable nametable,
       NameNode nn, NodeTupleSet nodeSet, NTuple<Descriptor> base, NodeTupleSet implicitFlowTupleSet) {
 
-    // System.out.println("analyzeFlowNameNode=" + nn.printNode(0));
+    System.out.println("analyzeFlowNameNode=" + nn.printNode(0));
 
     if (base == null) {
       base = new NTuple<Descriptor>();
@@ -4545,6 +4781,7 @@ public class LocationInference {
           if (fd.isFinal()) {
             // if it is 'static final', no need to have flow node for the TOP
             // location
+            System.out.println("STATIC FINAL");
             return null;
           } else {
             // if 'static', assign the default GLOBAL LOCATION to the first
@@ -4702,7 +4939,7 @@ public class LocationInference {
 
       // creates edges from RHS to LHS
       NTuple<Descriptor> interTuple = null;
-      if (nodeSetRHS.size() > 1) {
+      if (needToGenerateInterLoc(nodeSetRHS)) {
         interTuple = getFlowGraph(md).createIntermediateNode().getDescTuple();
       }
 
@@ -4783,7 +5020,7 @@ public class LocationInference {
     String fileName = "lattice_";
     if (md != null) {
       fileName +=
-          cd.getSymbol().replaceAll("[\\W_]", "") + "_" + md.toString().replaceAll("[\\W_]", "");
+      /* cd.getSymbol().replaceAll("[\\W_]", "") + "_" + */md.toString().replaceAll("[\\W_]", "");
     } else {
       fileName += cd.getSymbol().replaceAll("[\\W_]", "");
     }
@@ -4866,7 +5103,7 @@ public class LocationInference {
     bw.write(locName + " [label=\"" + prettyStr + "\"]" + ";\n");
   }
 
-  public void _debug_printGraph() {
+  public void _debug_writeFlowGraph() {
     Set<MethodDescriptor> keySet = mapMethodDescriptorToFlowGraph.keySet();
 
     for (Iterator<MethodDescriptor> iterator = keySet.iterator(); iterator.hasNext();) {