private static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>>
      Result<A, S, T> methodDataflow(TreePath methodPath, Context context, T transfer) {
    final ProcessingEnvironment env = JavacProcessingEnvironment.instance(context);

    final ControlFlowGraph cfg;
    try {
      cfg = cfgCache.getUnchecked(CfgParams.create(methodPath, env));
    } catch (UncheckedExecutionException e) {
      throw e.getCause() instanceof CompletionFailure ? (CompletionFailure) e.getCause() : e;
    }
    final AnalysisParams aparams = AnalysisParams.create(transfer, cfg, env);
    @SuppressWarnings("unchecked")
    final Analysis<A, S, T> analysis = (Analysis<A, S, T>) analysisCache.getUnchecked(aparams);

    return new Result<A, S, T>() {
      @Override
      public Analysis<A, S, T> getAnalysis() {
        return analysis;
      }

      @Override
      public ControlFlowGraph getControlFlowGraph() {
        return cfg;
      }
    };
  }
private static < A extends AbstractValue < A > , S extends Store < S > , T extends TransferFunction < A , S > > Result < A , S , T > methodDataflow ( TreePath methodPath , Context context , T transfer ) { final ProcessingEnvironment env = JavacProcessingEnvironment . instance ( context ) ; final ControlFlowGraph cfg ; try { cfg = cfgCache . getUnchecked ( CfgParams . create ( methodPath , env ) ) ; } catch ( UncheckedExecutionException e ) { throw e . getCause ( ) instanceof CompletionFailure ? ( CompletionFailure ) e . getCause ( ) : e ; } final AnalysisParams aparams = AnalysisParams . create ( transfer , cfg , env ) ; @ SuppressWarnings ( "unchecked" ) final Analysis < A , S , T > analysis = ( Analysis < A , S , T > ) analysisCache . getUnchecked ( aparams ) ; return new Result < A , S , T > ( ) { @ Override public Analysis < A , S , T > getAnalysis ( ) { return analysis ; } @ Override public ControlFlowGraph getControlFlowGraph ( ) { return cfg ; } } ; }
Run the {@code transfer} dataflow analysis over the method or lambda which is the leaf of the
{@code methodPath}.

<p>For caching, we make the following assumptions: - if two paths to methods are {@code equal},
their control flow graph is the same. - if two transfer functions are {@code equal}, and are
run over the same control flow graph, the analysis result is the same. - for all contexts, the
analysis result is the same.