private static boolean kmTypesEqual(KmType t1, KmType t2) {
    // todo: can be removed when KmType properly defines equals() and hashCode()
    if (t1 == null) { 
      return t2 == null;
    }
    return t2 != null
      && Attributes.isNullable(t1) == Attributes.isNullable(t2)
      && Objects.equals(t1.getClassifier(), t2.getClassifier())
      && kmTypesEqual(t1.getOuterType(), t2.getOuterType())
      && Iterators.equals(t1.getArguments(), t2.getArguments(), KotlinMeta::kmTypeProjectionEquals);
  }
private static boolean kmTypesEqual(KmType t1, KmType t2)