@Override
 @NotNull
 public String buildErrorString(Object... infos) {
   final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) infos[0];
   return InspectionGadgetsBundle.message(
       "cast.conflicts.with.instanceof.problem.descriptor", referenceExpression.getText());
 }
 private static boolean referenceExpressionsAreEquivalent(
     PsiReferenceExpression referenceExpression1, PsiReferenceExpression referenceExpression2) {
   final PsiElement element1 = referenceExpression1.resolve();
   final PsiElement element2 = referenceExpression2.resolve();
   if (element1 != null) {
     if (!element1.equals(element2)) {
       return false;
     }
   } else {
     return element2 == null;
   }
   if (element1 instanceof PsiMember) {
     final PsiMember member1 = (PsiMember) element1;
     if (member1.hasModifierProperty(PsiModifier.STATIC)) {
       return true;
     } else if (member1 instanceof PsiClass) {
       return true;
     }
   } else {
     return true;
   }
   final PsiExpression qualifier1 = referenceExpression1.getQualifierExpression();
   final PsiExpression qualifier2 = referenceExpression2.getQualifierExpression();
   if (qualifier1 != null
       && !(qualifier1 instanceof PsiThisExpression || qualifier1 instanceof PsiSuperExpression)) {
     if (qualifier2 == null) {
       return false;
     } else if (!expressionsAreEquivalent(qualifier1, qualifier2)) {
       return false;
     }
   } else {
     if (qualifier2 != null
         && !(qualifier2 instanceof PsiThisExpression
             || qualifier2 instanceof PsiSuperExpression)) {
       return false;
     }
   }
   final String text1 = referenceExpression1.getText();
   final String text2 = referenceExpression2.getText();
   return text1.equals(text2);
 }
 private static PsiMethodCallExpression prepareMethodCall(
     PsiReferenceExpression expr, String text) {
   PsiExpression qualifier = expr.getQualifierExpression();
   if (qualifier != null) {
     final PsiElement referenceNameElement = expr.getReferenceNameElement();
     if (referenceNameElement != null) {
       text = expr.getText().substring(0, referenceNameElement.getStartOffsetInParent()) + text;
     }
   }
   final PsiElementFactory factory =
       JavaPsiFacade.getInstance(expr.getProject()).getElementFactory();
   return (PsiMethodCallExpression) factory.createExpressionFromText(text, expr);
 }
  @Override
  protected boolean isAvailableImpl(int offset) {
    PsiReferenceExpression ref = myMethodCall.getMethodExpression();
    if (!ref.getText().equals(getSyntheticMethodName())) return false;

    PsiMethod method = PsiTreeUtil.getParentOfType(myMethodCall, PsiMethod.class);
    if (method == null || !method.isConstructor()) return false;
    if (CreateMethodFromUsageFix.hasErrorsInArgumentList(myMethodCall)) return false;
    List<PsiClass> targetClasses = getTargetClasses(myMethodCall);
    if (targetClasses.isEmpty()) return false;

    if (CreateFromUsageUtils.shouldShowTag(offset, ref.getReferenceNameElement(), myMethodCall)) {
      setText(QuickFixBundle.message("create.constructor.text", targetClasses.get(0).getName()));
      return true;
    }

    return false;
  }
  private static boolean containsOnlyPrivates(final PsiClass aClass) {
    final PsiField[] fields = aClass.getFields();
    for (PsiField field : fields) {
      if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false;
    }

    final PsiMethod[] methods = aClass.getMethods();
    for (PsiMethod method : methods) {
      if (!method.hasModifierProperty(PsiModifier.PRIVATE)) {
        if (method.isConstructor()) { // skip non-private constructors with call to super only
          final PsiCodeBlock body = method.getBody();
          if (body != null) {
            final PsiStatement[] statements = body.getStatements();
            if (statements.length == 0) continue;
            if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) {
              final PsiExpression expression =
                  ((PsiExpressionStatement) statements[0]).getExpression();
              if (expression instanceof PsiMethodCallExpression) {
                PsiReferenceExpression methodExpression =
                    ((PsiMethodCallExpression) expression).getMethodExpression();
                if (methodExpression.getText().equals(PsiKeyword.SUPER)) {
                  continue;
                }
              }
            }
          }
        }
        return false;
      }
    }

    final PsiClass[] inners = aClass.getInnerClasses();
    for (PsiClass inner : inners) {
      if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false;
    }

    return true;
  }
 @Nullable
 private String createListIterationText(@NotNull PsiForStatement forStatement) {
   final PsiBinaryExpression condition =
       (PsiBinaryExpression) ParenthesesUtils.stripParentheses(forStatement.getCondition());
   if (condition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(condition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(condition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = condition.getOperationTokenType();
   final String indexName;
   PsiExpression collectionSize;
   if (JavaTokenType.LT.equals(tokenType)) {
     indexName = lhs.getText();
     collectionSize = rhs;
   } else if (JavaTokenType.GT.equals(tokenType)) {
     indexName = rhs.getText();
     collectionSize = lhs;
   } else {
     return null;
   }
   if (collectionSize instanceof PsiReferenceExpression) {
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) collectionSize;
     final PsiElement target = referenceExpression.resolve();
     if (target instanceof PsiVariable) {
       final PsiVariable variable = (PsiVariable) target;
       collectionSize = ParenthesesUtils.stripParentheses(variable.getInitializer());
     }
   }
   if (!(collectionSize instanceof PsiMethodCallExpression)) {
     return null;
   }
   final PsiMethodCallExpression methodCallExpression =
       (PsiMethodCallExpression) ParenthesesUtils.stripParentheses(collectionSize);
   if (methodCallExpression == null) {
     return null;
   }
   final PsiReferenceExpression listLengthExpression =
       methodCallExpression.getMethodExpression();
   final PsiExpression qualifier =
       ParenthesesUtils.stripParentheses(listLengthExpression.getQualifierExpression());
   final PsiReferenceExpression listReference;
   if (qualifier instanceof PsiReferenceExpression) {
     listReference = (PsiReferenceExpression) qualifier;
   } else {
     listReference = null;
   }
   PsiType parameterType;
   if (listReference == null) {
     parameterType = extractListTypeFromContainingClass(forStatement);
   } else {
     final PsiType type = listReference.getType();
     if (type == null) {
       return null;
     }
     parameterType = extractContentTypeFromType(type);
   }
   if (parameterType == null) {
     parameterType = TypeUtils.getObjectType(forStatement);
   }
   final String typeString = parameterType.getCanonicalText();
   final PsiVariable listVariable;
   if (listReference == null) {
     listVariable = null;
   } else {
     final PsiElement target = listReference.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     listVariable = (PsiVariable) target;
   }
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration =
       isListElementDeclaration(firstStatement, listVariable, indexName, parameterType);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     contentVariableName = variable.getName();
     statementToSkip = declarationStatement;
     if (variable.hasModifierProperty(PsiModifier.FINAL)) {
       finalString = "final ";
     } else {
       finalString = "";
     }
   } else {
     final String collectionName;
     if (listReference == null) {
       collectionName = null;
     } else {
       collectionName = listReference.getReferenceName();
     }
     contentVariableName = createNewVariableName(forStatement, parameterType, collectionName);
     finalString = "";
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeString);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   @NonNls final String listName;
   if (listReference == null) {
     listName = "this";
   } else {
     listName = listReference.getText();
   }
   out.append(listName);
   out.append(')');
   if (body != null) {
     replaceCollectionGetAccess(
         body, contentVariableName, listVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
 @Nullable
 private String createArrayIterationText(@NotNull PsiForStatement forStatement) {
   final PsiExpression condition = forStatement.getCondition();
   final PsiBinaryExpression strippedCondition =
       (PsiBinaryExpression) ParenthesesUtils.stripParentheses(condition);
   if (strippedCondition == null) {
     return null;
   }
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(strippedCondition.getLOperand());
   if (lhs == null) {
     return null;
   }
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(strippedCondition.getROperand());
   if (rhs == null) {
     return null;
   }
   final IElementType tokenType = strippedCondition.getOperationTokenType();
   final PsiReferenceExpression arrayLengthExpression;
   final String indexName;
   if (tokenType.equals(JavaTokenType.LT)) {
     arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(rhs);
     indexName = lhs.getText();
   } else if (tokenType.equals(JavaTokenType.GT)) {
     arrayLengthExpression = (PsiReferenceExpression) ParenthesesUtils.stripParentheses(lhs);
     indexName = rhs.getText();
   } else {
     return null;
   }
   if (arrayLengthExpression == null) {
     return null;
   }
   PsiReferenceExpression arrayReference =
       (PsiReferenceExpression) arrayLengthExpression.getQualifierExpression();
   if (arrayReference == null) {
     final PsiElement target = arrayLengthExpression.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) target;
     final PsiExpression initializer = variable.getInitializer();
     if (!(initializer instanceof PsiReferenceExpression)) {
       return null;
     }
     final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) initializer;
     arrayReference = (PsiReferenceExpression) referenceExpression.getQualifierExpression();
     if (arrayReference == null) {
       return null;
     }
   }
   final PsiType type = arrayReference.getType();
   if (!(type instanceof PsiArrayType)) {
     return null;
   }
   final PsiArrayType arrayType = (PsiArrayType) type;
   final PsiType componentType = arrayType.getComponentType();
   final String typeText = componentType.getCanonicalText();
   final PsiElement target = arrayReference.resolve();
   if (!(target instanceof PsiVariable)) {
     return null;
   }
   final PsiVariable arrayVariable = (PsiVariable) target;
   final PsiStatement body = forStatement.getBody();
   final PsiStatement firstStatement = getFirstStatement(body);
   final boolean isDeclaration =
       isArrayElementDeclaration(firstStatement, arrayVariable, indexName);
   final String contentVariableName;
   @NonNls final String finalString;
   final PsiStatement statementToSkip;
   if (isDeclaration) {
     final PsiDeclarationStatement declarationStatement =
         (PsiDeclarationStatement) firstStatement;
     assert declarationStatement != null;
     final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
     final PsiElement declaredElement = declaredElements[0];
     if (!(declaredElement instanceof PsiVariable)) {
       return null;
     }
     final PsiVariable variable = (PsiVariable) declaredElement;
     if (VariableAccessUtils.variableIsAssigned(variable, forStatement)) {
       final String collectionName = arrayReference.getReferenceName();
       contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
       final Project project = forStatement.getProject();
       final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
       if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
         finalString = "final ";
       } else {
         finalString = "";
       }
       statementToSkip = null;
     } else {
       contentVariableName = variable.getName();
       statementToSkip = declarationStatement;
       if (variable.hasModifierProperty(PsiModifier.FINAL)) {
         finalString = "final ";
       } else {
         finalString = "";
       }
     }
   } else {
     final String collectionName = arrayReference.getReferenceName();
     contentVariableName = createNewVariableName(forStatement, componentType, collectionName);
     final Project project = forStatement.getProject();
     final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
     if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
       finalString = "final ";
     } else {
       finalString = "";
     }
     statementToSkip = null;
   }
   @NonNls final StringBuilder out = new StringBuilder();
   out.append("for(");
   out.append(finalString);
   out.append(typeText);
   out.append(' ');
   out.append(contentVariableName);
   out.append(": ");
   final String arrayName = arrayReference.getText();
   out.append(arrayName);
   out.append(')');
   if (body != null) {
     replaceArrayAccess(
         body, contentVariableName, arrayVariable, indexName, statementToSkip, out);
   }
   return out.toString();
 }
  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;
          }
        }
      }
    }
  }
  protected void generateFindViewById() {
    PsiClass activityClass =
        JavaPsiFacade.getInstance(mProject)
            .findClass("android.app.Activity", new EverythingGlobalScope(mProject));
    PsiClass compatActivityClass =
        JavaPsiFacade.getInstance(mProject)
            .findClass(
                "android.support.v7.app.AppCompatActivity", new EverythingGlobalScope(mProject));
    PsiClass fragmentClass =
        JavaPsiFacade.getInstance(mProject)
            .findClass("android.app.Fragment", new EverythingGlobalScope(mProject));
    PsiClass supportFragmentClass =
        JavaPsiFacade.getInstance(mProject)
            .findClass("android.support.v4.app.Fragment", new EverythingGlobalScope(mProject));

    // Check for Activity class
    if ((activityClass != null && mClass.isInheritor(activityClass, true))
        || (compatActivityClass != null && mClass.isInheritor(compatActivityClass, true))
        || mClass.getName().contains("Activity")) {
      if (mClass.findMethodsByName("onCreate", false).length == 0) {
        // Add an empty stub of onCreate()
        StringBuilder method = new StringBuilder();
        method.append(
            "@Override protected void onCreate(android.os.Bundle savedInstanceState) {\n");
        method.append("super.onCreate(savedInstanceState);\n");
        method.append("\t// TODO: add setContentView(...) and run LayoutCreator again\n");
        method.append("}");

        mClass.add(mFactory.createMethodFromText(method.toString(), mClass));
      } else {
        PsiStatement setContentViewStatement = null;
        boolean hasInitViewStatement = false;

        PsiMethod onCreate = mClass.findMethodsByName("onCreate", false)[0];
        for (PsiStatement statement : onCreate.getBody().getStatements()) {
          // Search for setContentView()
          if (statement.getFirstChild() instanceof PsiMethodCallExpression) {
            PsiReferenceExpression methodExpression =
                ((PsiMethodCallExpression) statement.getFirstChild()).getMethodExpression();
            if (methodExpression.getText().equals("setContentView")) {
              setContentViewStatement = statement;
            } else if (methodExpression.getText().equals("initView")) {
              hasInitViewStatement = true;
            }
          }
        }

        if (!hasInitViewStatement && setContentViewStatement != null) {
          // Insert initView() after setContentView()
          onCreate
              .getBody()
              .addAfter(
                  mFactory.createStatementFromText("initView();", mClass), setContentViewStatement);
        }
        generatorLayoutCode("this", null);
      }
      // Check for Fragment class
    } else if ((fragmentClass != null && mClass.isInheritor(fragmentClass, true))
        || (supportFragmentClass != null && mClass.isInheritor(supportFragmentClass, true))) {
      if (mClass.findMethodsByName("onCreateView", false).length == 0) {
        // Add an empty stub of onCreateView()
        StringBuilder method = new StringBuilder();
        method.append(
            "@Override public View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup container, android.os.Bundle savedInstanceState) {\n");
        method.append(
            "\t// TODO: inflate a fragment like bottom ... and run LayoutCreator again\n");
        method.append("View view = View.inflate(getActivity(), R.layout.frag_layout, null);");
        method.append("return view;");
        method.append("}");
        mClass.add(mFactory.createMethodFromText(method.toString(), mClass));
      } else {
        PsiReturnStatement returnStatement = null;
        String returnValue = null;
        boolean hasInitViewStatement = false;
        PsiMethod onCreateView = mClass.findMethodsByName("onCreateView", false)[0];
        for (PsiStatement statement : onCreateView.getBody().getStatements()) {
          if (statement instanceof PsiReturnStatement) {
            returnStatement = (PsiReturnStatement) statement;
            returnValue = returnStatement.getReturnValue().getText();
          } else if (statement.getFirstChild() instanceof PsiMethodCallExpression) {
            PsiReferenceExpression methodExpression =
                ((PsiMethodCallExpression) statement.getFirstChild()).getMethodExpression();
            if (methodExpression.getText().equals("initView")) {
              hasInitViewStatement = true;
            }
          }
        }

        if (!hasInitViewStatement && returnStatement != null && returnValue != null) {
          // Insert initView() before return statement
          onCreateView
              .getBody()
              .addBefore(
                  mFactory.createStatementFromText("initView(" + returnValue + ");", mClass),
                  returnStatement);
        }
        generatorLayoutCode("getContext()", returnValue);
      }
    }
  }
  private static void findParameterUsages(
      final PsiParameter parameter, final List<UsageInfo> usages) {
    final PsiMethod method = (PsiMethod) parameter.getDeclarationScope();
    final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
    // search for refs to current method only, do not search for refs to overriding methods, they'll
    // be searched separately
    ReferencesSearch.search(method)
        .forEach(
            reference -> {
              PsiElement element = reference.getElement();
              if (element != null) {
                final JavaSafeDeleteDelegate safeDeleteDelegate =
                    JavaSafeDeleteDelegate.EP.forLanguage(element.getLanguage());
                if (safeDeleteDelegate != null) {
                  safeDeleteDelegate.createUsageInfoForParameter(
                      reference, usages, parameter, method);
                }
                if (!parameter.isVarArgs()
                    && !RefactoringChangeUtil.isSuperMethodCall(element.getParent())) {
                  final PsiParameter paramInCaller =
                      SafeDeleteJavaCallerChooser.isTheOnlyOneParameterUsage(
                          element.getParent(), parameterIndex, method);
                  if (paramInCaller != null) {
                    final PsiMethod callerMethod = (PsiMethod) paramInCaller.getDeclarationScope();
                    if (ApplicationManager.getApplication().isUnitTestMode()) {
                      usages.add(
                          new SafeDeleteParameterCallHierarchyUsageInfo(
                              callerMethod, paramInCaller, callerMethod));
                    } else {
                      usages.add(
                          new SafeDeleteParameterCallHierarchyUsageInfo(
                              method, parameter, callerMethod));
                    }
                  }
                }
              }
              return true;
            });

    ReferencesSearch.search(parameter)
        .forEach(
            reference -> {
              PsiElement element = reference.getElement();
              final PsiDocTag docTag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);
              if (docTag != null) {
                usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(docTag, parameter, true));
                return true;
              }

              boolean isSafeDelete = false;
              if (element.getParent().getParent() instanceof PsiMethodCallExpression) {
                PsiMethodCallExpression call =
                    (PsiMethodCallExpression) element.getParent().getParent();
                PsiReferenceExpression methodExpression = call.getMethodExpression();
                if (methodExpression.getText().equals(PsiKeyword.SUPER)) {
                  isSafeDelete = true;
                } else if (methodExpression.getQualifierExpression()
                    instanceof PsiSuperExpression) {
                  final PsiMethod superMethod = call.resolveMethod();
                  if (superMethod != null
                      && MethodSignatureUtil.isSuperMethod(superMethod, method)) {
                    isSafeDelete = true;
                  }
                }
              }

              usages.add(
                  new SafeDeleteReferenceJavaDeleteUsageInfo(element, parameter, isSafeDelete));
              return true;
            });

    findFunctionalExpressions(usages, method);
  }
 @Override
 public void doFix(Project project, ProblemDescriptor descriptor)
     throws IncorrectOperationException {
   final PsiReferenceExpression parameterReference =
       (PsiReferenceExpression) descriptor.getPsiElement();
   final PsiElement target = parameterReference.resolve();
   if (!(target instanceof PsiParameter)) {
     return;
   }
   final PsiParameter parameter = (PsiParameter) target;
   final PsiElement declarationScope = parameter.getDeclarationScope();
   final PsiElement body;
   if (declarationScope instanceof PsiMethod) {
     final PsiMethod method = (PsiMethod) declarationScope;
     body = method.getBody();
   } else if (declarationScope instanceof PsiCatchSection) {
     final PsiCatchSection catchSection = (PsiCatchSection) declarationScope;
     body = catchSection.getCatchBlock();
   } else if (declarationScope instanceof PsiLoopStatement) {
     final PsiLoopStatement forStatement = (PsiLoopStatement) declarationScope;
     final PsiStatement forBody = forStatement.getBody();
     if (forBody instanceof PsiBlockStatement) {
       final PsiBlockStatement blockStatement = (PsiBlockStatement) forBody;
       body = blockStatement.getCodeBlock();
     } else {
       body = forBody;
     }
   } else {
     return;
   }
   if (body == null) {
     return;
   }
   final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
   final String parameterName = parameterReference.getText();
   final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
   final String variableName =
       javaCodeStyleManager.suggestUniqueVariableName(parameterName, parameterReference, true);
   final SearchScope scope = parameter.getUseScope();
   final Query<PsiReference> search = ReferencesSearch.search(parameter, scope);
   final PsiReference reference = search.findFirst();
   if (reference == null) {
     return;
   }
   final PsiElement element = reference.getElement();
   if (!(element instanceof PsiReferenceExpression)) {
     return;
   }
   final PsiReferenceExpression firstReference = (PsiReferenceExpression) element;
   final PsiElement[] children = body.getChildren();
   final int startIndex;
   final int endIndex;
   if (body instanceof PsiCodeBlock) {
     startIndex = 1;
     endIndex = children.length - 1;
   } else {
     startIndex = 0;
     endIndex = children.length;
   }
   boolean newDeclarationCreated = false;
   final StringBuilder buffer = new StringBuilder();
   for (int i = startIndex; i < endIndex; i++) {
     final PsiElement child = children[i];
     newDeclarationCreated |=
         replaceVariableName(child, firstReference, variableName, parameterName, buffer);
   }
   final String replacementText;
   if (newDeclarationCreated) {
     replacementText = "{" + buffer + '}';
   } else {
     final PsiType type = parameterReference.getType();
     if (type == null) {
       return;
     }
     final String className = type.getCanonicalText();
     replacementText =
         '{' + className + ' ' + variableName + " = " + parameterName + ';' + buffer + '}';
   }
   final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
   final PsiCodeBlock block = elementFactory.createCodeBlockFromText(replacementText, null);
   body.replace(block);
   codeStyleManager.reformat(declarationScope);
 }