static void DebugManualMappingDeciphering()
        {
            Console.Write("Text> ");
            string text;

            string input = Console.ReadLine().ToUpper().Replace(" ", "").ToUpper();

            if (input[0] == '\\')
            {
                text = GetTextFromFile(input.Substring(1)).ToUpper();
            }
            else
            {
                text = input;
            }

            Console.Write("Key Length> ");
            int keyLength = int.Parse(Console.ReadLine());

            string _;

            ManualMappingDeciphering.RunDeciphering(text, keyLength, out _);
        }
        static void ReleaseMain(string[] args)
        {
            Console.Write("Text> ");
            string text;

            string input = Console.ReadLine().ToUpper().Replace(" ", "").ToUpper();

            if (input[0] == '\\')
            {
                text = GetTextFromFile(input.Substring(1)).ToUpper();
            }
            else
            {
                text = input;
            }

            foreach (char c in text)
            {
                if (!validCharacters.Contains(c))
                {
                    Console.WriteLine($"Error: Invalid character in text ({c})");
                    return;
                }
            }

            int keyLengthSelection = KeyLengthSelection(text);

            Console.Write("Automatically decipher text (0/1)?> ");
            bool autoDecipher = int.Parse(Console.ReadLine()) != 0;

            if (autoDecipher)
            {
                string[] offsetTextSelections = FrequencyAnalysis.SplitTextByOffset(text, keyLengthSelection);

                string[] decipheredStrings = new string[offsetTextSelections.Length];
                int[]    shiftAmounts      = new int[offsetTextSelections.Length];

                for (int i = 0; i < decipheredStrings.Length; i++)
                {
                    string selection = offsetTextSelections[i];

                    double _;
                    Dictionary <char, double> selectionProportions = FrequencyAnalysis.CharFrequencyToCharProportion(FrequencyAnalysis.GetTextCharFrequency(selection));
                    Dictionary <char, char>   optimalMapping       = FrequencyAnalysis.GetOptimalCharacterMapping(selectionProportions,
                                                                                                                  EnglishLetterFrequency.GetLetterProportions(),
                                                                                                                  out _,
                                                                                                                  out shiftAmounts[i]);

                    decipheredStrings[i] = FrequencyAnalysis.DecipherTextByMapping(selection, optimalMapping);
                }

                string fullDeciphering = FrequencyAnalysis.ReconstructTextFromOffsetSelections(decipheredStrings);

                Console.WriteLine("Keyword: " + ProgramMath.GetKeywordFromOffsets(shiftAmounts));
                Console.WriteLine("Deciphered Text:");
                Console.WriteLine(fullDeciphering);
            }
            else
            {
                string keyword;
                string fullDeciphering = ManualMappingDeciphering.RunDeciphering(text,
                                                                                 keyLengthSelection,
                                                                                 out keyword);

                Console.WriteLine("Keyword: " + keyword);
                Console.WriteLine("Deciphered Text:");
                Console.WriteLine(fullDeciphering);
            }
        }