private void checkParameterAndReturnTypesForOverridingMethods(
      @NotNull List<ValueParameterDescriptor> valueParameters,
      @NotNull List<TypeParameterDescriptor> methodTypeParameters,
      @Nullable JetType returnType) {
    TypeSubstitutor substitutor =
        DescriptorResolverUtils.createSubstitutorForTypeParameters(originalToAltTypeParameters);

    for (ValueParameterDescriptor parameter : valueParameters) {
      int index = parameter.getIndex();
      ValueParameterDescriptor altParameter = altValueParameters.get(index);

      JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT);
      assert substituted != null;

      if (!TypeUtils.equalTypes(substituted, altParameter.getType())) {
        throw new AlternativeSignatureMismatchException(
            "Parameter type changed for method which overrides another: "
                + altParameter.getType()
                + ", was: "
                + parameter.getType());
      }
    }

    // don't check receiver

    for (TypeParameterDescriptor parameter : methodTypeParameters) {
      int index = parameter.getIndex();

      JetType substituted =
          substitutor.substitute(parameter.getUpperBoundsAsType(), Variance.INVARIANT);
      assert substituted != null;

      if (!TypeUtils.equalTypes(substituted, altTypeParameters.get(index).getUpperBoundsAsType())) {
        throw new AlternativeSignatureMismatchException(
            "Type parameter's upper bound changed for method which overrides another: "
                + altTypeParameters.get(index).getUpperBoundsAsType()
                + ", was: "
                + parameter.getUpperBoundsAsType());
      }
    }

    if (returnType != null) {
      JetType substitutedReturnType = substitutor.substitute(returnType, Variance.INVARIANT);
      assert substitutedReturnType != null;

      if (!JetTypeChecker.INSTANCE.isSubtypeOf(altReturnType, substitutedReturnType)) {
        throw new AlternativeSignatureMismatchException(
            "Return type is changed to not subtype for method which overrides another: "
                + altReturnType
                + ", was: "
                + returnType);
      }
    }
  }
 @Nullable
 private JetType checkAssignmentType(
     @Nullable JetType assignmentType,
     @NotNull JetBinaryExpression expression,
     @NotNull ExpressionTypingContext context) {
   if (assignmentType != null
       && !KotlinBuiltIns.getInstance().isUnit(assignmentType)
       && context.expectedType != TypeUtils.NO_EXPECTED_TYPE
       && TypeUtils.equalTypes(context.expectedType, assignmentType)) {
     context.trace.report(Errors.ASSIGNMENT_TYPE_MISMATCH.on(expression, context.expectedType));
     return null;
   }
   return DataFlowUtils.checkStatementType(expression, context);
 }