public boolean putParameter(DuplicatesFinder.Parameter parameter, PsiElement value) {
    final PsiVariable psiVariable = parameter.getVariable();

    if (myDeclarationCorrespondence.get(psiVariable) == null) {
      final boolean [] valueDependsOnReplacedScope = new boolean[1];
      value.accept(new JavaRecursiveElementWalkingVisitor() {
        @Override
        public void visitReferenceExpression(final @NotNull PsiReferenceExpression expression) {
          super.visitReferenceExpression(expression);
          final PsiElement resolved = expression.resolve();
          if (resolved != null && Comparing.equal(resolved.getContainingFile(), getMatchEnd().getContainingFile())) {
            final TextRange range = checkRange(resolved);
            final TextRange startRange = checkRange(getMatchStart());
            final TextRange endRange = checkRange(getMatchEnd());
            if (startRange.getStartOffset() <= range.getStartOffset() && range.getEndOffset() <= endRange.getEndOffset()) {
              valueDependsOnReplacedScope[0] = true;
            }
          }
        }
      });
      if (valueDependsOnReplacedScope[0]) return false;
    }

    final List<PsiElement> currentValue = myParameterValues.get(psiVariable);
    final boolean isVararg = psiVariable instanceof PsiParameter && ((PsiParameter)psiVariable).isVarArgs();
    if (!(value instanceof PsiExpression)) return false;
    final PsiElement parent = value.getParent();
    if (parent instanceof PsiMethodCallExpression && value == ((PsiMethodCallExpression)parent).getMethodExpression()) return false;
    final PsiType type = ((PsiExpression)value).getType();
    final PsiType parameterType = parameter.getType();
    if (type == null) return false;
    if (currentValue == null) {
      if (PsiUtil.resolveClassInClassTypeOnly(parameterType) instanceof PsiTypeParameter typeParameter) {
        LOG.assertTrue(typeParameter != null);
        for (PsiClassType classType : typeParameter.getExtendsListTypes()) {
          if (!classType.isAssignableFrom(type)) return false;
        }
      }
      else {
        if (isVararg) {
          if (!((PsiEllipsisType)psiVariable.getType()).getComponentType().isAssignableFrom(type) && !((PsiEllipsisType)psiVariable.getType()).toArrayType().equals(type)) {
            myChangedParams.put(psiVariable, new PsiEllipsisType(parameterType));
          }
        } else {
          if (!myIgnoreParameterTypes && !parameterType.isAssignableFrom(type)) return false;  //todo
        }
      }
      final List<PsiElement> values = new ArrayList<>();
      values.add(value);
      myParameterValues.put(psiVariable, values);
      final ArrayList<PsiElement> elements = new ArrayList<>();
      myParameterOccurrences.put(psiVariable, elements);
    }
    else {
      for (PsiElement val : currentValue) {
        if (!isVararg && !PsiEquivalenceUtil.areElementsEquivalent(val, value)) {
          return false;
        }
      }
      if (isVararg) {
        if (!parameterType.isAssignableFrom(type)) return false;
        if (!((PsiEllipsisType)psiVariable.getType()).toArrayType().equals(type)){
          currentValue.add(value);
        }
      }
      myParameterOccurrences.get(psiVariable).add(value);
    }
    return true;
  }
public boolean putParameter(DuplicatesFinder.Parameter parameter, PsiElement value)