docs: public void execute() throws DataflowAnalysisException {
          boolean change;
          boolean debugWas = DEBUG;
          if (DEBUG) {
              reportAnalysis("Executing");
          }
  
          int timestamp = 0;
          boolean firstTime = true;
          do {
              change = false;
              boolean sawBackEdge = false;
              ++numIterations;
              if (numIterations > MAX_ITERS && !DEBUG) {
                  DEBUG = true;
                  reportAnalysis("Too many iterations");
                  System.out.println(this.getClass().getName());
                  if (this.getClass() == UnconditionalValueDerefDataflow.class || this.getClass() == LiveLocalStoreDataflow.class) {
                      try {
                          ClassContext cc = Global.getAnalysisCache().getClassAnalysis(ClassContext.class,
                                  DescriptorFactory.createClassDescriptorFromDottedClassName(cfg.getMethodGen().getClassName()));
                          System.out.println("Forwards cfg");
                          CFGPrinter printer = new CFGPrinter(cfg);
                          printer.setIsForwards(true);
                          printer.print(System.out);
                          System.out.println("Backwards cfg");
                          printer = new CFGPrinter(cfg);
                          printer.setIsForwards(false);
                          printer.print(System.out);
                          cc.dumpSimpleDataflowInformation(cfg.getMethodGen().getMethod());
                      } catch (CheckedAnalysisException e) {
                          e.printStackTrace(System.out);
                      }
                  }
              }
  
              if (DEBUG) {
                  System.out.println("----------------------------------------------------------------------");
                  System.out.println(this.getClass().getName() + " iteration: " + numIterations + ", timestamp: " + timestamp);
                  MethodGen mg = cfg.getMethodGen();
                  System.out.println(mg.getClassName() + "." + mg.getName() + mg.getSignature());
                  System.out.println("----------------------------------------------------------------------");
  
              }
  
              if (numIterations >= MAX_ITERS + 9) {
                  throw new DataflowAnalysisException("Too many iterations (" + numIterations + ") in dataflow when analyzing "
                          + getFullyQualifiedMethodName());
              }
  
              analysis.startIteration();
  
              if (DEBUG && firstTime && blockOrder instanceof ReverseDFSOrder) {
                  ReverseDFSOrder rBlockOrder = (ReverseDFSOrder) blockOrder;
                  System.out.println("Entry point is: " + logicalEntryBlock());
                  System.out.println("Basic block order: ");
                  Iterator<BasicBlock> i = blockOrder.blockIterator();
                  while (i.hasNext()) {
  
                      BasicBlock block = i.next();
                      debug(block, "rBlockOrder " + rBlockOrder.rdfs.getDiscoveryTime(block) + "\n");
                  }
              }
              Iterator<BasicBlock> i = blockOrder.blockIterator();
              if (numIterations > 3 && numIterations % 2 == 0 && blockOrder instanceof ReverseDFSOrder) {
                  if (DEBUG) {
                      System.out.println("Trying program order");
                  }
                  TreeSet<BasicBlock> bb = new TreeSet<>(new BackwardProgramOrder());
                  Iterator<BasicBlock> j = blockOrder.blockIterator();
                  while (j.hasNext()) {
                      BasicBlock block = j.next();
                      bb.add(block);
                  }
                  if (DEBUG) {
                      for (BasicBlock block : bb) {
                          debug(block, "\n");
                      }
                  }
                  i = bb.iterator();
              }
              if (DEBUG) {
                  dumpDataflow(analysis);
              }
  
              // For each block in CFG...
  
              while (i.hasNext()) {
  
                  BasicBlock block = i.next();
  
                  // Get start fact for block.
                  Fact start = analysis.getStartFact(block);
                  assert start != null;
  
                  boolean needToRecompute = false;
                  // Get result facts for block,
                  Fact result = analysis.getResultFact(block);
                  assert result != null;
  
                  int originalResultTimestamp = analysis.getLastUpdateTimestamp(result);
  
                  // Meet all of the logical predecessor results into this block's
                  // start.
                  // Special case: if the block is the logical entry, then it gets
                  // the special "entry fact".
                  if (block == logicalEntryBlock()) {
                      analysis.makeFactTop(start);
                      analysis.initEntryFact(start);
                      if (DEBUG) {
                          debug(block, "Init entry fact ==> " + analysis.factToString(start) + "\n");
                      }
                      needToRecompute = true;
                  } else {
                      int lastCalculated = analysis.getLastUpdateTimestamp(start);
                      Iterator<Edge> predEdgeIter = logicalPredecessorEdgeIterator(block);
  
                      int predCount = 0;
                      int rawPredCount = 0;
                      while (predEdgeIter.hasNext()) {
                          Edge edge = predEdgeIter.next();
                          rawPredCount++;
                          if (needToRecompute) {
                              // don't need to check to see if we need to recompute.
                              if (firstTime && !sawBackEdge) {
                                  // may need to se sawBackEdge
                              } else {
                                  continue;
                              }
  
                          }
                          BasicBlock logicalPred = isForwards ? edge.getSource() : edge.getTarget();
  
                          int direction = blockOrder.compare(block, logicalPred);
  
                          if (DEBUG) {
                              debug(block, "direction " + direction + " for " + blockId(logicalPred) + "\n");
                          }
                          if (direction < 0) {
                              sawBackEdge = true;
                          }
  
                          // Get the predecessor result fact
                          Fact predFact = analysis.getResultFact(logicalPred);
                          int predLastUpdated = analysis.getLastUpdateTimestamp(predFact);
                          if (!analysis.isTop(predFact)) {
                              predCount++;
                              if (predLastUpdated >= lastCalculated) {
  
                                  needToRecompute = true;
                                  if (DEBUG) {
                                      debug(block, "\n Need to recompute. My timestamp = " + lastCalculated + ", pred timestamp = "
                                              + predLastUpdated + ",\n   pred fact = " + predFact + "\n");
                                  }
                                  // break;
                              }
                          }
                      }
                      if (predCount == 0) {
                          needToRecompute = true;
                      }
  
                      if (!needToRecompute) {
                          continue;
                      }
  
                      analysis.makeFactTop(start);
                      predEdgeIter = logicalPredecessorEdgeIterator(block);
                      while (predEdgeIter.hasNext()) {
                          Edge edge = predEdgeIter.next();
                          BasicBlock logicalPred = isForwards ? edge.getSource() : edge.getTarget();
  
                          // Get the predecessor result fact
                          Fact predFact = analysis.getResultFact(logicalPred);
  
                          // Apply the edge transfer function.
                          Fact edgeFact = analysis.createFact();
                          analysis.copy(predFact, edgeFact);
                          analysis.edgeTransfer(edge, edgeFact);
  
                          if (DEBUG && !analysis.same(edgeFact, predFact)) {
                              debug(block, logicalPred, edge, "Edge transfer " + analysis.factToString(predFact) + " ==> "
                                      + analysis.factToString(edgeFact));
                          }
  
                          // Merge the predecessor fact (possibly transformed
                          // by the edge transfer function)
                          // into the block's start fact.
                          if (DEBUG) {
                              if (analysis.isTop(start)) {
                                  debug(block, logicalPred, edge, "\n  First pred is " + analysis.factToString(edgeFact)
                                          + "\n   last updated at " + analysis.getLastUpdateTimestamp(predFact) + "\n");
                              } else {
                                  debug(block, logicalPred, edge, "\n  Meet " + analysis.factToString(start) + "\n   with "
                                          + analysis.factToString(edgeFact)
  
                                          + "\n   pred last updated at " + analysis.getLastUpdateTimestamp(predFact) + "\n");
                              }
                          }
  
                          if (analysis instanceof UnconditionalValueDerefAnalysis) {
                              ((UnconditionalValueDerefAnalysis) analysis).meetInto((UnconditionalValueDerefSet) edgeFact,
                                      edge, (UnconditionalValueDerefSet) start, rawPredCount == 1);
                          } else {
                              analysis.meetInto(edgeFact, edge, start);
                          }
                          analysis.setLastUpdateTimestamp(start, timestamp);
  
                          int pos = -1;
                          if (block.getFirstInstruction() != null) {
                              pos = block.getFirstInstruction().getPosition();
                          }
                          if (DEBUG) {
                              System.out.println(" [" + pos + "]==> " + analysis.factToString(start) + " @ " + timestamp
                                      + " \n");
                          }
                      }
                  }
                  if (DEBUG) {
                      debug(block, "start fact is " + analysis.factToString(start) + "\n");
                  }
  
                  // making a copy of result facts (so we can detect if it
                  // changed).
                  boolean resultWasTop = analysis.isTop(result);
                  Fact origResult = null;
                  if (!resultWasTop) {
                      origResult = analysis.createFact();
                      analysis.copy(result, origResult);
                  }
  
                  //                if (true || analysis.isTop(start)) {
                  // Apply the transfer function.
  
                  analysis.transfer(block, null, start, result);
                  //                } else {
                  //                    analysis.copy(start, result);
                  //                }
  
                  if (DEBUG && SystemProperties.getBoolean("dataflow.blockdebug")) {
                      debug(block, "Dumping flow values for block:\n");
                      Iterator<InstructionHandle> ii = block.instructionIterator();
                      while (ii.hasNext()) {
                          InstructionHandle handle = ii.next();
                          Fact tmpResult = analysis.createFact();
                          analysis.transfer(block, handle, start, tmpResult);
                          System.out.println("\t" + handle + " " + analysis.factToString(tmpResult));
                      }
                  }
  
                  // See if the result changed.
                  if (DEBUG) {
                      debug(block, "orig result is " + (origResult == null ? "TOP" : analysis.factToString(origResult)) + "\n");
                  }
                  boolean thisResultChanged = false;
                  if (resultWasTop) {
                      thisResultChanged = !analysis.isTop(result);
                  } else {
                      thisResultChanged = !analysis.same(result, origResult);
                  }
                  if (thisResultChanged) {
                      timestamp++;
                      if (DEBUG) {
                          debug(block, "result changed at timestamp " + timestamp + "\n");
                      }
                      if (DEBUG && !needToRecompute) {
                          System.out.println("I thought I didn't need to recompute");
                      }
                      change = true;
                      analysis.setLastUpdateTimestamp(result, timestamp);
                  } else {
                      analysis.setLastUpdateTimestamp(result, originalResultTimestamp);
                  }
  
                  if (DEBUG) {
                      debug(block,
                              "result is " + analysis.factToString(result) + " @ timestamp "
                                      + analysis.getLastUpdateTimestamp(result) + "\n");
                  }
              }
  
              analysis.finishIteration();
              if (!sawBackEdge) {
                  break;
              }
  
          } while (change);
  
          if (DEBUG) {
              System.out.println("-- Quiescence achieved-------------------------------------------------");
              System.out.println(this.getClass().getName() + " iteration: " + numIterations + ", timestamp: " + timestamp);
              MethodGen mg = cfg.getMethodGen();
              System.out.println(mg.getClassName() + "." + mg.getName() + mg.getSignature());
              new RuntimeException("Quiescence achieved----------------------------------------------------------------")
              .printStackTrace(System.out);
  
          }
          DEBUG = debugWas;
      }