/// <summary>
        /// Creates the elfie indexes.
        /// </summary>
        async Task CreateIndex(Catalog2ElfieOptions options, CancellationToken cancellationToken)
        {
            // The NuGet service catalog root.
            Uri nugetServicesUri = new Uri(options.Source);

            // The list of NuGet service endpoints.
            NugetServiceEndpoints nugetServiceUrls = new NugetServiceEndpoints(new Uri(options.Source));

            // The storage object responsible for loading and saving files from storage.
            Storage storage = options.StorageFactory.Create();
            Uri downloadCountsUri = new Uri(options.DownloadSource);

            ElfieFromCatalogCollector collector = new ElfieFromCatalogCollector(options.IndexerVersion, options.MergerVersion, nugetServiceUrls, downloadCountsUri, options.DownloadPercentage, storage, options.MaxThreads, options.TempPath);

            int reties = 3;
            for (int attempt = 0; attempt < reties; attempt++)
            {
                bool success = await collector.Run(cancellationToken);

                // The collector returns true if it successfully created the indexes,
                // returns false if it couldn't create the indexes, but the error is transient,
                // throws an exception if it encounters an unrecoverable error.
                if (success)
                {
                    break;
                }
                else
                {
                    // Wait for a few seconds before retrying.
                    int delay = (int)Math.Pow(15, reties);
                    Thread.Sleep(delay * 1000);
                }
            }
        }
        public static Catalog2ElfieOptions FromArgs(string[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            IDictionary<string, string> arguments = CommandHelpers.GetArguments(args, 1);

            if (arguments == null)
            {
                throw new ArgumentOutOfRangeException("args", "Invalid command line arguments.");
            }

            bool verbose = CommandHelpers.GetVerbose(arguments);
            Version indexerVersion = CommandHelpers.GetIndexerVersion(arguments);
            Version mergerVersion = CommandHelpers.GetMergerVersion(arguments);
            string source = CommandHelpers.GetSource(arguments);
            string downloadSource = CommandHelpers.GetDownloadSource(arguments);
            double downloadPercentage = CommandHelpers.GetDownloadPercentage(arguments);
            IStorageFactory storageFactory = CommandHelpers.CreateStorageFactory(arguments, verbose);
            int interval = CommandHelpers.GetInterval(arguments);
            int maxThreads = CommandHelpers.GetMaxThreads(arguments);
            string tempPath = CommandHelpers.GetTempPath(arguments);

            Catalog2ElfieOptions options = new Catalog2ElfieOptions(indexerVersion, mergerVersion, source, downloadSource, downloadPercentage, storageFactory, maxThreads, tempPath, verbose);
            options.Validate();

            return options;
        }