/// <summary>
 /// Tests whether a feature appears in these features.
 /// This never throws.
 /// </summary>
 /// <param name="this">This enumerable of features.</param>
 /// <param name="f">The expected feature.</param>
 /// <returns>True if the feature exists in these features.</returns>
 public static bool Has(this IEnumerable <VFeature> @this, VFeature f) => @this.Contains(f);
 /// <summary>
 /// Tests whether a feature appears with a maximal version in these features.
 /// This never throws.
 /// </summary>
 /// <param name="this">This enumerable of features.</param>
 /// <param name="f">The expected feature.</param>
 /// <returns>True if the feature exists in these features with the expected version or a lower one.</returns>
 public static bool HasAtMost(this IEnumerable <VFeature> @this, VFeature f)
 {
     return(@this.Any(x => x.Name == f.Name && x.Version <= f.Version));
 }
        /// <summary>
        /// Tests whether a feature name (or a versioned "Name/SVersion") appears in these features.
        /// This never throws.
        /// </summary>
        /// <param name="this">This enumerable of features.</param>
        /// <param name="featureName">The name or the "Name/SVersion".</param>
        /// <returns>True if the feature name or versioned name exists in these features.</returns>
        public static bool Has(this IEnumerable <VFeature> @this, string featureName)
        {
            var f = VFeature.TryParse(featureName);

            return(f.IsValid ? @this.Contains(f) : @this.Any(x => x.Name == featureName));
        }