class TaintDataflowEngine implements IMethodAnalysisEngine<TaintDataflow> {

    @Override
    public TaintDataflow analyze(IAnalysisCache cache, MethodDescriptor descriptor)
            throws CheckedAnalysisException {
        if(FindSecBugsGlobalConfig.getInstance().isDebugPrintInstructionVisited() || FindSecBugsGlobalConfig.getInstance().isDebugPrintInvocationVisited()) {
            System.out.println("==[ Method: "+descriptor.getName()+" ]==");
        }
        CFG cfg = cache.getMethodAnalysis(CFG.class, descriptor);
        DepthFirstSearch dfs = cache.getMethodAnalysis(DepthFirstSearch.class, descriptor);
        MethodGen methodGen = cache.getMethodAnalysis(MethodGen.class, descriptor);
        TaintAnalysis analysis = new TaintAnalysis(methodGen, dfs, descriptor, taintConfig, visitors);
        TaintDataflow flow = new TaintDataflow(cfg, analysis);
        flow.execute();
        analysis.finishAnalysis();
        if (CONFIG.isDebugOutputTaintConfigs() && writer != null) {
            String slashedMethodName = getSlashedMethodName(methodGen);
            TaintMethodConfig derivedConfig = taintConfig.get(slashedMethodName);
            if (derivedConfig != null) {
                try {
                    writer.append(slashedMethodName);

                    Taint outputTaint = derivedConfig.getOutputTaint();
                    if (outputTaint != null) {
                        writer.append(':');
                        writeTaint(outputTaint);
                    }

                    Map<Integer, Taint> parametersOutputTaints = derivedConfig.getParametersOutputTaints();
                    if (!parametersOutputTaints.isEmpty()) {
                        for (Map.Entry<Integer, Taint> parameterTaint : parametersOutputTaints.entrySet()) {
                            writer.append('^');
                            writer.append(Integer.toString(parameterTaint.getKey()));
                            writer.append(':');
                            writeTaint(parameterTaint.getValue());
                        }
                    }

                    writer.append('\n');
                    writer.flush();
                } catch (IOException ex) {
                    AnalysisContext.logError("Cannot write derived configs", ex);
                }
            }
        }
        return flow;
    }

    public  TaintDataflowEngine();

}