/// <summary>
        /// Attempts to Parse a string representing a Hotkeys.
        /// </summary>
        /// <param name="s">The Hotkeys to Parse</param>
        /// <param name="hks">The <see cref="AhkHotkeys"/> that represents the parsed results</param>
        /// <returns>
        /// Returns True if the parse was successful; Otherwise false
        /// </returns>
        public static bool TryParse(string s, out HotkeyKeys hks)
        {
            bool       retval = false;
            HotkeyKeys outHks = null;

            try
            {
                HotkeyKeys hk = HotkeyKeys.Parse(s);
                outHks     = new HotkeyKeys();
                outHks.Alt = hk.Alt;
                // outHks.Combine = hk.Combine;
                outHks.Ctrl        = hk.Ctrl;
                outHks.InstallHook = hk.InstallHook;
                outHks.Key1        = hk.Key1;
                outHks.Key2        = hk.Key2;
                outHks.Left        = hk.Left;
                outHks.NativeBlock = hk.NativeBlock;
                outHks.Right       = hk.Right;
                outHks.Shift       = hk.Shift;
                outHks.UP          = hk.UP;
                outHks.WildCard    = hk.WildCard;
                outHks.Win         = hk.Win;
                retval             = true;
            }
            catch (Exception)
            {
            }
            hks = outHks;
            return(retval);
        }
        /// <summary>
        /// Parses a Hotkeys From a string value
        /// </summary>
        /// <param name="s">The Hotkeys to Parse</param>
        /// <returns>
        /// An instance of <see cref="HotkeyKeys"/> if the parse was successful.
        /// </returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="HotKeyFormatInvalidException"></exception>
        /// <exception cref="HotkeysCombineException">
        /// If <paramref name="s"/> contains more than one <see cref="AhkHotkeys.CombineString"/> or
        /// if left or right of <see cref="AhkHotkeys.CombineString"/> is not the correct type of value.
        /// </exception>
        /// <exception cref="KeyNotSupportedException">
        /// If any of the keys are not a key found in <see cref="HotkeysEnum"/>.
        /// </exception>
        public static HotkeyKeys Parse(string s)
        {
            if (string.IsNullOrWhiteSpace(s))
            {
                throw new ArgumentNullException();
            }
            HotkeyKeys retval = new HotkeyKeys();
            // by splitting we can get how many modifier there are at the start of the string.
            var Sections = s.Split(new char[] { AhkHotkeys.Alt
                                                , AhkHotkeys.Shift
                                                , AhkHotkeys.Ctrl
                                                , AhkHotkeys.Win
                                                , AhkHotkeys.Left
                                                , AhkHotkeys.Right
                                                , AhkHotkeys.WildCard
                                                , AhkHotkeys.InstallHook
                                                , AhkHotkeys.NativeBlock });
            int iPrefexLength = 0;

            foreach (var str in Sections)
            {
                if (string.IsNullOrEmpty(str))
                {
                    iPrefexLength++;
                }
                else
                {
                    break;
                }
            }
            // iPrefexLength now contains the number of modifiers in the hotkey
            // Get the Modifiers and assign the to retval
            if (iPrefexLength > 0)
            {
                string Mod = s.Substring(0, iPrefexLength);

                if (Mod.IndexOf(AhkHotkeys.Alt) >= 0)
                {
                    retval.Alt = true;
                }
                if (Mod.IndexOf(AhkHotkeys.Ctrl) >= 0)
                {
                    retval.Ctrl = true;
                }
                if (Mod.IndexOf(AhkHotkeys.InstallHook) >= 0)
                {
                    retval.InstallHook = true;
                }
                if (Mod.IndexOf(AhkHotkeys.Left) >= 0)
                {
                    retval.Left = true;
                }
                if (Mod.IndexOf(AhkHotkeys.NativeBlock) >= 0)
                {
                    retval.NativeBlock = true;
                }
                if (Mod.IndexOf(AhkHotkeys.Right) >= 0)
                {
                    retval.Right = true;
                }
                if (Mod.IndexOf(AhkHotkeys.Shift) >= 0)
                {
                    retval.Shift = true;
                }
                if (Mod.IndexOf(AhkHotkeys.WildCard) >= 0)
                {
                    retval.WildCard = true;
                }
                if (Mod.IndexOf(AhkHotkeys.Win) >= 0)
                {
                    retval.Win = true;
                }
            }

            string NoMod = s;

            if (iPrefexLength > 0 && s.Length > iPrefexLength)
            {
                NoMod = s.Substring(iPrefexLength);
            }
            if (NoMod.Length == 0)
            {
                throw new HotKeyFormatInvalidException(Properties.Resources.HotKeyFormatInvalidExceptionMissingTriggerKey);
            }

            // NoMod now contains is the remainder of the hotkey without any modifier keys.
            // Now we need to check for the UP modifier
            if (NoMod.Length > 3)
            {
                if (NoMod.EndsWith(AhkHotkeys.UpString, StringComparison.CurrentCultureIgnoreCase))
                {
                    retval.UP = true;
                    NoMod     = NoMod.Substring(0, NoMod.Length - AhkHotkeys.UpString.Length);
                }
            }
            // If NoMod had a up modifier has been removed at this point
            // Now we need to check for combine key (&)

            bool comb = false;

            if (NoMod.Length > 2 && NoMod.IndexOf(AhkHotkeys.Combine) >= 0)
            {
                comb = true;
            }

            // I am thinking that combine when used on a hotkey that does support Combining but does have two single keys
            // should automatically become a multi-key hotkey; such as ^a & s
            // If this works out then all existing multi-key hotkeys need to be converted from format ^ab to ^a & b
            // If the HotKey can combine is false but combine is true then it is a multi key

            if (comb == true)
            {
                // Splitting with RemoveEmptyEntries will ignore whitespace on either side of the & so C   & f are the same as c&f
                var keys = NoMod.Split(new char[] { AhkHotkeys.Combine }, StringSplitOptions.RemoveEmptyEntries);
                if (keys.Length > 2)
                {
                    throw new HotkeysCombineException(Properties.Resources.HotkeysCombineExceptionTooManyKeys);
                }
                if (keys.Length < 2)
                {
                    throw new HotkeysCombineException(Properties.Resources.HotkeysCombineExceptionToFiewKeys);
                }

                HotkeysEnum k1 = HotkeysEnum.None;
                if (Enum.TryParse <HotkeysEnum>(keys[0], true, out k1) == false)
                {
                    throw new KeyNotSupportedException(string.Format(Properties.Resources.KeyNotSupportedExceptionDefault
                                                                     , keys[0]));
                }
                retval.Key1 = k1;

                HotkeysEnum k2 = HotkeysEnum.None;
                if (Enum.TryParse <HotkeysEnum>(keys[1], true, out k2) == false)
                {
                    throw new KeyNotSupportedException(string.Format(Properties.Resources.KeyNotSupportedExceptionDefault
                                                                     , keys[1]));
                }
                retval.Key2 = k2;
            }
            else
            {
                HotkeysEnum kk = HotkeysEnum.None;
                if (Enum.TryParse <HotkeysEnum>(NoMod, true, out kk) == false)
                {
                    throw new KeyNotSupportedException(string.Format(Properties.Resources.KeyNotSupportedExceptionDefault
                                                                     , NoMod));
                }
                retval.Key1 = kk;
            }

            if (retval.IsValid == false)
            {
                throw new HotKeyFormatInvalidException(Properties.Resources.HotKeyFormatInvalidExceptionInvalidCombination);
            }
            return(retval);
        }