@Override
  protected void findUsages(final @NotNull List<? super FixableUsageInfo> usages) {
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject);
    final PsiElementFactory elementFactory = facade.getElementFactory();
    final PsiResolveHelper resolveHelper = facade.getResolveHelper();

    if (myCurrentInheritor != null) {
      myTargetClasses = new PsiClass[] {myCurrentInheritor};
    }
    else {
      Collection<PsiClass> inheritors = DirectClassInheritorsSearch.search(mySuperClass).findAll();
      myTargetClasses = inheritors.toArray(PsiClass.EMPTY_ARRAY);
    }

    if (myCurrentInheritor != null) {
      findUsagesInExtendsList(usages, myCurrentInheritor.getExtendsList());
      findUsagesInExtendsList(usages, myCurrentInheritor.getImplementsList());
    }
    else {
      ReferencesSearch.search(mySuperClass).forEach(reference -> {
        final PsiElement element = reference.getElement();
        if (element instanceof PsiJavaCodeReferenceElement classRef) {
          final PsiImportStaticStatement staticImportStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class);
          if (staticImportStatement != null) {
            usages.add(new ReplaceStaticImportUsageInfo(staticImportStatement, myTargetClasses));
          } else {
            final PsiImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PsiImportStatement.class);
            if (importStatement != null) {
              usages.add(new RemoveImportUsageInfo(importStatement));
            }
            else {
              final PsiElement parent = element.getParent();
              if (parent instanceof PsiReferenceList) {
                final PsiElement pparent = parent.getParent();
                if (pparent instanceof PsiClass inheritor) {
                  if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) {
                    usages.add(new ReplaceExtendsListUsageInfo(classRef, mySuperClass, inheritor));
                  }
                  else if (parent.equals(inheritor.getPermitsList())) {
                    usages.add(new RemovePermitsListUsageInfo(classRef, mySuperClass, inheritor));
                  }
                }
              } else {
                final PsiClass targetClass = myTargetClasses[0];
                final PsiClassType targetClassType = elementFactory
                  .createType(targetClass, TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY));

                if (parent instanceof PsiTypeElement typeElement) {
                  final PsiType superClassType = typeElement.getType();
                  PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass);
                  usages.add(new ReplaceWithSubtypeUsageInfo(typeElement, elementFactory.createType(targetClass, subst), myTargetClasses));
                }
                else if (parent instanceof PsiNewExpression newExpression) {
                  final PsiClassType newType = elementFactory.createType(
                    targetClass, getSuperClassSubstitutor(newExpression.getType(), targetClassType, resolveHelper, targetClass));
                  usages.add(new ReplaceConstructorUsageInfo(newExpression, newType, myTargetClasses));
                }
                else if (parent instanceof PsiJavaCodeReferenceElement ref) {
                  usages.add(new ReplaceReferenceUsageInfo(ref.getQualifier(), myTargetClasses));
                }
              }
            }
          }
        }
        return true;
      });
    }
    for (PsiClass targetClass : myTargetClasses) {
      if (skipTargetClass(targetClass)) {
        continue;
      }

      for (MemberInfo memberInfo : myMemberInfos) {
        final PsiMember member = memberInfo.getMember();
        for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) {
          final PsiElement element = reference.getElement();
          if (element instanceof PsiReferenceExpression &&
              ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression &&
              PsiTreeUtil.isAncestor(targetClass, element, false) &&
              !PushDownConflicts.isSuperCallToBeInlined(member, targetClass, mySuperClass)) {
            usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element));
          }
        }
      }

      if (!mySuperClass.isInterface()) {
        final PsiMethod[] superConstructors = mySuperClass.getConstructors();
        Set<PsiMethod> addedSuperConstructors = new HashSet<>();
        for (PsiMethod constructor : targetClass.getConstructors()) {
          final PsiCodeBlock constrBody = constructor.getBody();
          PsiMethodCallExpression call = JavaPsiConstructorUtil.findThisOrSuperCallInConstructor(constructor);
          if (JavaPsiConstructorUtil.isSuperConstructorCall(call)) {
            final PsiMethod superConstructor = call.resolveMethod();
            if (superConstructor != null && superConstructor.getBody() != null) {
              usages.add(new InlineSuperCallUsageInfo(call));
              processChainedCallsInSuper(superConstructor, targetClass, usages, addedSuperConstructors);
              continue;
            }
          }

          //insert implicit call to super
          for (PsiMethod superConstructor : superConstructors) {
            if (superConstructor.getParameterList().isEmpty()) {
              final PsiExpression expression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor);
              usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression, constrBody));
              processChainedCallsInSuper(superConstructor, targetClass, usages, addedSuperConstructors);
            }
          }
        }

        if (targetClass.getConstructors().length == 0) {
          //copy default constructor
          for (PsiMethod superConstructor : superConstructors) {
            if (superConstructor.getParameterList().isEmpty()) {
              usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor));
              break;
            }
          }
        }
      }
    }
  }
@Override
  protected void findUsages(final @NotNull List<? super FixableUsageInfo> usages)