public static void CryptoAPI(int keySize, int quantity, int timeout, bool onlyExtractPQ)
        {
            string filename = FileDialogs.SaveDialog();

            if (filename == null)
            {
                return;
            }

            if (keySize % 8 != 0)
            {
                MessageBox.Show("The key size must be a multiple of 8.", "Key size error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }


            StringBuilder fileBuilder = new StringBuilder();
            bool          onlyPrimes  = onlyExtractPQ;

            try
            {
                if (!onlyPrimes)
                {
                    File.AppendAllText(filename, $"<{ElementKeys}>");
                }
                // Timeout
                DateTime quitTime = DateTime.Now.Add(TimeSpan.FromSeconds(timeout));

                int counter   = 0;
                int writeSize = 409600;


                while (counter++ < quantity)
                {
                    if (DateTime.Now > quitTime)
                    {
                        break;
                    }
                    fileBuilder.AppendLine(onlyPrimes ? string.Join(Environment.NewLine, PrivateKeySerializer.GetPrivateKeyPQ(keySize)) : PrivateKeySerializer.GetPrivateKey(keySize));
                    if (fileBuilder.Length > writeSize)
                    {
                        File.AppendAllText(filename, fileBuilder.ToString());
                        fileBuilder.Clear();
                    }
                }
            }
            finally
            {
                if (fileBuilder != null && fileBuilder.Length > 0)
                {
                    File.AppendAllText(filename, fileBuilder.ToString());
                }

                if (!onlyPrimes)
                {
                    File.AppendAllText(filename, $"</{ElementKeys}>");
                }
            }
        }
        public void Begin()
        {
            if (CancelToken.IsCancellationRequested)
            {
                return;
            }

            FilePaths = SearchExtensions.SelectMany(searchPattern => Directory.EnumerateFiles(SearchDirectory, searchPattern, SearchOption.TopDirectoryOnly));
            //FilePaths = Directory.EnumerateFiles(SearchDirectory, SearchExtension, SearchOption.TopDirectoryOnly);

            if (FilePaths == null)
            {
                throw new Exception("No files to process!");
            }

            byte[]         bytes   = new byte[] { };
            ANS1PrivateKey ans1Key = null;
            StringBuilder  output  = new StringBuilder();

            List <string> filesToDelete = new List <string>();

            IEnumerable <string> pathBatch = FilePaths.Take(BatchSize);

            while (pathBatch.Any() && !CancelToken.IsCancellationRequested)
            {
                foreach (string file in pathBatch)
                {
                    bytes = GetEncodedBytes(file);

                    if (bytes == null)
                    {
                        continue;
                    }
                    else if (bytes == EmptyByteArray)
                    {
                        if (DeleteFiles)
                        {
                            filesToDelete.Add(file);
                        }
                    }

                    using (ans1Key = new ANS1PrivateKey(bytes))
                    {
                        ans1Key.ParseBuffer();

                        EncodingUtility.AssertValidRSAPrivateKey(ans1Key);

                        if (ExportOnlyPQ)
                        {
                            PrivateKeySerializer.WritePQDocument(output, ans1Key);
                        }
                        else
                        {
                            PrivateKeySerializer.WriteXMLDocument(output, ans1Key);
                        }

                        bytes = null;

                        if (DeleteFiles)
                        {
                            filesToDelete.Add(file);
                        }
                    }
                }

                File.AppendAllText(OutputFilename, output.ToString());
                output.Clear();
                bytes = null;

                if (DeleteFiles && filesToDelete.Any())
                {
                    foreach (string file in filesToDelete)
                    {
                        File.Delete(file);
                    }
                    filesToDelete.Clear();
                }

                FilePaths = FilePaths.Skip(BatchSize);
                pathBatch = FilePaths.Take(BatchSize);
            }
        }