public CochangeApriori calculeApriori(final FilePair cochange) {
    Long totalIssues = issueRepository.countFixedIssues();
    Long file1Issues = fileRepository.calculeNumberOfIssues(cochange.getFile1());
    Long file2Issues = fileRepository.calculeNumberOfIssues(cochange.getFile2());
    Long cochangeIssues = fileRepository.countFixedIssues(cochange);

    CochangeApriori apriori =
        new CochangeApriori(
            cochange.getFile1(),
            cochange.getFile2(),
            file1Issues,
            file2Issues,
            cochangeIssues,
            totalIssues);

    return apriori;
  }
  @Override
  public AssociationRuleLog process(Project project) throws Exception {
    commitRepository.setProject(project);
    issueRepository.setProject(project);
    fileRepository.setProject(project);
    issuesMetricsRepository.setProject(project);
    networkMetricsRepository.setProject(project);
    fileMetricsRepository.setProject(project);
    commitMetricsRepository.setProject(project);
    predictionRepository.setProject(project);

    AssociationRuleLog associationRuleLog = new AssociationRuleLog(project, "Zimmermann");
    associationRuleLog.start();

    final Predicate<File> fileFilter = FileFilter.getFilterByFilename(filter);

    // select new commits
    final List<Commit> newCommits;
    if (StringUtils.isBlank(issueKey)) {
      newCommits = commitRepository.selectNewCommitsForAssociationRule();
    } else {
      newCommits = commitRepository.selectCommitsOf(issueKey);
    }

    for (Commit newCommit : newCommits) {

      log.info("Computing metrics for changed files on commit " + newCommit.getId());
      // select changed files
      final List<File> changedFiles = fileRepository.selectChangedFilesIn(newCommit);

      final long totalTransactions = commitRepository.count();

      for (File changedFile :
          changedFiles.stream().filter(fileFilter).collect(Collectors.toList())) {

        log.info("Computing association rule for file " + changedFile.getId() + " in the past.");
        // find all issues/commits where file was changed
        final List<Issue> issuesOfFile =
            issueRepository.selectFixedIssuesOf(changedFile, newCommit);
        final Set<Transaction<File>> transactions = new LinkedHashSet<>();

        long issuesProcessed = 0;
        for (Issue issue : issuesOfFile) {
          log.info(++issuesProcessed + " of " + issuesOfFile.size() + " past issues processed.");

          List<Commit> commits = commitRepository.selectCommitsOf(issue);

          // Transaction is composed by files of commit
          for (Commit commit : commits) {
            final List<File> changedFilesInIssue = fileRepository.selectChangedFilesIn(commit);
            final Transaction<File> transaction =
                new Transaction<>(issue.getId().longValue(), new HashSet<>(changedFilesInIssue));
            transactions.add(transaction);
          }
        }

        AssociationRuleExtractor<File> extractor =
            new AssociationRuleExtractor<>(transactions, totalTransactions);

        final Set<AssociationRule<File>> navigationRules =
            extractor.queryAssociationRulesSingleConsequent(changedFile);
        final List<AssociationRule<File>> orderedPredictions =
            AssociationRuleOrdering.sortBySupportAndConfidence(navigationRules);
        predictionRepository.savePrediction(newCommit, orderedPredictions, topAssociationRules);
      }
    }

    associationRuleLog.stop();

    return associationRuleLog;
  }