/// <summary>
        /// Converts the provided text from l33t format to plain text
        /// </summary>
        /// <param name="l33t">The encoded text to parse</param>
        /// <param name="level">Specifies the replacement level to use</param>
        /// <param name="replacements">The list to use when decoding the provided text with <see cref="L33tLevel.Custom"/></param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public static IEnumerable <string> Decode(string l33t, L33tLevel level, IEnumerable <L33tReplacement> replacements = null)
        {
            // Validate inputs
            if (string.IsNullOrEmpty(l33t))
            {
                throw new ArgumentNullException(nameof(l33t), "Must provide l33t text to decode");
            }

            if (level > L33tLevel.Custom)
            {
                throw new ArgumentException($"Invalid {nameof(L33tLevel)} specified", nameof(level));
            }

            if (level == L33tLevel.Custom && replacements == null)
            {
                throw new ArgumentNullException(nameof(replacements), $"Must provide replacements list when using custom {nameof(L33tLevel)}");
            }

            // Run appropriate decoder
            return(level switch
            {
                L33tLevel.Basic => Decode(l33t, BasicReplacements),
                L33tLevel.Intermediate => Decode(l33t, BasicReplacements.Concat(IntermediateReplacements)),
                L33tLevel.Advanced => Decode(l33t, BasicReplacements.Concat(IntermediateReplacements).Concat(AdvancedReplacements)),
                L33tLevel.Custom => Decode(l33t, replacements),
                _ => throw new ArgumentException($"Invalid {nameof(L33tLevel)} specified", nameof(level))
            });
        /// <summary>
        /// Returns the full collection of l33t replacements for the specified level
        /// </summary>
        /// <param name="level">The dictionary level to return</param>
        /// <exception cref="ArgumentException"></exception>
        public static IEnumerable <L33tReplacement> GetReplacements(L33tLevel level)
        {
            if (level >= L33tLevel.Custom)
            {
                throw new ArgumentException($"Must specify {nameof(L33tLevel)} lower than custom", nameof(level));
            }

            var replacements = BasicReplacements
                               .Concat(IntermediateReplacements)
                               .Concat(AdvancedReplacements);

            return(replacements
                   .Where(x => x.Level <= level));
        }