private JavaDescriptorResolver.ValueParameterDescriptors
      modifyValueParametersAccordingToSuperMethods(
          @NotNull
              JavaDescriptorResolver.ValueParameterDescriptors
                  parameters // descriptors built by parameters resolver
          ) {
    // we are not processing receiver type specifically:
    // if this function comes from Kotlin, then we don't need to do it, if it doesn't, then it can't
    // have receiver

    List<ValueParameterDescriptor> resultParameters = Lists.newArrayList();

    for (ValueParameterDescriptor originalParam : parameters.getDescriptors()) {
      final int index = originalParam.getIndex();
      List<TypeAndVariance> typesFromSuperMethods =
          ContainerUtil.map(
              superFunctions,
              new Function<FunctionDescriptor, TypeAndVariance>() {
                @Override
                public TypeAndVariance fun(FunctionDescriptor superFunction) {
                  return new TypeAndVariance(
                      superFunction.getValueParameters().get(index).getType(), INVARIANT);
                }
              });

      VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam);

      JetType altType =
          modifyTypeAccordingToSuperMethods(
              varargCheckResult.parameterType,
              typesFromSuperMethods,
              MEMBER_SIGNATURE_CONTRAVARIANT);

      resultParameters.add(
          new ValueParameterDescriptorImpl(
              originalParam.getContainingDeclaration(),
              index,
              originalParam.getAnnotations(),
              originalParam.getName(),
              altType,
              originalParam.declaresDefaultValue(),
              varargCheckResult.isVararg
                  ? KotlinBuiltIns.getInstance().getArrayElementType(altType)
                  : null));
    }

    JetType originalReceiverType = parameters.getReceiverType();
    if (originalReceiverType != null) {
      JetType substituted =
          SignaturesUtil.createSubstitutorForFunctionTypeParameters(autoTypeParameterToModified)
              .substitute(originalReceiverType, INVARIANT);
      assert substituted != null;
      return new JavaDescriptorResolver.ValueParameterDescriptors(substituted, resultParameters);
    } else {
      return new JavaDescriptorResolver.ValueParameterDescriptors(null, resultParameters);
    }
  }
  public SignaturesPropagationData(
      @NotNull ClassDescriptor containingClass,
      @NotNull
          JetType
              autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull
                              // annotations
      @NotNull
          JavaDescriptorResolver.ValueParameterDescriptors
              autoValueParameters, // descriptors built by parameters resolver
      @NotNull
          List<TypeParameterDescriptor>
              autoTypeParameters, // descriptors built by signature resolver
      @NotNull PsiMethodWrapper method,
      @NotNull BindingTrace trace) {
    this.containingClass = containingClass;
    superFunctions = getSuperFunctionsForMethod(method, trace, containingClass);

    autoTypeParameterToModified =
        SignaturesUtil.recreateTypeParametersAndReturnMapping(autoTypeParameters);

    modifiedTypeParameters = modifyTypeParametersAccordingToSuperMethods(autoTypeParameters);
    modifiedReturnType = modifyReturnTypeAccordingToSuperMethods(autoReturnType);
    modifiedValueParameters = modifyValueParametersAccordingToSuperMethods(autoValueParameters);
  }