private static void collectCopyMapping(@NotNull PsiElement pattern,
                                         @NotNull PsiElement copy,
                                         @NotNull Predicate<? super PsiExpression> isReplaceablePattern,
                                         @NotNull BiConsumer<? super PsiExpression, ? super PsiExpression> expressionsMapping,
                                         @NotNull BiConsumer<? super PsiVariable, ? super PsiVariable> variablesMapping) {
    if (pattern == copy) return;
    if (pattern instanceof PsiExpression && copy instanceof PsiExpression && isReplaceablePattern.test((PsiExpression)pattern)) {
      expressionsMapping.accept((PsiExpression)pattern, (PsiExpression)copy);
      return;
    }

    if (pattern instanceof PsiJavaCodeReferenceElement && copy instanceof PsiJavaCodeReferenceElement) {
      PsiElement resolvedPattern = ((PsiJavaCodeReferenceElement)pattern).resolve();
      PsiElement resolvedCopy = ((PsiJavaCodeReferenceElement)copy).resolve();
      if (resolvedPattern != resolvedCopy && resolvedPattern instanceof PsiVariable && resolvedCopy instanceof PsiVariable) {
        variablesMapping.accept((PsiVariable)resolvedPattern, (PsiVariable)resolvedCopy);
      }
      PsiElement patternQualifier = ((PsiJavaCodeReferenceElement)pattern).getQualifier();
      PsiElement copyQualifier = ((PsiJavaCodeReferenceElement)copy).getQualifier();
      if (patternQualifier != null && copyQualifier != null) {
        collectCopyMapping(patternQualifier, copyQualifier, isReplaceablePattern, expressionsMapping, variablesMapping);
      }
      return;
    }

    if (pattern instanceof PsiVariable && copy instanceof PsiVariable) {
      variablesMapping.accept((PsiVariable)pattern, (PsiVariable)copy);
    }

    collectCopyMapping(pattern.getChildren(), copy.getChildren(), isReplaceablePattern, expressionsMapping, variablesMapping);
  }
private static void collectCopyMapping(@NotNull PsiElement pattern,
                                         @NotNull PsiElement copy,
                                         @NotNull Predicate<? super PsiExpression> isReplaceablePattern,
                                         @NotNull BiConsumer<? super PsiExpression, ? super PsiExpression> expressionsMapping,
                                         @NotNull BiConsumer<? super PsiVariable, ? super PsiVariable> variablesMapping)