bug fixes + generating PC/RETURNLOC in a flow graph
[IRC.git] / Robust / src / Analysis / SSJava / LocationInference.java
index e2c808c734eb40b14a775c9cae21f9ac4013acfb..f90d87d9ddfa8ec0088f44f1d0df2be25c990183 100644 (file)
@@ -124,21 +124,25 @@ public class LocationInference {
 
   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 String RLOC = "_RLOC_";
 
   public static final Descriptor GLOBALDESC = new NameDescriptor(GLOBALLOC);
 
   public static final Descriptor TOPDESC = new NameDescriptor(TOPLOC);
 
+  public static final Descriptor RETURNLOC = new NameDescriptor(RLOC);
+
+  public static final Descriptor LITERALDESC = new NameDescriptor("LITERAL");
+
   public static String newline = System.getProperty("line.separator");
 
   LocationInfo curMethodInfo;
 
   boolean debug = true;
 
-  private static int locSeed = 0;
+  public static int locSeed = 0;
 
   public LocationInference(SSJavaAnalysis ssjava, State state) {
     this.ssjava = ssjava;
@@ -221,18 +225,24 @@ public class LocationInference {
 
   public void inference() {
 
+    ssjava.init();
+
     // construct value flow graph
     constructFlowGraph();
 
     assignCompositeLocation();
 
+    // calculate RETURNLOC,PCLOC
+    calculateExtraLocations();
+
+    _debug_writeFlowGraph();
+
+    // System.exit(0);
+
     constructHierarchyGraph();
 
     debug_writeHierarchyDotFiles();
 
-    // calculate RETURNLOC,PCLOC
-    calculateExtraLocations();
-
     simplifyHierarchyGraph();
 
     debug_writeSimpleHierarchyDotFiles();
@@ -257,17 +267,6 @@ public class LocationInference {
 
     System.exit(0);
 
-    // 2) construct lattices
-    // inferLattices();
-    // simplifyLattices();
-    // 3) check properties
-    // checkLattices();
-
-    debug_writeLatticeDotFile();
-
-    // 4) generate annotated source codes
-    generateAnnoatedCode();
-
   }
 
   public Map<NTuple<Descriptor>, NTuple<Descriptor>> getMapCallerArgToCalleeParam(
@@ -292,9 +291,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() {
@@ -304,6 +303,9 @@ public class LocationInference {
 
     while (!methodDescList.isEmpty()) {
       MethodDescriptor md = methodDescList.removeLast();
+
+      System.out.println("\n#updateCompositeLocationAssignments=" + md);
+
       FlowGraph flowGraph = getFlowGraph(md);
 
       MethodSummary methodSummary = getMethodSummary(md);
@@ -311,23 +313,36 @@ public class LocationInference {
       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);
-          methodSummary.addMapVarNameToInferCompLoc(localVarDesc, node.getCompositeLocation());
+          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()));
+      }
+
     }
 
   }
@@ -338,10 +353,17 @@ public class LocationInference {
       Location loc = compLoc.get(i);
       String nodeIdentifier = loc.getLocIdentifier();
       Descriptor enclosingDesc = loc.getDescriptor();
-      System.out.println("enclosingDesc=" + enclosingDesc);
       String locName;
       if (!enclosingDesc.equals(GLOBALDESC)) {
         LocationSummary locSummary = getLocationSummary(enclosingDesc);
+        HierarchyGraph hierarchyGraph = getSimpleHierarchyGraph(enclosingDesc);
+        if (hierarchyGraph != null) {
+
+          HNode curNode = hierarchyGraph.getCurrentHNode(nodeIdentifier);
+          if (curNode != null) {
+            nodeIdentifier = curNode.getName();
+          }
+        }
         locName = locSummary.getLocationName(nodeIdentifier);
       } else {
         locName = nodeIdentifier;
@@ -355,15 +377,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();
@@ -380,12 +399,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());
     }
 
@@ -403,7 +417,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);
@@ -453,8 +468,10 @@ 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);
@@ -464,32 +481,45 @@ public class LocationInference {
       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();) {
@@ -513,7 +543,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();
@@ -684,8 +714,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);
@@ -721,6 +749,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>>();
@@ -753,6 +799,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();
@@ -858,12 +918,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();) {
@@ -875,13 +934,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);
@@ -960,13 +1017,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);
 
@@ -974,12 +1026,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);
 
@@ -996,6 +1046,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>();
@@ -1206,10 +1269,21 @@ 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();
@@ -1543,7 +1617,6 @@ public class LocationInference {
 
     // do fixed-point analysis
 
-    ssjava.init();
     LinkedList<MethodDescriptor> descriptorListToAnalyze = ssjava.getSortedDescriptors();
 
     // Collections.sort(descriptorListToAnalyze, new
@@ -1604,6 +1677,18 @@ 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);
+        }
+      }
+    }
+
   }
 
   private HierarchyGraph getHierarchyGraph(Descriptor d) {
@@ -1627,9 +1712,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();
@@ -1680,6 +1772,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) {
@@ -1814,22 +1923,24 @@ public class LocationInference {
     rtr += "\")";
 
     if (desc instanceof MethodDescriptor) {
-      TypeDescriptor returnType = ((MethodDescriptor) desc).getReturnType();
+      System.out.println("#EXTRA LOC DECLARATION GEN=" + desc);
 
       MethodSummary methodSummary = getMethodSummary((MethodDescriptor) desc);
 
-      if (returnType != null && (!returnType.isVoid())) {
-        rtr +=
-            "\n@RETURNLOC(\"" + generateLocationAnnoatation(methodSummary.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 = methodSummary.getPCLoc();
-      if ((pcLoc != null) && (!pcLoc.get(0).isTop())) {
-        rtr += "\n@PCLOC(\"" + generateLocationAnnoatation(pcLoc) + "\")";
-      }
+      rtr += "\n@THISLOC(\"" + methodSummary.getThisLocName() + "\")";
+      rtr += "\n@GLOBALLOC(\"" + methodSummary.getGlobalLocName() + "\")";
 
     }
 
@@ -1846,7 +1957,6 @@ public class LocationInference {
 
       setupToAnalazeMethod(cd);
 
-      LocationInfo locInfo = mapClassToLocationInfo.get(cd);
       String sourceFileName = cd.getSourceFileName();
 
       if (cd.isInterface()) {
@@ -1856,26 +1966,13 @@ 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
-      LocationSummary fieldLocSummary = getLocationSummary(cd);
       // Map<Descriptor, CompositeLocation> inferLocMap = fieldLocInfo.getMapDescToInferLocation();
       Map<String, String> mapFieldNameToLocName = fieldLocSummary.getMapHNodeNameToLocationName();
 
@@ -1957,7 +2054,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 =
@@ -1972,9 +2070,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);
@@ -2146,17 +2244,16 @@ public class LocationInference {
 
   }
 
-  private void inferLattices() {
-  }
-
   private void calculateExtraLocations() {
-    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();
       if (!ssjava.getMethodContainingSSJavaLoop().equals(md)) {
         calculateExtraLocations(md);
       }
     }
+
   }
 
   private void checkLatticesOfVirtualMethods(MethodDescriptor md) {
@@ -2252,7 +2349,7 @@ public class LocationInference {
     return desc;
   }
 
-  private void calcualtePCLOC(MethodDescriptor md) {
+  private void calculatePCLOC(MethodDescriptor md) {
 
     System.out.println("#calcualtePCLOC");
     MethodSummary methodSummary = getMethodSummary(md);
@@ -2263,49 +2360,49 @@ public class LocationInference {
     // PC location is higher than location types of parameters which has incoming flows.
 
     Set<NTuple<Location>> paramLocTupleHavingInFlowSet = new HashSet<NTuple<Location>>();
+    Set<Descriptor> paramDescNOTHavingInFlowSet = new HashSet<Descriptor>();
+    // Set<FlowNode> paramNodeNOThavingInFlowSet = new HashSet<FlowNode>();
 
     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);
 
       if (fg.getIncomingNodeSetByPrefix(prefix).size() > 0) {
         // parameter has in-value flows
-        NTuple<Descriptor> paramDescTuple = paramFlowNode.getCurrentDescTuple();
-        NTuple<Location> paramLocTuple = translateToLocTuple(md, paramDescTuple);
         paramLocTupleHavingInFlowSet.add(paramLocTuple);
+      } else {
+        // paramNodeNOThavingInFlowSet.add(fg.getFlowNode(paramDescTuple));
+        paramDescNOTHavingInFlowSet.add(prefix);
       }
     }
 
-    System.out.println("paramLocTupleHavingInFlowSet=" + paramLocTupleHavingInFlowSet);
+    System.out.println("paramNodeNOThavingInFlowSet=" + paramDescNOTHavingInFlowSet);
 
-    if (!coversAllParamters(md, fg, paramLocTupleHavingInFlowSet)) {
-      // if (numParamsWithIncomingValue > 0 && numParamsWithIncomingValue != fg.getNumParameters())
-      // {
+    if (paramLocTupleHavingInFlowSet.size() > 0
+        && !coversAllParamters(md, fg, paramLocTupleHavingInFlowSet)) {
 
       // Here, generates a location in the method lattice that is higher than the
       // paramLocTupleHavingInFlowSet
       NTuple<Location> pcLocTuple =
           generateLocTupleRelativeTo(md, paramLocTupleHavingInFlowSet, PCLOC);
 
-      int pcLocTupleIdx = pcLocTuple.size() - 1;
-      Location pcLoc = pcLocTuple.get(pcLocTupleIdx);
-      Descriptor pcDesc = pcLoc.getLocDescriptor();
-      Descriptor enclosingDesc = pcLocTuple.get(pcLocTupleIdx).getDescriptor();
+      NTuple<Descriptor> pcDescTuple = translateToDescTuple(pcLocTuple);
+
+      // add ordering relations s.t. PCLOC is higher than all flow nodes except the set of
+      // parameters that do not have incoming flows
 
-      HierarchyGraph hierarchyGraph = getHierarchyGraph(enclosingDesc);
-      HNode pcNode = hierarchyGraph.getHNode(pcDesc);
-      pcNode.setSkeleton(true);
+      for (Iterator iterator = fg.getNodeSet().iterator(); iterator.hasNext();) {
+        FlowNode node = (FlowNode) iterator.next();
 
-      for (Iterator iterator = paramLocTupleHavingInFlowSet.iterator(); iterator.hasNext();) {
-        NTuple<Location> paramLocTuple = (NTuple<Location>) iterator.next();
-        if (paramLocTuple.size() > pcLocTupleIdx) {
-          Descriptor lowerDesc = paramLocTuple.get(pcLocTupleIdx).getLocDescriptor();
-          hierarchyGraph.addEdge(pcDesc, lowerDesc);
+        if (!paramDescNOTHavingInFlowSet.contains(node.getCurrentDescTuple().get(0))) {
+          fg.addValueFlowEdge(pcDescTuple, node.getDescTuple());
         }
       }
 
-      System.out.println("pcLoc=" + pcLoc);
+      System.out.println("pcLoc=" + pcLocTuple);
 
       methodSummary.setPCLoc(new CompositeLocation(pcLocTuple));
     }
@@ -2351,14 +2448,11 @@ public class LocationInference {
 
   private void calculateRETURNLOC(MethodDescriptor md) {
 
-    System.out.println("#calculateRETURNLOC");
+    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();
 
@@ -2366,53 +2460,42 @@ public class LocationInference {
       // first, generate the set of return value location types that starts
       // with 'this' reference
 
-      Set<NTuple<Location>> inferFieldReturnLocSet = new HashSet<NTuple<Location>>();
-
       Set<FlowNode> paramFlowNodeFlowingToReturnValueSet = getParamNodeFlowingToReturnValue(md);
       System.out.println("paramFlowNodeFlowingToReturnValueSet="
           + paramFlowNodeFlowingToReturnValueSet);
 
-      Set<NTuple<Location>> locFlowingToReturnValueSet = new HashSet<NTuple<Location>>();
+      Set<NTuple<Location>> tupleToBeHigherThanReturnLocSet = new HashSet<NTuple<Location>>();
       for (Iterator iterator = paramFlowNodeFlowingToReturnValueSet.iterator(); iterator.hasNext();) {
         FlowNode fn = (FlowNode) iterator.next();
-
         NTuple<Descriptor> paramDescTuple = fn.getCurrentDescTuple();
-        NTuple<Location> paramLocTuple = translateToLocTuple(md, paramDescTuple);
-
-        locFlowingToReturnValueSet.add(paramLocTuple);
+        tupleToBeHigherThanReturnLocSet.add(translateToLocTuple(md, paramDescTuple));
       }
 
       Set<FlowNode> returnNodeSet = fg.getReturnNodeSet();
       for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
         FlowNode returnNode = (FlowNode) iterator.next();
         NTuple<Descriptor> returnDescTuple = returnNode.getCurrentDescTuple();
-        NTuple<Location> returnLocTuple = translateToLocTuple(md, returnDescTuple);
-        locFlowingToReturnValueSet.add(returnLocTuple);
+        tupleToBeHigherThanReturnLocSet.add(translateToLocTuple(md, returnDescTuple));
       }
-      System.out.println("locFlowingToReturnValueSet=" + locFlowingToReturnValueSet);
+      System.out.println("-flow graph's returnNodeSet=" + returnNodeSet);
+      System.out.println("tupleSetToBeHigherThanReturnLoc=" + tupleToBeHigherThanReturnLocSet);
 
       // Here, generates a return location in the method lattice that is lower than the
       // locFlowingToReturnValueSet
       NTuple<Location> returnLocTuple =
-          generateLocTupleRelativeTo(md, locFlowingToReturnValueSet, RLOC);
+          generateLocTupleRelativeTo(md, tupleToBeHigherThanReturnLocSet, RLOC);
 
       System.out.println("returnLocTuple=" + returnLocTuple);
 
-      int returnLocTupleIdx = returnLocTuple.size() - 1;
-      Location returnLoc = returnLocTuple.get(returnLocTupleIdx);
-      Descriptor returnDesc = returnLoc.getLocDescriptor();
-      Descriptor enclosingDesc = returnLocTuple.get(returnLocTupleIdx).getDescriptor();
-
-      HierarchyGraph hierarchyGraph = getHierarchyGraph(enclosingDesc);
-      HNode returnNode = hierarchyGraph.getHNode(returnDesc);
-      returnNode.setSkeleton(true);
-
-      for (Iterator iterator = locFlowingToReturnValueSet.iterator(); iterator.hasNext();) {
-        NTuple<Location> locTuple = (NTuple<Location>) iterator.next();
-        Descriptor higherDesc = locTuple.get(returnLocTupleIdx).getLocDescriptor();
-        hierarchyGraph.addEdge(higherDesc, returnDesc);
+      NTuple<Descriptor> returnDescTuple = translateToDescTuple(returnLocTuple);
+      for (Iterator iterator = tupleToBeHigherThanReturnLocSet.iterator(); iterator.hasNext();) {
+        NTuple<Location> higherTuple = (NTuple<Location>) iterator.next();
+        fg.addValueFlowEdge(translateToDescTuple(higherTuple), returnDescTuple);
       }
 
+      fg.getFlowNode(returnDescTuple).setSkeleton(true);
+      System.out.println("fg node set=" + fg.getNodeSet());
+
       methodSummary.setRETURNLoc(new CompositeLocation(returnLocTuple));
 
       // skip: for (Iterator iterator = returnNodeSet.iterator(); iterator.hasNext();) {
@@ -2489,7 +2572,7 @@ public class LocationInference {
 
     System.out.println("\nSSJAVA:Calculate PCLOC/RETURNLOC locations: " + md);
 
-    calcualtePCLOC(md);
+    calculatePCLOC(md);
     calculateRETURNLOC(md);
 
   }
@@ -2888,8 +2971,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
@@ -2913,19 +2994,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);
 
           }
 
@@ -2933,7 +3014,7 @@ public class LocationInference {
         }
       }
     }
-    System.out.println("##\n");
+    // System.out.println("##\n");
 
   }
 
@@ -3155,6 +3236,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();
@@ -3329,13 +3413,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;
       }
 
     }
@@ -3659,17 +3743,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);
 
       }
@@ -3904,7 +3988,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();
@@ -3931,6 +4015,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) {
@@ -3968,22 +4053,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) {
 
@@ -3998,7 +4115,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();
@@ -4053,24 +4170,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);
@@ -4087,7 +4222,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,
@@ -4098,11 +4233,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();
@@ -4140,7 +4275,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();
       }
 
@@ -4218,7 +4353,7 @@ public class LocationInference {
       break;
 
     case Kind.LiteralNode:
-      analyzeLiteralNode(md, nametable, (LiteralNode) en);
+      analyzeFlowLiteralNode(md, nametable, (LiteralNode) en, nodeSet);
       break;
 
     case Kind.MethodInvokeNode:
@@ -4336,7 +4471,7 @@ public class LocationInference {
       FlowGraph calleeFlowGraph = getFlowGraph(calleeMethodDesc);
       Set<FlowNode> calleeReturnSet = calleeFlowGraph.getReturnNodeSet();
 
-      System.out.println("-calleeReturnSet=" + calleeReturnSet);
+      // System.out.println("-calleeReturnSet=" + calleeReturnSet);
 
       if (min.getExpression() != null) {
 
@@ -4363,7 +4498,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())) {
@@ -4395,8 +4530,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();) {
@@ -4413,9 +4547,6 @@ public class LocationInference {
           addArgIdxMap(min, idx, argTuple);
 
           FlowNode paramNode = calleeFlowGraph.getParamFlowNode(idx);
-          System.out.println("-paramNode=" + paramNode + " hasInFlowTo="
-              + hasInFlowTo(calleeFlowGraph, paramNode, calleeReturnSet));
-
           if (hasInFlowTo(calleeFlowGraph, paramNode, calleeReturnSet)
               || calleeMethodDesc.getModifiers().isNative()) {
             addParamNodeFlowingToReturnValue(calleeMethodDesc, paramNode);
@@ -4464,8 +4595,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,
@@ -4564,7 +4698,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>();
@@ -4600,6 +4734,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
@@ -4757,7 +4892,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();
       }
 
@@ -4838,7 +4973,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_]", "");
     }
@@ -4921,7 +5056,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();) {