Normalize `ModuleIdentifier` This commit reworks the `ComponentModuleIdentifier`/`ComponentModuleSelector`/`ModuleVersionSelector` classes to use `ModuleIdentifier` under the hood, instead of storing denormalized strings. This has the advantage that we can reduce the use of the module identifier factory, which is called very often during dependency resolution. Sharing instances reduces the need for conversions, and makes comparisons faster.
Associate rejected versions with their constraint or rule This commit reworks the mapping between rejected versions and version selectors, so that we can make the difference between a version which was rejected by a selector (regular or constraint) or a rule. Then the dependency insight report can properly show what versions were rejected in which context.