private int InternalLastIndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase)
        {
            Debug.Assert(value != null);
            Debug.Assert(startIndex >= 0);
            Debug.Assert(count <= this.Length - startIndex);

            int matchLength = value.Length;
            int matchChars  = matchLength - 1;

            for (int i = (startIndex + count) - 1; i >= startIndex; i--)
            {
                ASCIIChar curr    = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value[matchChars]) : value[matchChars];
                if (curr == toMatch)
                {
                    matchChars--;
                    if (matchChars == -1)
                    {
                        return(i);
                    }
                    continue;
                }
                matchChars = matchLength - 1;
            }

            return(-1);
        }
        private int InternalIndexOf(ASCIIString value, int startIndex, int count, bool ignoreCase)
        {
            Debug.Assert(value != null);
            Debug.Assert(startIndex >= 0 && startIndex < this.Length);
            Debug.Assert(count <= this.Length - startIndex);

            int matchChars  = 0;
            int matchLength = value.Length;

            for (int i = startIndex; i < startIndex + count; i++)
            {
                ASCIIChar curr    = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value[matchChars]) : value[matchChars];
                if (curr == toMatch)
                {
                    matchChars++;
                    if (matchChars == matchLength)
                    {
                        return(i - (matchLength - 1));
                    }
                    continue;
                }
                matchChars = 0;
            }

            return(-1);
        }
        /// <summary>
        /// Returns a copy of this string converted to lowercase.
        /// </summary>
        public ASCIIString ToLower()
        {
            ASCIIChar[] converted = new ASCIIChar[this.Length];
            for (int i = 0; i < this.Length; i++)
            {
                converted[i] = ASCIIChar.ToLower(this.asciiChars[i]);
            }

            return(new ASCIIString(converted));
        }
        private int InternalLastIndexOf(ASCIIChar value, int startIndex, int count, bool ignoreCase)
        {
            Debug.Assert(startIndex >= 0 && startIndex < this.Length);
            Debug.Assert(count <= this.Length - startIndex);

            ASCIIChar toMatch = ignoreCase ? ASCIIChar.ToLower(value) : value;

            for (int i = (startIndex + count) - 1; i >= startIndex; i--)
            {
                ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                if (curr == toMatch)
                {
                    return(i);
                }
            }

            return(-1);
        }
        private int InternalLastIndexOfAny(ASCIIChar[] anyOf, int startIndex, int count, bool ignoreCase)
        {
            Debug.Assert(anyOf != null && anyOf.Length > 0);
            Debug.Assert(startIndex >= 0 && startIndex < this.Length);
            Debug.Assert(count <= this.Length - startIndex);

            ASCIIChar match0, match1, match2;
            int       startAt = (startIndex + count) - 1;
            int       endAt   = startIndex;

            switch (anyOf.Length)
            {
            case 1:
                Debug.Assert(anyOf != null);

                match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0];

                for (int i = startAt; i >= endAt; i--)
                {
                    ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                    if (curr == match0)
                    {
                        return(i);
                    }
                }
                break;

            case 2:
                Debug.Assert(anyOf != null);

                match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0];
                match1 = ignoreCase ? ASCIIChar.ToLower(anyOf[1]) : anyOf[1];

                for (int i = startAt; i >= endAt; i--)
                {
                    ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                    if (curr == match0 || curr == match1)
                    {
                        return(i);
                    }
                }
                break;

            case 3:
                Debug.Assert(anyOf != null);

                match0 = ignoreCase ? ASCIIChar.ToLower(anyOf[0]) : anyOf[0];
                match1 = ignoreCase ? ASCIIChar.ToLower(anyOf[1]) : anyOf[1];
                match2 = ignoreCase ? ASCIIChar.ToLower(anyOf[2]) : anyOf[2];

                for (int i = startAt; i >= endAt; i--)
                {
                    ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                    if (curr == match0 || curr == match1 || curr == match2)
                    {
                        return(i);
                    }
                }
                break;

            default:
                Debug.Assert(anyOf != null);

                ASCIIChar[] chars = ignoreCase ? anyOf.Select(ASCIIChar.ToLower).ToArray() : anyOf.ToArray();

                for (int i = startAt; i >= endAt; i--)
                {
                    ASCIIChar curr = ignoreCase ? ASCIIChar.ToLower(this[i]) : this[i];
                    if (chars.Contains(curr))
                    {
                        return(i);
                    }
                }
                break;
            }

            return(-1);
        }