public static Dialog CreateDialog(Action okAction)
        {
            PasswordGeneratorState state = new PasswordGeneratorState();

            var ok = new Button(3, 14, LocMan.Get("Ok"));

            ok.Clicked += () => { okAction.Invoke(); };

            var dialog = new Dialog(LocMan.Get("🎲 Random Password Generator"), 60, 20, ok);

            var passwordLengthLabel = new Label(1, 1, LocMan.Get("Password length:"));

            var positiveNumbersOnlyProvider = new TextRegexProvider("^[1-9]+[0-9]$")
            {
                ValidateOnInput = true
            };
            var passwordLengthTextField = new TextValidateField(positiveNumbersOnlyProvider)
            {
                X      = 1,
                Y      = 2,
                Width  = 4,
                Height = 1
            };

            passwordLengthTextField.Text = state.PasswordLength.ToString();


            var useUppercase = new CheckBox(1, 4, "Upper-case latin characters (e.g. A, C, K, Z)", state.IncludeUpperCaseLatinLetters);

            useUppercase.Toggled += (bool old) => { state.IncludeUpperCaseLatinLetters = !old; };

            var useLowercase = new CheckBox(1, 5, "Lower-case latin characters (e.g. a, c, k, z)", state.IncludeLowerCaseLatinLetters);

            useLowercase.Toggled += (bool old) => { state.IncludeLowerCaseLatinLetters = !old; };

            var useDigits = new CheckBox(1, 6, "Digits (e.g. 4, 6, 9)", state.IncludeDigits);

            useDigits.Toggled += (bool old) => { state.IncludeDigits = !old; };

            var useSpecialASCII = new CheckBox(1, 7, "Special characters ASCII", state.IncludeSpecialCharactersASCII);

            useSpecialASCII.Toggled += (bool old) => { state.IncludeSpecialCharactersASCII = !old; };

            var useBasicEmojis = new CheckBox(1, 8, "Basic emoji (e.g. 😊)", state.IncludeEmojis);

            useBasicEmojis.Toggled += (bool old) => { state.IncludeEmojis = !old; };


            var generatedPasswordLabel = new Label(1, 10, LocMan.Get("Generated password:"******"")
            {
                ReadOnly = true,
                X        = 1,
                Y        = 11,
                Width    = Dim.Fill(),
                Height   = 1
            };


            var copyToClipboardButton = new Button(3, 12, LocMan.Get("Copy to Clipboard"));

            var generateButton = new Button(25, 12, LocMan.Get("Generate"));

            generateButton.Clicked += () => { GenerateRandomPassword(state); generatedPasswordField.Text = state.GeneratedPassword; };

            dialog.Add(passwordLengthLabel, passwordLengthTextField, useUppercase, useLowercase, useDigits, useSpecialASCII, useBasicEmojis, generatedPasswordLabel, generatedPasswordField, copyToClipboardButton, generateButton);

            return(dialog);
        }
        private static void GenerateRandomPassword(PasswordGeneratorState state)
        {
            List <string> generated = new List <string>(state.PasswordLength);

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

            using (var generator = RandomNumberGenerator.Create())
            {
                if (state.IncludeUpperCaseLatinLetters)
                {
                    int index = GetPositiveRandomInt(generator) % upperCaseLatinLetters.Count;
                    generated.Add(upperCaseLatinLetters[index].ToString());
                    possibleChars.AddRange(Array.ConvertAll <char, string>(upperCaseLatinLetters.ToArray(), element => element.ToString()));
                }

                if (state.IncludeLowerCaseLatinLetters)
                {
                    int index = GetPositiveRandomInt(generator) % lowerCaseLatinLetters.Count;
                    generated.Add(lowerCaseLatinLetters[index].ToString());
                    possibleChars.AddRange(Array.ConvertAll <char, string>(lowerCaseLatinLetters.ToArray(), element => element.ToString()));
                }

                if (state.IncludeDigits)
                {
                    int index = GetPositiveRandomInt(generator) % digits.Count;
                    generated.Add(digits[index].ToString());
                    possibleChars.AddRange(Array.ConvertAll <char, string>(digits.ToArray(), element => element.ToString()));
                }

                if (state.IncludeSpecialCharactersASCII)
                {
                    int index = GetPositiveRandomInt(generator) % specialCharactersASCII.Count;
                    generated.Add(specialCharactersASCII[index].ToString());
                    possibleChars.AddRange(Array.ConvertAll <char, string>(specialCharactersASCII.ToArray(), element => element.ToString()));
                }

                if (state.IncludeEmojis)
                {
                    if (emoticonsUnicodeBlock.Count < 1)
                    {
                        ConstructEmojiList();
                    }

                    int index = GetPositiveRandomInt(generator) % emoticonsUnicodeBlock.Count;
                    generated.Add(emoticonsUnicodeBlock[index]);
                    possibleChars.AddRange(emoticonsUnicodeBlock);
                }

                // Reorder all possible chars
                possibleChars = possibleChars.OrderBy(x => GetPositiveRandomInt(generator)).ToList();

                while (generated.Count < state.PasswordLength)
                {
                    int index = GetPositiveRandomInt(generator) % possibleChars.Count;
                    generated.Add(possibleChars[index]);
                }

                // Reorder all generated chars
                generated = generated.OrderBy(x => GetPositiveRandomInt(generator)).ToList();
            }

            state.GeneratedPassword = string.Join("", generated);             //  new String( generated.ToArray());
        }