public static MultiMap<PsiElement, @Nls String> checkConflicts(final MemberInfoBase<? extends GrMember>[] infos,
                                                                 @NotNull final PsiClass subclass,
                                                                 @Nullable PsiClass superClass,
                                                                 @NotNull final PsiPackage targetPackage,
                                                                 @NotNull PsiDirectory targetDirectory,
                                                                 final InterfaceContainmentVerifier interfaceContainmentVerifier,
                                                                 boolean movedMembers2Super) {
    final PsiElement targetRepresentativeElement;
    final boolean isInterfaceTarget;
    if (superClass != null) {
      isInterfaceTarget = superClass.isInterface();
      targetRepresentativeElement = superClass;
    }
    else {
      isInterfaceTarget = false;
      targetRepresentativeElement = targetDirectory;
    }

    final Set<GrMember> movedMembers = new HashSet<>();
    final Set<GrMethod> abstractMethods = new HashSet<>();
    for (MemberInfoBase<? extends GrMember> info : infos) {
      GrMember member = info.getMember();
      if (member instanceof GrMethod) {
        if (!info.isToAbstract() && !isInterfaceTarget) {
          movedMembers.add(member);
        }
        else {
          abstractMethods.add((GrMethod)member);
        }
      }
      else {
        movedMembers.add(member);
      }
    }

    final Set<PsiMethod> allAbstractMethods = new HashSet<>(abstractMethods);
    if (superClass != null) {
      for (PsiMethod method : subclass.getMethods()) {
        if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) {
          if (method.findSuperMethods(superClass).length > 0) {
            allAbstractMethods.add(method);
          }
        }
      }
    }

    final MultiMap<PsiElement, @Nls String> conflicts = new MultiMap<>();

    GrRefactoringConflictsUtil.analyzeAccessibilityConflicts(movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement,
                                                             allAbstractMethods);

    if (superClass != null) {
      if (movedMembers2Super) {
        checkSuperclassMembers(superClass, infos, conflicts);
        if (isInterfaceTarget) {
          checkInterfaceTarget(infos, conflicts);
        }
      } else {
        final String qualifiedName = superClass.getQualifiedName();
        assert qualifiedName != null;
        if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
          if (!Comparing.strEqual(StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) {
            conflicts.putValue(superClass,
                               GroovyBundle.message("pull.up.wont.be.accessible.from",
                                                    RefactoringUIUtil.getDescription(superClass, true),
                                                    RefactoringUIUtil.getDescription(targetPackage, true)));
          }
        }
      }
    }
    // check if moved methods use other members in the classes between Subclass and Superclass
    List<PsiElement> checkModuleConflictsList = new ArrayList<>();
    for (PsiMember member : movedMembers) {
      if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) {
        GrClassMemberReferenceVisitor visitor =
          movedMembers2Super? new ConflictingUsagesOfSubClassMembers(member, movedMembers, abstractMethods, subclass, superClass,
                                                                     superClass != null ? null : targetPackage, conflicts,
                                                                     interfaceContainmentVerifier)
                            : new ConflictingUsagesOfSuperClassMembers(member, subclass, targetPackage, movedMembers, conflicts);
        ((GroovyPsiElement)member).accept(visitor);
      }
      checkModuleConflictsList.add(member);
    }
    for (final PsiMethod method : abstractMethods) {
      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList());
      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement());
      ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList());
    }
    GrRefactoringConflictsUtil.analyzeModuleConflicts(subclass.getProject(), checkModuleConflictsList, UsageInfo.EMPTY_ARRAY, targetRepresentativeElement, conflicts);
    final String fqName = subclass.getQualifiedName();
    final String packageName;
    if (fqName != null) {
      packageName = StringUtil.getPackageName(fqName);
    } else {
      final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class);
      if (psiFile instanceof PsiClassOwner) {
        packageName = ((PsiClassOwner)psiFile).getPackageName();
      } else {
        packageName = null;
      }
    }
    final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName);
    for (final GrMethod abstractMethod : abstractMethods) {
      abstractMethod.accept(new GrClassMemberReferenceVisitor(subclass) {
        @Override
        protected void visitClassMemberReferenceElement(GrMember classMember, GrReferenceElement classMemberReference) {
          if (classMember != null && willBeMoved(classMember, movedMembers)) {
            boolean isAccessible = false;
            if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) {
              isAccessible = true;
            }
            else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) &&
                     toDifferentPackage) {
              isAccessible = true;
            }
            if (isAccessible) {
              String message =
                GroovyBundle.message("pull.up.wont.be.accessible.from.the.subclass", RefactoringUIUtil.getDescription(abstractMethod, false), RefactoringUIUtil.getDescription(classMember, true));
              conflicts.putValue(classMember, StringUtil.capitalize(message));
            }
          }
        }
      });
      if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) {
        if (!isInterfaceTarget) {
          String message =
            GroovyBundle.message("pull.up.abstract.wont.be.accessible.from", RefactoringUIUtil.getDescription(abstractMethod, false));
          conflicts.putValue(abstractMethod, StringUtil.capitalize(message));
        }
      }
    }
    return conflicts;
  }
public static MultiMap<PsiElement, @Nls String> checkConflicts(final MemberInfoBase<? extends GrMember>[] infos,
                                                                 @NotNull final PsiClass subclass,
                                                                 @Nullable PsiClass superClass,
                                                                 @NotNull final PsiPackage targetPackage,
                                                                 @NotNull PsiDirectory targetDirectory,
                                                                 final InterfaceContainmentVerifier interfaceContainmentVerifier,
                                                                 boolean movedMembers2Super)