/// <summary>
        /// Run a specific sieve using the provided parameters.
        /// </summary>
        /// <param name="sieve">The sieve to run, as determined by a combination of properties.</param>
        /// <param name="settings">The running parameters to use.</param>
        /// <exception cref="ArgumentException">If no sieve class matching the requested sieve can be found, an exception will be thrown.</exception>
        private static void Run(SieveProperty sieve, SettingsV2 settings)
        {
            Func <ISieveRunner> createSieve = GetSieveCreator(sieve, settings)
                                              ?? throw new ArgumentException($"Unable to run sieve: {sieve}", nameof(sieve));

            var demo = createSieve();

            Console.WriteLine($"@Kinematics: Starting ({demo.Description}{(settings.MultiThreaded ? " (multithreaded)" : "")})...");

            long millisecondsToRun = settings.SecondsToRun * MillisecondsPerSecond;

            Stopwatch watch = new();

            var(completedSieve, passes) = settings.MultiThreaded switch
            {
                false => RunSingleThread(createSieve, watch, millisecondsToRun, settings),
                true => RunMultiThread(createSieve, watch, millisecondsToRun, settings),
            };

            if (completedSieve is null)
            {
                Console.WriteLine("Invalid state after run.");
                return;
            }

            PrintResults(completedSieve, passes, watch, settings);
        }
 /// <summary>
 /// Function to translate sieve property presets into functions to create a sieve object.
 /// </summary>
 /// <param name="sieve">The sieve requested.</param>
 /// <param name="settings">The settings to be used during the sieve's run.</param>
 /// <returns>Returns a function to create an instance of the requested sieve.</returns>
 private static Func <ISieveRunner>?GetSieveCreator(SieveProperty sieve, SettingsV2 settings)
 {
     return(sieve switch
     {
         SievePropertyCombinations.Bit2 => () => new Bit2Sieve(settings.SieveSize),
         SievePropertyCombinations.Bit2While => () => new Bit2WhileSieve(settings.SieveSize),
         SievePropertyCombinations.Bit6 => () => new Bit6Sieve(settings.SieveSize),
         SievePropertyCombinations.Bit30 => () => new Bit30Sieve(settings.SieveSize),
         SievePropertyCombinations.Bool2 => () => new Bool2Sieve(settings.SieveSize),
         SievePropertyCombinations.Bool2While => () => new Bool2WhileSieve(settings.SieveSize),
         SievePropertyCombinations.Bool6 => () => new Bool6Sieve(settings.SieveSize),
         SievePropertyCombinations.Bool30 => () => new Bool30Sieve(settings.SieveSize),
         SievePropertyCombinations.InvBool2 => () => new InvBool2Sieve(settings.SieveSize),
         SievePropertyCombinations.InvBool2While => () => new InvBool2WhileSieve(settings.SieveSize),
         SievePropertyCombinations.InvBool6 => () => new InvBool6Sieve(settings.SieveSize),
         SievePropertyCombinations.InvBool30 => () => new InvBool30Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolB2 => () => new PoolB2Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolD2 => () => new PoolD2Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolQ2 => () => new PoolQ2Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolB6 => () => new PoolB6Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolD6 => () => new PoolD6Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolQ6 => () => new PoolQ6Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolB30 => () => new PoolB30Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolD30 => () => new PoolD30Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolQ30 => () => new PoolQ30Sieve(settings.SieveSize),
         SievePropertyCombinations.PoolQ30M => () => new PoolQ30MSieve(settings.SieveSize),
         SievePropertyCombinations.PoolQ2M => () => new PoolQ2MSieve(settings.SieveSize),
         SievePropertyCombinations.RawB2 => () => new RawB2Sieve(settings.SieveSize),
         SievePropertyCombinations.RawD2 => () => new RawD2Sieve(settings.SieveSize),
         SievePropertyCombinations.RawQ2 => () => new RawQ2Sieve(settings.SieveSize),
         SievePropertyCombinations.RawB6 => () => new RawB6Sieve(settings.SieveSize),
         SievePropertyCombinations.RawD6 => () => new RawD6Sieve(settings.SieveSize),
         SievePropertyCombinations.RawQ6 => () => new RawQ6Sieve(settings.SieveSize),
         SievePropertyCombinations.RawB30 => () => new RawB30Sieve(settings.SieveSize),
         SievePropertyCombinations.RawD30 => () => new RawD30Sieve(settings.SieveSize),
         SievePropertyCombinations.RawQ30 => () => new RawQ30Sieve(settings.SieveSize),
         SievePropertyCombinations.RawQ30M => () => new RawQ30MSieve(settings.SieveSize),
         _ => null
     });