/// <summary>
 /// Equality is based on an exact match of <see cref="Kind"/> and <see cref="NullableProfile"/>
 /// but also handles the case when one of the two is oblivious of NRT and the other is <see cref="NullablityTypeKindExtension.IsNRTFullNullable(NullabilityTypeKind)"/>.
 /// </summary>
 /// <param name="other">The other info.</param>
 /// <returns>True if this is equal to other, false otherwise.</returns>
 public bool Equals(NullabilityTypeInfo other)
 {
     Debug.Assert(Kind != other.Kind || ((_profile == null) == (other._profile == null)), "If Kind are equals then both have a profile or not.");
     // Strict equality.
     if (Kind == other.Kind &&
         (_profile == null || _profile.SequenceEqual(other._profile !)))
     {
         return(true);
     }
     // Basic type properties must be the same.
     if ((Kind & (~NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable)) != (other.Kind & (~NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable)))
     {
         return(false);
     }
     // If this is a Full NRT nullable and the other is not NRT aware it is necessarily nullable since this is a reference type and
     // other has the same basic type kind, it is nullable by default.
     if (Kind.IsNRTFullNullable() && !other.Kind.IsNRTAware())
     {
         Debug.Assert(other.Kind.IsReferenceType() && other.Kind.IsNullable());
         return(true);
     }
     // Reverse the previous check.
     if (other.Kind.IsNRTFullNullable() && !Kind.IsNRTAware())
     {
         Debug.Assert(Kind.IsReferenceType() && Kind.IsNullable());
         return(true);
     }
     return(false);
 }