@Nullable
  private static PsiMethod existingClassIsCompatible(PsiClass aClass, List<ParameterChunk> params) {
    if (params.size() == 1) {
      final ParameterChunk parameterChunk = params.get(0);
      final PsiType paramType = parameterChunk.parameter.type;
      if (TypeConversionUtil.isPrimitiveWrapper(aClass.getQualifiedName())) {
        parameterChunk.setField(aClass.findFieldByName("value", false));
        parameterChunk.setGetter(paramType.getCanonicalText() + "Value");
        for (PsiMethod constructor : aClass.getConstructors()) {
          if (constructorIsCompatible(constructor, params)) return constructor;
        }
      }
    }
    final PsiMethod[] constructors = aClass.getConstructors();
    PsiMethod compatibleConstructor = null;
    for (PsiMethod constructor : constructors) {
      if (constructorIsCompatible(constructor, params)) {
        compatibleConstructor = constructor;
        break;
      }
    }
    if (compatibleConstructor == null) {
      return null;
    }
    final PsiParameterList parameterList = compatibleConstructor.getParameterList();
    final PsiParameter[] constructorParams = parameterList.getParameters();
    for (int i = 0; i < constructorParams.length; i++) {
      final PsiParameter param = constructorParams[i];
      final ParameterChunk parameterChunk = params.get(i);

      final PsiField field = findFieldAssigned(param, compatibleConstructor);
      if (field == null) {
        return null;
      }

      parameterChunk.setField(field);

      final PsiMethod getterForField = PropertyUtil.findGetterForField(field);
      if (getterForField != null) {
        parameterChunk.setGetter(getterForField.getName());
      }

      final PsiMethod setterForField = PropertyUtil.findSetterForField(field);
      if (setterForField != null) {
        parameterChunk.setSetter(setterForField.getName());
      }
    }
    return compatibleConstructor;
  }
  private void findUsagesForMethod(
      PsiMethod overridingMethod, List<FixableUsageInfo> usages, boolean changeSignature) {
    final PsiCodeBlock body = overridingMethod.getBody();
    final String baseParameterName = StringUtil.decapitalize(className);
    final String fixedParamName =
        body != null
            ? JavaCodeStyleManager.getInstance(myProject)
                .suggestUniqueVariableName(baseParameterName, body.getLBrace(), true)
            : JavaCodeStyleManager.getInstance(myProject)
                .propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER);

    usages.add(
        new MergeMethodArguments(
            overridingMethod,
            className,
            packageName,
            fixedParamName,
            paramsToMerge,
            typeParams,
            keepMethodAsDelegate,
            myCreateInnerClass ? method.getContainingClass() : null,
            changeSignature));

    final ParamUsageVisitor visitor = new ParamUsageVisitor(overridingMethod, paramsToMerge);
    overridingMethod.accept(visitor);
    final Set<PsiReferenceExpression> values = visitor.getParameterUsages();
    for (PsiReferenceExpression paramUsage : values) {
      final PsiParameter parameter = (PsiParameter) paramUsage.resolve();
      assert parameter != null;
      final PsiMethod containingMethod = (PsiMethod) parameter.getDeclarationScope();
      final int index = containingMethod.getParameterList().getParameterIndex(parameter);
      final PsiParameter replacedParameter = method.getParameterList().getParameters()[index];
      final ParameterChunk parameterChunk =
          ParameterChunk.getChunkByParameter(parameter, parameters);

      @NonNls String getter = parameterChunk != null ? parameterChunk.getter : null;
      final String paramName =
          parameterChunk != null ? parameterChunk.parameter.name : replacedParameter.getName();
      final PsiType paramType =
          parameterChunk != null ? parameterChunk.parameter.type : replacedParameter.getType();
      if (getter == null) {
        getter = GenerateMembersUtil.suggestGetterName(paramName, paramType, myProject);
        paramsNeedingGetters.add(replacedParameter);
      }
      @NonNls String setter = parameterChunk != null ? parameterChunk.setter : null;
      if (setter == null) {
        setter = GenerateMembersUtil.suggestSetterName(paramName, paramType, myProject);
      }
      if (RefactoringUtil.isPlusPlusOrMinusMinus(paramUsage.getParent())) {
        usages.add(
            new ReplaceParameterIncrementDecrement(paramUsage, fixedParamName, setter, getter));
        if (parameterChunk == null || parameterChunk.setter == null) {
          paramsNeedingSetters.add(replacedParameter);
        }
      } else if (RefactoringUtil.isAssignmentLHS(paramUsage)) {
        usages.add(
            new ReplaceParameterAssignmentWithCall(paramUsage, fixedParamName, setter, getter));
        if (parameterChunk == null || parameterChunk.setter == null) {
          paramsNeedingSetters.add(replacedParameter);
        }
      } else {
        usages.add(new ReplaceParameterReferenceWithCall(paramUsage, fixedParamName, getter));
      }
    }
  }