private static String finegrainedFlowResults() {
    int totalReachableIfs = 0;
    int taintedReachableIfs = 0;

    int totalCountOfTaintSets = 0;
    int totalSizeOfTaintSets = 0;

    long totalValues = 0;

    Set<InfoValue> allSrcs = new HashSet<InfoValue>();
    Set<Set<InfoValue>> allSrcSets = new HashSet<Set<InfoValue>>();

    StringBuffer buf = new StringBuffer();

    for (MethodOrMethodContext momc : PTABridge.v().getReachableMethodContexts()) {
      // reset counted locals for each method
      Set<Value> countedLocals = new HashSet<Value>();

      SootMethod method = momc.method();

      if (!method.isConcrete()) continue;
      try {
        Body body = method.retrieveActiveBody();

        Iterator<Unit> unitIt = body.getUnits().snapshotIterator();

        while (unitIt.hasNext()) {
          Stmt stmt = (Stmt) unitIt.next();

          for (ValueBox vb : stmt.getUseAndDefBoxes()) {
            Value v = vb.getValue();

            if (countedLocals.contains(v)) continue;

            countedLocals.add(v);

            Set<InfoValue> taints = getTaintSet(v, momc);

            if (taints != null) totalValues++;

            if (taints != null && !taints.isEmpty()) {
              allSrcs.addAll(taints);

              totalCountOfTaintSets++;
              totalSizeOfTaintSets += taints.size();

              if (!allSrcSets.contains(taints)) allSrcSets.add(taints);

              countedLocals.add(v);
            }
          }

          if (stmt instanceof IfStmt) {
            totalReachableIfs++;
            boolean hasTainted = false;

            for (ValueBox vb : stmt.getUseBoxes()) {
              Value v = vb.getValue();

              Set<InfoValue> taints = getTaintSet(v, momc);

              if (taints != null && !taints.isEmpty()) {
                hasTainted = true;
                break;
              }
            }

            totalReachableIfs++;

            if (hasTainted) {
              taintedReachableIfs++;
            }
          }
        }

      } catch (Exception e) {
        // ignore and continue
      }
    }

    buf.append("Tainted Reachable if statements: " + taintedReachableIfs + "\n");
    buf.append("Total Reachable if Statements: " + totalReachableIfs + "\n");
    buf.append(
        "Count of non-zero taint sets for primitives and strings: " + totalCountOfTaintSets + "\n");
    buf.append(
        "Total distinct reachable primitives or string values in code: " + totalValues + "\n");
    buf.append(
        "Total size of non-zero taint sets for primitives and strings: "
            + totalSizeOfTaintSets
            + "\n");
    buf.append("Count of distinct sources: " + allSrcs.size() + "\n");
    buf.append("Total distinct source sets: " + allSrcSets.size() + "\n");

    return buf.toString();
  }
  private static boolean internalAggregate(
      StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) {
    LocalUses localUses;
    LocalDefs localDefs;
    ExceptionalUnitGraph graph;
    boolean hadAggregation = false;
    Chain<Unit> units = body.getUnits();

    graph = new ExceptionalUnitGraph(body);
    localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph));
    localUses = new SimpleLocalUses(graph, localDefs);

    List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false);
    for (Unit u : unitList) {
      if (!(u instanceof AssignStmt)) continue;
      AssignStmt s = (AssignStmt) u;

      Value lhs = s.getLeftOp();
      if (!(lhs instanceof Local)) continue;
      Local lhsLocal = (Local) lhs;

      if (onlyStackVars && !lhsLocal.getName().startsWith("$")) continue;

      List<UnitValueBoxPair> lu = localUses.getUsesOf(s);
      if (lu.size() != 1) continue;

      UnitValueBoxPair usepair = lu.get(0);
      Unit use = usepair.unit;
      ValueBox useBox = usepair.valueBox;

      List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use);
      if (ld.size() != 1) continue;

      // Check to make sure aggregation pair in the same zone
      if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) {
        continue;
      }

      /* we need to check the path between def and use */
      /* to see if there are any intervening re-defs of RHS */
      /* in fact, we should check that this path is unique. */
      /* if the RHS uses only locals, then we know what
      to do; if RHS has a method invocation f(a, b,
      c) or field access, we must ban field writes, other method
      calls and (as usual) writes to a, b, c. */

      boolean cantAggr = false;
      boolean propagatingInvokeExpr = false;
      boolean propagatingFieldRef = false;
      boolean propagatingArrayRef = false;
      ArrayList<FieldRef> fieldRefList = new ArrayList<FieldRef>();

      LinkedList<Value> localsUsed = new LinkedList<Value>();
      for (ValueBox vb : s.getUseBoxes()) {
        Value v = vb.getValue();
        if (v instanceof Local) localsUsed.add(v);
        else if (v instanceof InvokeExpr) propagatingInvokeExpr = true;
        else if (v instanceof ArrayRef) propagatingArrayRef = true;
        else if (v instanceof FieldRef) {
          propagatingFieldRef = true;
          fieldRefList.add((FieldRef) v);
        }
      }

      // look for a path from s to use in graph.
      // only look in an extended basic block, though.

      List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use);

      if (path == null) continue;

      Iterator<Unit> pathIt = path.iterator();

      // skip s.
      if (pathIt.hasNext()) pathIt.next();

      while (pathIt.hasNext() && !cantAggr) {
        Stmt between = (Stmt) (pathIt.next());

        if (between != use) {
          // Check for killing definitions

          for (ValueBox vb : between.getDefBoxes()) {
            Value v = vb.getValue();
            if (localsUsed.contains(v)) {
              cantAggr = true;
              break;
            }

            if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
              if (v instanceof FieldRef) {
                if (propagatingInvokeExpr) {
                  cantAggr = true;
                  break;
                } else if (propagatingFieldRef) {
                  // Can't aggregate a field access if passing a definition of a field
                  // with the same name, because they might be aliased
                  for (FieldRef fieldRef : fieldRefList) {
                    if (((FieldRef) v).getField() == fieldRef.getField()) {
                      cantAggr = true;
                      break;
                    }
                  }
                }
              } else if (v instanceof ArrayRef) {
                if (propagatingInvokeExpr) {
                  // Cannot aggregate an invoke expr past an array write
                  cantAggr = true;
                  break;
                } else if (propagatingArrayRef) {
                  // cannot aggregate an array read past a write
                  // this is somewhat conservative
                  // (if types differ they may not be aliased)

                  cantAggr = true;
                  break;
                }
              }
            }
          }

          // Make sure not propagating past a {enter,exit}Monitor
          if (propagatingInvokeExpr && between instanceof MonitorStmt) cantAggr = true;
        }

        // Check for intervening side effects due to method calls
        if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
          for (final ValueBox box : between.getUseBoxes()) {
            if (between == use && box == useBox) {
              // Reached use point, stop looking for
              // side effects
              break;
            }

            Value v = box.getValue();

            if (v instanceof InvokeExpr
                || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) {
              cantAggr = true;
              break;
            }
          }
        }
      }

      // we give up: can't aggregate.
      if (cantAggr) {
        continue;
      }
      /* assuming that the d-u chains are correct, */
      /* we need not check the actual contents of ld */

      Value aggregatee = s.getRightOp();

      if (usepair.valueBox.canContainValue(aggregatee)) {
        boolean wasSimpleCopy = isSimpleCopy(usepair.unit);
        usepair.valueBox.setValue(aggregatee);
        units.remove(s);
        hadAggregation = true;
        // clean up the tags. If s was not a simple copy, the new statement should get
        // the tags of s.
        // OK, this fix was wrong. The condition should not be
        // "If s was not a simple copy", but rather "If usepair.unit
        // was a simple copy". This way, when there's a load of a constant
        // followed by an invoke, the invoke gets the tags.
        if (wasSimpleCopy) {
          // usepair.unit.removeAllTags();
          usepair.unit.addAllTagsOf(s);
        }
      } else {
        /*
        if(Options.v().verbose())
        {
            G.v().out.println("[debug] failed aggregation");
              G.v().out.println("[debug] tried to put "+aggregatee+
                             " into "+usepair.stmt +
                             ": in particular, "+usepair.valueBox);
              G.v().out.println("[debug] aggregatee instanceof Expr: "
                             +(aggregatee instanceof Expr));
        }*/
      }
    }
    return hadAggregation;
  }