private boolean initMatches(PsiElement @NotNull [] pattern, @NotNull List<Match> matches) {
    if (myElements.length == 0) {
      return false;
    }

    myUsagesList = new ArrayList<>();
    Map<PsiExpression, ClusterOfUsages> usagesMap = new HashMap<>();
    Set<Match> badMatches = new HashSet<>();
    for (Match match : matches) {
      List<ClusterOfUsages> usagesInMatch = getUsagesInMatch(usagesMap, match);
      if (usagesInMatch == null) {
        badMatches.add(match);
        continue;
      }
      for (ClusterOfUsages usages : usagesInMatch) {
        myUsagesList.add(usages);
        for (PsiExpression expression : usages.myPatterns) {
          usagesMap.put(expression, usages);
        }
      }
    }

    if (!badMatches.isEmpty()) {
      matches = new ArrayList<>(matches);
      matches.removeAll(badMatches);
    }
    myMatches = matches;
    if (myMatches.isEmpty()) {
      return false;
    }

    Map<Match, Map<PsiExpression, PsiExpression>> expressionsMapping = new HashMap<>();
    for (ClusterOfUsages usages : myUsagesList) {
      for (Match match : myMatches) {
        ExtractedParameter parameter = usages.getParameter(match);
        if (parameter == null) {
          Map<PsiExpression, PsiExpression> expressions =
            expressionsMapping.computeIfAbsent(match, unused -> {
              Map<PsiExpression, PsiExpression> result = new HashMap<>();
              collectCopyMapping(pattern, match.getMatchElements(), usagesMap.keySet()::contains, result::put, (unused1, unused2) -> {});
              return result;
            });
          PsiExpression candidateUsage = usages.myPatterns.stream().map(expressions::get).findAny().orElse(null);
          LOG.assertTrue(candidateUsage != null, "candidateUsage shouldn't be null");

          ExtractedParameter fromParameter = usages.myParameter;
          parameter = fromParameter.copyWithCandidateUsage(candidateUsage);
          match.addExtractedParameter(parameter);
          usages.putParameter(match, parameter);
        }
      }
    }

    mergeDuplicateUsages(myUsagesList, myMatches);
    myUsagesList.sort(Comparator.comparing(usages -> usages.myFirstOffset));
    return true;
  }
private boolean initMatches(PsiElement @NotNull [] pattern, @NotNull List<Match> matches)