/// <summary>
        /// Implements the "Before_Dot" condition
        ///
        /// Specification: C is followed by <code>U+0307 COMBINING DOT ABOVE</code>.
        /// Any sequence of characters with a combining class that is
        /// neither 0 nor 230 may intervene between the current character
        /// and the combining dot above.
        ///
        /// Regular Expression:
        ///   After C: ([{cc!=230}&{cc!=0}])*[\u0307]
        /// </summary>
        private static bool IsBeforeDot(String src, int index)
        {
            int ch;
            int cc;
            int len = src.Length();

            // Look for a following COMBINING DOT ABOVE
            for (int i = index + Character.CharCount(src.CodePointAt(index)); i < len; i += Character.CharCount(ch))
            {
                ch = src.CodePointAt(i);

                if (ch == '\u0307')
                {
                    return(true);
                }
                else
                {
                    cc = Normalizer.getCombiningClass(ch);
                    if ((cc == 0) || (cc == COMBINING_CLASS_ABOVE))
                    {
                        return(false);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Implements the "Final_Cased" condition
        ///
        /// Specification: Within the closest word boundaries containing C, there is a cased
        /// letter before C, and there is no cased letter after C.
        ///
        /// Regular Expression:
        ///   Before C: [{cased==true}][{wordBoundary!=true}]*
        ///   After C: !([{wordBoundary!=true}]*[{cased}])
        /// </summary>
        private static bool IsFinalCased(String src, int index, Locale locale)
        {
            BreakIterator wordBoundary = BreakIterator.GetWordInstance(locale);

            wordBoundary.SetText(src);
            int ch;

            // Look for a preceding 'cased' letter
            for (int i = index; (i >= 0) && !wordBoundary.IsBoundary(i); i -= Character.CharCount(ch))
            {
                ch = src.CodePointBefore(i);
                if (IsCased(ch))
                {
                    int len = src.Length();
                    // Check that there is no 'cased' letter after the index
                    for (i = index + Character.CharCount(src.CodePointAt(index)); (i < len) && !wordBoundary.IsBoundary(i); i += Character.CharCount(ch))
                    {
                        ch = src.CodePointAt(i);
                        if (IsCased(ch))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }
            }

            return(false);
        }
        private static char[] LookUpTable(String src, int index, Locale locale, bool bLowerCasing)
        {
            HashSet <Entry> set = EntryTable[new Integer(src.CodePointAt(index))];

            char[] ret = null;

            if (set != null)
            {
                IEnumerator <Entry> iter = set.GetEnumerator();
                String currentLang       = locale.Language;
                while (iter.MoveNext())
                {
                    Entry  entry         = iter.Current;
                    String conditionLang = entry.Language;
                    if (((conditionLang == null) || (conditionLang.Equals(currentLang))) && IsConditionMet(src, index, locale, entry.Condition))
                    {
                        ret = bLowerCasing ? entry.LowerCase : entry.UpperCase;
                        if (conditionLang != null)
                        {
                            break;
                        }
                    }
                }
            }

            return(ret);
        }
 internal static char[] ToUpperCaseCharArray(String src, int index, Locale locale)
 {
     char[] result = LookUpTable(src, index, locale, false);
     if (result != null)
     {
         return(result);
     }
     else
     {
         return(Character.ToUpperCaseCharArray(src.CodePointAt(index)));
     }
 }
        /// <summary>
        /// Implements the "More_Above" condition
        ///
        /// Specification: C is followed by one or more characters of combining
        /// class 230 (ABOVE) in the combining character sequence.
        ///
        /// Regular Expression:
        ///   After C: [{cc!=0}]*[{cc==230}]
        /// </summary>
        private static bool IsMoreAbove(String src, int index)
        {
            int ch;
            int cc;
            int len = src.Length();

            // Look for a following ABOVE combining class character
            for (int i = index + Character.CharCount(src.CodePointAt(index)); i < len; i += Character.CharCount(ch))
            {
                ch = src.CodePointAt(i);
                cc = Normalizer.getCombiningClass(ch);

                if (cc == COMBINING_CLASS_ABOVE)
                {
                    return(true);
                }
                else if (cc == 0)
                {
                    return(false);
                }
            }

            return(false);
        }
        internal static int ToLowerCaseEx(String src, int index, Locale locale)
        {
            char[] result = LookUpTable(src, index, locale, true);

            if (result != null)
            {
                if (result.Length == 1)
                {
                    return(result[0]);
                }
                else
                {
                    return(Character.ERROR);
                }
            }
            else
            {
                // default to Character class' one
                return(char.ToLower(src.CodePointAt(index)));
            }
        }