private void printStats(
      int totalSnippets, int accepted, MicrobenchmarkGenerator g, List<BenchSnippet> snippets) {

    Map<String, Integer> causes = conf.getPreconditions().getRejectionCause();

    HashSet<String> classes = new HashSet<>();
    HashSet<String> methods = new HashSet<>();

    // Get Classes and Methods
    for (BenchSnippet snippet : snippets) {
      String className =
          snippet.getASTElement().getPosition().getCompilationUnit().getFile().getAbsolutePath();
      if (!classes.contains(className)) classes.add(className);

      try {
        String methodName =
            className + "::" + snippet.getASTElement().getParent(CtMethod.class).getSignature();
        if (!methods.contains(methodName)) methods.add(methodName);
      } catch (Exception ex) {
        log.warn("Unable to get method name for " + snippet.getPosition());
        // Do nothing
      }
    }
    log.info("----------- STATS: ---------------");
    log.info("Class covered: " + classes.size());
    log.info("Methods covered: " + methods.size());

    logCause(true, "Total", totalSnippets, totalSnippets);
    logCause(true, "Accepted", accepted, totalSnippets);

    logCause(true, VARS_UNSUPPORTED, causes, totalSnippets);
    logCause(false, COLLECTION_OF_UNSUPPORTED_TYPE, causes, totalSnippets);
    logCause(false, TYPE_IS_NOT_PUBLIC, causes, totalSnippets);
    logCause(
        false,
        TYPE_IS_NOT_STORABLE,
        causeCount(VARS_UNSUPPORTED, causes)
            - (causeCount(COLLECTION_OF_UNSUPPORTED_TYPE, causes)
                + causeCount(TYPE_IS_NOT_PUBLIC, causes)),
        totalSnippets);
    logCause(true, DYN_INV_UNSUPPORTED, causes, totalSnippets);
    logCause(false, DYN_METHOD_TARGET_TYPE_UNSUPPORTED, causes, totalSnippets);
    logCause(false, LEVELS_TOO_DEEP, causes, totalSnippets);
    logCause(false, PRIVATE_CONSTRUCTOR, causes, totalSnippets);
    logCause(false, ERR_GET_BODY + " - Protected", causes, totalSnippets);
    logCause(true, "Generated", g.getGeneratedCount(), totalSnippets);
    log.info("----------------------------------");

    for (Map.Entry<String, Integer> k : conf.getPreconditions().getRejectionCause().entrySet())
      log.info(" + " + k.getKey() + ": " + k.getValue());
  }
  /** Generates the benchmark suite */
  public void generate() {
    try {
      if (!checkInputPath()) return;

      // Clean working and result's dir
      log.info("Cleaning working dirs");
      cleanWorkingDir();
      cleanResultsDir();

      // Build the output project
      log.info("Building output POM file");
      MavenProjectBuilder builder = new MavenProjectBuilder(conf);
      builder.build();

      // Collect all tagglets from the input source
      log.info("Collecting tagglets");
      Map<String, List<Tagglet>> tagglets = null;
      if (customDetector == null) tagglets = collectTagglets();

      // Instrument all tagged points to record the data context
      log.info("Instrumenting data context");
      List<BenchSnippet> snippets = recordDataContext(tagglets);

      log.info("Removing non compliant snippets");
      List<BenchSnippet> complyingSnippets = new ArrayList<>();
      for (BenchSnippet snippet : snippets) {
        if (snippet.meetsPreconditions()) complyingSnippets.add(snippet);
        else if (conf.getPrintRejected()) {
          log.warn("REJECTING: " + snippet.getASTElement().toString());
        }
      }

      int totalSnippets = snippets.size();
      int accepted = complyingSnippets.size();
      if (accepted == 0) {
        log.info("No snippets accepted. Exiting");
        return;
      }

      snippets = complyingSnippets;

      // Clean the instrumentation from the snippets
      cleanInstrumentation(snippets);

      // Finally generate the benchmarks
      runGenerators(new MainClassGenerator(), snippets);
      log.info("Main file generated");

      runGenerators(new LoaderGenerator(), snippets);
      log.info("Loader file generated");

      runGenerators(new TestForMicrobenchmarkGenerator(), snippets);
      log.info("Unit tests file generated");

      // After the generation of the parts, the snippet changes its AST
      // That's why they are the last thing to be generated
      MicrobenchmarkGenerator g = new MicrobenchmarkGenerator();
      runGenerators(g, snippets);
      log.info("Microbenchmarks generated");

      printStats(totalSnippets, accepted, g, complyingSnippets);

    } catch (Exception e) {
      log.fatal("Process failed");
      throw new RuntimeException(e);
    }
  }