/// <summary>
        /// Searches for a string in the reverse direction of <see cref="FindForward"/>.
        /// </summary>
        /// <param name="Txt">The text to search for.</param>
        /// <param name="StartLoc">The starting location of the search.</param>
        /// <param name="EndLoc">The ending location of the search.</param>
        /// <param name="Flags">Flags controlling how the searching is conducted.</param>
        /// <param name="Result">Receives the results of the search.</param>
        /// <returns>True if a match was found.</returns>
        private bool FindReverse(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result)
        {
            bool bFound = false;
            bool bMatchWord;
            bool bIsWord;
            StringComparison ComparisonFlags;

            SetupFindState(Txt, ref StartLoc, ref EndLoc, Flags, out Result, out bIsWord, out ComparisonFlags, out bMatchWord);

            for(int CurLineIndex = StartLoc.Line; CurLineIndex >= EndLoc.Line && !bFound; --CurLineIndex)
            {
                if(GetLineLength(CurLineIndex) == 0)
                {
                    continue;
                }

                DocumentLine CurLineBldr = mLines[CurLineIndex];
                string LineTxt;
                int ColumnIndex = 0;

                if(CurLineIndex == StartLoc.Line && StartLoc.Column < GetLineLength(CurLineIndex))
                {
                    LineTxt = CurLineBldr.ToString(0, StartLoc.Column);
                }
                else if(CurLineIndex == EndLoc.Line && EndLoc.Column > 0)
                {
                    LineTxt = CurLineBldr.ToString(EndLoc.Column, CurLineBldr.Length - EndLoc.Column);
                    ColumnIndex = EndLoc.Column;
                }
                else
                {
                    LineTxt = CurLineBldr.ToString();
                }

                int Index = LineTxt.LastIndexOf(Txt, ComparisonFlags);

                if(Index != -1)
                {
                    ColumnIndex += Index;
                    CheckForWholeWord(Txt, ref Result, bMatchWord, ref bFound, bIsWord, CurLineIndex, CurLineBldr, ColumnIndex, Index);
                }
            }

            return bFound;
        }
        /// <summary>
        /// Performs general housekeeping for setting up a search.
        /// </summary>
        /// <param name="Txt">The text to search for.</param>
        /// <param name="StartLoc">The location to begin searching from.</param>
        /// <param name="EndLoc">The location to stop searching at.</param>
        /// <param name="Flags">Flags controlling how the search is performed.</param>
        /// <param name="Result">Receives the resulting location if a match is found.</param>
        /// <param name="bIsWord">Set to true if <paramref name="Txt"/> is a valid word.</param>
        /// <param name="ComparisonFlags">Receives flags controlling how strings are compared.</param>
        /// <param name="bMatchWord">Is set to true if only full words are to be matched.</param>
        private void SetupFindState(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result, out bool bIsWord, out StringComparison ComparisonFlags, out bool bMatchWord)
        {
            Result = FindResult.Empty;

            if(!IsValidTextLocation(StartLoc))
            {
                throw new ArgumentException("StartLoc is an invalid text location!");
            }

            if(!IsValidTextLocation(EndLoc))
            {
                throw new ArgumentException("EndLoc is an invalid text location!");
            }

            if((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse)
            {
                if(StartLoc < EndLoc)
                {
                    throw new ArgumentException("StartLoc must be greater than EndLoc when doing a reverse search!");
                }
            }
            else
            {
                if(StartLoc > EndLoc)
                {
                    throw new ArgumentException("StartLoc must be less than EndLoc when doing a forward search!");
                }
            }

            bMatchWord = (Flags & RichTextBoxFinds.WholeWord) == RichTextBoxFinds.WholeWord;
            bIsWord = IsWord(0, Txt);
            ComparisonFlags = StringComparison.OrdinalIgnoreCase;

            if((Flags & RichTextBoxFinds.MatchCase) == RichTextBoxFinds.MatchCase)
            {
                ComparisonFlags = StringComparison.Ordinal;
            }
        }
 /// <summary>
 /// Finds the first occurence of the specified string within the document if it exists.
 /// </summary>
 /// <param name="Txt">The string to find.</param>
 /// <param name="StartLoc">The position within the document to begin searching.</param>
 /// <param name="EndLoc">The position within the document to end searching.</param>
 /// <param name="Flags">Flags telling the document how to conduct its search.</param>
 /// <param name="Result">The location within the document of the supplied text.</param>
 /// <returns>True if the text was found.</returns>
 public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result)
 {
     if((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse)
     {
         return FindReverse(Txt, ref StartLoc, ref EndLoc, Flags, out Result);
     }
     else
     {
         return FindForward(Txt, ref StartLoc, ref EndLoc, Flags, out Result);
     }
 }
        /// <summary>
        /// Checks to see if a text location is a matching word.
        /// </summary>
        /// <param name="Txt">The text being searched for.</param>
        /// <param name="Result">Receives the result if the text location is a matching word.</param>
        /// <param name="bMatchWord">True if an entire word is to be matched.</param>
        /// <param name="bFound">Set to true if a matching word is found.</param>
        /// <param name="bIsWord">True if <paramref name="Txt"/> is a valid word.</param>
        /// <param name="CurLineIndex">The index of the current line.</param>
        /// <param name="CurLineBldr">The text of the current line.</param>
        /// <param name="ColumnIndex">The character index within the line of text where the matching will begin.</param>
        /// <param name="Index">The index of a match within the range of searchable characters for the current line. The true line index is <paramref name="ColumnIndex"/> + <paramref name="Index"/>.</param>
        private static void CheckForWholeWord(string Txt, ref FindResult Result, bool bMatchWord, ref bool bFound, bool bIsWord, int CurLineIndex, DocumentLine CurLine, int ColumnIndex, int Index)
        {
            int FinalCharIndex = ColumnIndex + Txt.Length;

            if(bMatchWord && bIsWord)
            {
                if((FinalCharIndex >= CurLine.Length || !IsWordCharacter(CurLine[FinalCharIndex]))
                    && (ColumnIndex == 0 || !IsWordCharacter(CurLine[ColumnIndex - 1])))
                {
                    bFound = true;
                }
            }
            else
            {
                bFound = true;
            }

            if(bFound)
            {
                Result.Line = CurLineIndex;
                Result.Column = ColumnIndex;
                Result.Length = Txt.Length;
            }
        }
		/// <summary>
		/// Finds the first occurence of the specified string within the document if it exists.
		/// </summary>
		/// <param name="Txt">The string to find.</param>
		/// <param name="StartLoc">The position within the document to begin searching.</param>
		/// <param name="EndLoc">The position within the document to end searching.</param>
		/// <param name="Flags">Flags telling the document how to conduct its search.</param>
		/// <param name="Result">The location within the document of the supplied text.</param>
		/// <returns>True if the text was found.</returns>
		public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result)
		{
			bool bResult = false;

			if(mDocument == null)
			{
				Result = FindResult.Empty;
			}
			else
			{
				bResult = mDocument.Find(Txt, StartLoc, EndLoc, Flags, out Result);
			}

			if(bResult && (Flags & RichTextBoxFinds.NoHighlight) != RichTextBoxFinds.NoHighlight)
			{
				Select(Result);
			}

			return bResult;
		}
		/// <summary>
		/// Selects a range of text and brings the selection into view.
		/// </summary>
		/// <param name="Range">The location of the selection and its length.</param>
		public void Select(FindResult Range)
		{
			if(mDocument != null)
			{
				TextLocation StartLoc = new TextLocation(Range.Line, Range.Column);

				if(!IsValidTextLocation(StartLoc))
				{
					throw new ArgumentOutOfRangeException("Range");
				}

				TextLocation EndLoc = new TextLocation(Range.Line, Math.Min(Range.Column + Range.Length, mDocument.GetLineLength(Range.Line)));

				Select(StartLoc, EndLoc);
			}
		}
        /// <summary>
        /// Searches for a string in the reverse direction of <see cref="FindForward"/>.
        /// </summary>
        /// <param name="Txt">The text to search for.</param>
        /// <param name="StartLoc">The starting location of the search.</param>
        /// <param name="EndLoc">The ending location of the search.</param>
        /// <param name="Flags">Flags controlling how the searching is conducted.</param>
        /// <param name="Result">Receives the results of the search.</param>
        /// <returns>True if a match was found.</returns>
        private bool FindReverse(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result)
        {
            bool             bFound = false;
            bool             bMatchWord;
            bool             bIsWord;
            StringComparison ComparisonFlags;

            SetupFindState(Txt, ref StartLoc, ref EndLoc, Flags, out Result, out bIsWord, out ComparisonFlags, out bMatchWord);

            for (int CurLineIndex = StartLoc.Line; CurLineIndex >= EndLoc.Line && !bFound; --CurLineIndex)
            {
                if (GetLineLength(CurLineIndex) == 0)
                {
                    continue;
                }

                DocumentLine CurLineBldr = mLines[CurLineIndex];
                string       LineTxt;
                int          ColumnIndex = 0;

                if (CurLineIndex == StartLoc.Line && StartLoc.Column < GetLineLength(CurLineIndex))
                {
                    LineTxt = CurLineBldr.ToString(0, StartLoc.Column);
                }
                else if (CurLineIndex == EndLoc.Line && EndLoc.Column > 0)
                {
                    LineTxt     = CurLineBldr.ToString(EndLoc.Column, CurLineBldr.Length - EndLoc.Column);
                    ColumnIndex = EndLoc.Column;
                }
                else
                {
                    LineTxt = CurLineBldr.ToString();
                }

                int Index = LineTxt.LastIndexOf(Txt, ComparisonFlags);

                if (Index != -1)
                {
                    ColumnIndex += Index;
                    CheckForWholeWord(Txt, ref Result, bMatchWord, ref bFound, bIsWord, CurLineIndex, CurLineBldr, ColumnIndex, Index);
                }
            }

            return(bFound);
        }
        /// <summary>
        /// Performs general housekeeping for setting up a search.
        /// </summary>
        /// <param name="Txt">The text to search for.</param>
        /// <param name="StartLoc">The location to begin searching from.</param>
        /// <param name="EndLoc">The location to stop searching at.</param>
        /// <param name="Flags">Flags controlling how the search is performed.</param>
        /// <param name="Result">Receives the resulting location if a match is found.</param>
        /// <param name="bIsWord">Set to true if <paramref name="Txt"/> is a valid word.</param>
        /// <param name="ComparisonFlags">Receives flags controlling how strings are compared.</param>
        /// <param name="bMatchWord">Is set to true if only full words are to be matched.</param>
        private void SetupFindState(string Txt, ref TextLocation StartLoc, ref TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result, out bool bIsWord, out StringComparison ComparisonFlags, out bool bMatchWord)
        {
            Result = FindResult.Empty;

            if (!IsValidTextLocation(StartLoc))
            {
                throw new ArgumentException("StartLoc is an invalid text location!");
            }

            if (!IsValidTextLocation(EndLoc))
            {
                throw new ArgumentException("EndLoc is an invalid text location!");
            }

            if ((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse)
            {
                if (StartLoc < EndLoc)
                {
                    throw new ArgumentException("StartLoc must be greater than EndLoc when doing a reverse search!");
                }
            }
            else
            {
                if (StartLoc > EndLoc)
                {
                    throw new ArgumentException("StartLoc must be less than EndLoc when doing a forward search!");
                }
            }

            bMatchWord      = (Flags & RichTextBoxFinds.WholeWord) == RichTextBoxFinds.WholeWord;
            bIsWord         = IsWord(0, Txt);
            ComparisonFlags = StringComparison.OrdinalIgnoreCase;

            if ((Flags & RichTextBoxFinds.MatchCase) == RichTextBoxFinds.MatchCase)
            {
                ComparisonFlags = StringComparison.Ordinal;
            }
        }
 /// <summary>
 /// Finds the first occurence of the specified string within the document if it exists.
 /// </summary>
 /// <param name="Txt">The string to find.</param>
 /// <param name="StartLoc">The position within the document to begin searching.</param>
 /// <param name="EndLoc">The position within the document to end searching.</param>
 /// <param name="Flags">Flags telling the document how to conduct its search.</param>
 /// <param name="Result">The location within the document of the supplied text.</param>
 /// <returns>True if the text was found.</returns>
 public bool Find(string Txt, TextLocation StartLoc, TextLocation EndLoc, RichTextBoxFinds Flags, out FindResult Result)
 {
     if ((Flags & RichTextBoxFinds.Reverse) == RichTextBoxFinds.Reverse)
     {
         return(FindReverse(Txt, ref StartLoc, ref EndLoc, Flags, out Result));
     }
     else
     {
         return(FindForward(Txt, ref StartLoc, ref EndLoc, Flags, out Result));
     }
 }