Retain separate versions for 'strictly' and 'prefers' Previously, a `strictly` version constraint was translated into a separate 'prefer' and 'reject' constraint: this is how it was processed internally, as well as how it was represented in a `.module` file.
With this change, strict version constraints are logically retained as a first class version constraint: - `.module` files can have versions declared with `strictly` - Strict constraints are only translated to a reject version selector as part of resolution (not when parsing the constraint)
Ensure MutableVersionConstraint does not have null preferredVersion While the interface for `VersionConstraint` declared that version was `@Nullable`, in reality we prevented this when constructing an immutable version constraint. This meant that `MutableVersionConstraint.asImmutable()` converted null values to empty strings.
This changes the contract so that `VersionConstraint.preferredVersion` is no longer `@Nullable`, and an empty string is consistently used to define a 'missing' preferred version, for all implementations of `VersionConstraint`.