/// <summary>
        /// Explores the input (sub-)space. Each invocation may return a different set.
        /// </summary>
        /// <returns>
        /// All valid combinations of values from the dimensions.
        /// </returns>
        /// <exception cref="DimensionStrategyNotSetException">Any dimension found with no corresponding strategy.</exception>
        public override IEnumerable <Vector> Explore()
        {
            if (TargetMatrix.Dimensions.Count == 0)
            {
                return(Enumerable.Empty <Vector>());               // No dimensions to explore
            }
            ReadOnlyCollection <DimensionWithValues> dimensionValues = GetAllDimensionValues();

            return(CombinatorialUtilities.EnumerateAllVectors(dimensionValues).Where(IsValidVector));
        }
        private static ExtendedConstraint ExtendConstraint(IConstraint constraint, ReadOnlyCollection <DimensionWithValues> dimensionValues)
        {
            List <int> dimensionIndexes = GetDimensionIndexes(constraint, dimensionValues).ToList();

            if (dimensionIndexes.Count == 0)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                  "Constraint {0} doesn't have any required dimensions.", constraint.GetType().Name));
            }
            ReadOnlyCollection <DimensionWithValues> dimensionValuesSubset = dimensionIndexes.Select(di => dimensionValues[di]).ToList().AsReadOnly();
            ExtendedConstraint ret = new ExtendedConstraint(dimensionIndexes, dimensionValues);

            foreach (ReadOnlyCollection <int> indexes in CombinatorialUtilities.GetAllIndexCombinations(dimensionValuesSubset.Select(dv => dv.Values.Count)))
            {
                Vector v = CombinatorialUtilities.ConstructVector(dimensionValuesSubset, indexes);
                if (constraint.IsValid(v))
                {
                    ret.AddNewValueCombinations(indexes);
                }
            }
            return(ret);
        }
            protected override bool IsValid(IEnumerable <int> combination)
            {
                Vector v = CombinatorialUtilities.ConstructVector(_dimensionValuesSubset, combination.ToList().AsReadOnly());

                return(_constraint.IsValid(v));
            }