/// <summary>
        /// Prepares textmode to be used
        /// </summary>
        /// <param name="prompt"></param>
        /// <param name="onEnter">What happens when enter is pressed?</param>
        /// <param name="keydown">Custom keydown event. <see cref="Interactive.DefaultKeydown(string, ref string, ref int, ConsoleKeyInfo)"/> is used if no keydown is specified(null)</param>
        /// <param name="SpecialCaseHandler"></param>
        private void TextModeWrapper(string prompt, Action <string> onEnter, keydownAction keydown = null, Action <ConsoleKeyInfo> SpecialCaseHandler = null)
        {
            var tT = "";

            getPromptText = () => prompt + tT;
            var typedIndex = 0;

            if (keydown == null)
            {
                keydown = DefaultKeydown;
            }
            onQueryModeKeyPress = (k) => TextInputMode(k, prompt, ref tT, ref typedIndex, onEnter, keydown, SpecialCaseHandler);
        }
 /// <summary>
 /// Switches the input into Password mode.
 /// <para>
 /// This means typed characters won't be visible but instead substituted by <paramref name="disguiseChar"/>.</para>
 /// Passwords won't be stored in memory by the password mode, instead a <paramref name="storeChar"/> function
 /// has to be specified, which should store them safely and only as temporarily as possible.
 /// Adding the char to a <see cref="System.Security.SecureString"/> is a good implementation.
 /// </summary>
 /// <param name="prompt">current prompt</param>
 /// <param name="onEnter">What happens on enter press?</param>
 /// <param name="storeChar">Char storage function. Try to avoid <see cref="string"/>s</param>
 /// <param name="disguiseChar">the char to display instead of the actual character. defaults to *</param>
 /// <param name="keydown">Custom keydown event. A secure default implementation is used, if no custom keydown is specified(null)</param>
 /// <param name="SpecialCaseHandler"></param>
 private void PasswordModeWrapper(string prompt, Action <string> onEnter, Action <char> storeChar, char disguiseChar = '*', keydownAction keydown = null, Action <ConsoleKeyInfo> SpecialCaseHandler = null)
 {
     if (keydown == null)
     {
         keydown = (string p, ref string tT, ref int tI, ConsoleKeyInfo k) => {
             if (tI != tT.Length)
             {
                 HideStr(p, tT);
             }
             tT = tT.Insert(tI, disguiseChar.ToString());
             tI++;
             if (tI == tT.Length)
             {
                 Console.Write(disguiseChar.ToString());
             }
             else
             {
                 Console.Write(tT);
                 Console.CursorLeft = p.Length + tI;
             }
             storeChar?.Invoke(k.KeyChar);
         }
     }
     ;
     TextModeWrapper(prompt, onEnter, keydown, SpecialCaseHandler);
 }
        /// <summary>
        /// TextInputMode is for accepting general text using the <see cref="keydownAction"/> delegate
        /// </summary>
        /// <param name="k">pressed key</param>
        /// <param name="prompt">current prompt</param>
        /// <param name="typedText">previously typed text</param>
        /// <param name="typedIndex">cursorindex</param>
        /// <param name="onEnter"></param>
        /// <param name="keydown">Custom keydown event</param>
        /// <param name="SpecialCaseHandler">Add Custom keyhandlers here. Will always be called</param>
        private static void TextInputMode(ConsoleKeyInfo k, string prompt, ref string typedText, ref int typedIndex, Action <string> onEnter, keydownAction keydown, Action <ConsoleKeyInfo> SpecialCaseHandler = null)
        {
            var ch = k.KeyChar;

            switch (k.Key)
            {
            case ConsoleKey.Enter: {
                onEnter(typedText);
                break;
            }

            case ConsoleKey.Backspace:
                if (typedText.Length != 0)
                {
                    typedText = typedText.Remove(typedIndex - 1, 1);
                    typedIndex--;
                    if (typedIndex != typedText.Length)
                    {
                        HideStr(prompt, typedText);
                        Console.Write(typedText);
                        Console.CursorLeft = prompt.Length + typedIndex;
                    }
                    else
                    {
                        Console.Write(backspace);
                    }
                }
                else
                {
                    Beep();
                }
                break;

            case ConsoleKey.Delete:
                if (typedIndex != typedText.Length && typedText.Length != 0)
                {
                    typedText = typedText.Remove(typedIndex, 1);
                    HideStr(prompt, typedText);
                    Console.Write(typedText);
                    Console.CursorLeft = prompt.Length + typedIndex;
                }
                else
                {
                    Beep();
                }
                break;

            case ConsoleKey.Escape:
                HideStr(prompt, typedText);
                typedText  = "";
                typedIndex = 0;
                break;

            case ConsoleKey.LeftArrow:
                if (typedIndex == 0)
                {
                    Beep();
                }
                else
                {
                    typedIndex--;
                    Console.CursorLeft = prompt.Length + typedIndex;
                }
                break;

            case ConsoleKey.RightArrow:
                if (typedIndex >= typedText.Length)
                {
                    Beep();
                }
                else
                {
                    typedIndex++;
                    Console.CursorLeft = prompt.Length + typedIndex;
                }
                break;

            default:
                keydown(prompt, ref typedText, ref typedIndex, k);
                break;
            }
            SpecialCaseHandler?.Invoke(k);
        }