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

    ReferencesSearch.search(mySuperClass)
        .forEach(
            new Processor<PsiReference>() {
              public boolean process(final PsiReference reference) {
                final PsiElement element = reference.getElement();
                if (element instanceof PsiJavaCodeReferenceElement) {
                  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) {
                          final PsiClass inheritor = (PsiClass) pparent;
                          if (parent.equals(inheritor.getExtendsList())
                              || parent.equals(inheritor.getImplementsList())) {
                            usages.add(
                                new ReplaceExtendsListUsageInfo(
                                    (PsiJavaCodeReferenceElement) element,
                                    mySuperClass,
                                    inheritor));
                          }
                        }
                      } else {
                        final PsiClass targetClass = myTargetClasses[0];
                        final PsiClassType targetClassType =
                            elementFactory.createType(
                                targetClass,
                                TypeConversionUtil.getSuperClassSubstitutor(
                                    mySuperClass, targetClass, PsiSubstitutor.EMPTY));

                        if (parent instanceof PsiTypeElement) {
                          final PsiType superClassType = ((PsiTypeElement) parent).getType();
                          PsiSubstitutor subst =
                              getSuperClassSubstitutor(
                                  superClassType, targetClassType, resolveHelper, targetClass);
                          usages.add(
                              new ReplaceWithSubtypeUsageInfo(
                                  ((PsiTypeElement) parent),
                                  elementFactory.createType(targetClass, subst),
                                  myTargetClasses));
                        } else if (parent instanceof PsiNewExpression) {
                          final PsiClassType newType =
                              elementFactory.createType(
                                  targetClass,
                                  getSuperClassSubstitutor(
                                      ((PsiNewExpression) parent).getType(),
                                      targetClassType,
                                      resolveHelper,
                                      targetClass));
                          usages.add(
                              new ReplaceConstructorUsageInfo(
                                  ((PsiNewExpression) parent), newType, myTargetClasses));
                        } else if (parent instanceof PsiJavaCodeReferenceElement) {
                          usages.add(
                              new ReplaceReferenceUsageInfo(
                                  ((PsiJavaCodeReferenceElement) parent).getQualifier(),
                                  myTargetClasses));
                        }
                      }
                    }
                  }
                }
                return true;
              }
            });
    for (PsiClass targetClass : myTargetClasses) {
      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)) {
            usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression) element));
          }
        }
      }

      final PsiMethod[] superConstructors = mySuperClass.getConstructors();
      for (PsiMethod constructor : targetClass.getConstructors()) {
        final PsiCodeBlock constrBody = constructor.getBody();
        LOG.assertTrue(constrBody != null);
        final PsiStatement[] statements = constrBody.getStatements();
        if (statements.length > 0) {
          final PsiStatement firstConstrStatement = statements[0];
          if (firstConstrStatement instanceof PsiExpressionStatement) {
            final PsiExpression expression =
                ((PsiExpressionStatement) firstConstrStatement).getExpression();
            if (expression instanceof PsiMethodCallExpression) {
              final PsiReferenceExpression methodExpression =
                  ((PsiMethodCallExpression) expression).getMethodExpression();
              if (methodExpression.getText().equals(PsiKeyword.SUPER)) {
                final PsiMethod superConstructor =
                    ((PsiMethodCallExpression) expression).resolveMethod();
                if (superConstructor != null && superConstructor.getBody() != null) {
                  usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression) expression));
                  continue;
                }
              }
            }
          }
        }

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

      if (targetClass.getConstructors().length == 0) {
        // copy default constructor
        for (PsiMethod superConstructor : superConstructors) {
          if (superConstructor.getParameterList().getParametersCount() == 0) {
            usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor));
            break;
          }
        }
      }
    }
  }