// private methods --------------------------------------------------

        /// <summary>
        /// Group name iteration, iterate all the names in the current 32-group and
        /// returns the first codepoint that has a valid name.
        /// </summary>
        ///
        /// <param name="result">stores the result codepoint and name</param>
        /// <param name="limit">last codepoint + 1 in range to search</param>
        /// <returns>false if a codepoint with a name is found in group and we can
        /// bail from further iteration, true to continue on with the
        /// iteration</returns>
        private bool IterateSingleGroup(ValueIterator_Constants.Element result, int limit)
        {
            lock (GROUP_OFFSETS_) {
                lock (GROUP_LENGTHS_) {
                    int index = m_name_.GetGroupLengths(m_groupIndex_,
                                                        GROUP_OFFSETS_, GROUP_LENGTHS_);
                    while (m_current_ < limit)
                    {
                        int    offset = IBM.ICU.Impl.UCharacterName.GetGroupOffset(m_current_);
                        String name   = m_name_.GetGroupName(index
                                                             + GROUP_OFFSETS_[offset], GROUP_LENGTHS_[offset],
                                                             m_choice_);
                        if ((name == null || name.Length == 0) &&
                            m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME)
                        {
                            name = m_name_.GetExtendedName(m_current_);
                        }
                        if (name != null && name.Length > 0)
                        {
                            result.integer   = m_current_;
                            result.value_ren = name;
                            return(false);
                        }
                        ++m_current_;
                    }
                }
            }
            return(true);
        }
        /// <summary>
        /// Group name iteration, iterate all the names in the current 32-group and
        /// returns the first codepoint that has a valid name.
        /// </summary>
        ///
        /// <param name="result">stores the result codepoint and name</param>
        /// <param name="limit">last codepoint + 1 in range to search</param>
        /// <returns>false if a codepoint with a name is found in group and we can
        /// bail from further iteration, true to continue on with the
        /// iteration</returns>
        private bool IterateGroup(ValueIterator_Constants.Element result, int limit)
        {
            if (m_groupIndex_ < 0)
            {
                m_groupIndex_ = m_name_.GetGroup(m_current_);
            }

            while (m_groupIndex_ < m_name_.m_groupcount_ && m_current_ < limit)
            {
                // iterate till the last group or the last codepoint
                int startMSB = IBM.ICU.Impl.UCharacterName.GetCodepointMSB(m_current_);
                int gMSB     = m_name_.GetGroupMSB(m_groupIndex_); // can be -1
                if (startMSB == gMSB)
                {
                    if (startMSB == IBM.ICU.Impl.UCharacterName.GetCodepointMSB(limit - 1))
                    {
                        // if start and limit - 1 are in the same group, then
                        // enumerate
                        // only in that one
                        return(IterateSingleGroup(result, limit));
                    }
                    // enumerate characters in the partial start group
                    // if (m_name_.getGroupOffset(m_current_) != 0) {
                    if (!IterateSingleGroup(result,
                                            IBM.ICU.Impl.UCharacterName.GetGroupLimit(gMSB)))
                    {
                        return(false);
                    }
                    ++m_groupIndex_;     // continue with the next group
                }
                else if (startMSB > gMSB)
                {
                    // make sure that we start enumerating with the first group
                    // after start
                    m_groupIndex_++;
                }
                else
                {
                    int gMIN = IBM.ICU.Impl.UCharacterName.GetGroupMin(gMSB);
                    if (gMIN > limit)
                    {
                        gMIN = limit;
                    }
                    if (m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME)
                    {
                        if (!IterateExtended(result, gMIN))
                        {
                            return(false);
                        }
                    }
                    m_current_ = gMIN;
                }
            }

            return(true);
        }
 /// <summary>
 /// Iterate extended names.
 /// </summary>
 ///
 /// <param name="result">stores the result codepoint and name</param>
 /// <param name="limit">last codepoint + 1 in range to search</param>
 /// <returns>false if a codepoint with a name is found and we can bail from
 /// further iteration, true to continue on with the iteration (this
 /// will always be false for valid codepoints)</returns>
 private bool IterateExtended(ValueIterator_Constants.Element result, int limit)
 {
     while (m_current_ < limit)
     {
         String name = m_name_.GetExtendedOr10Name(m_current_);
         if (name != null && name.Length > 0)
         {
             result.integer   = m_current_;
             result.value_ren = name;
             return(false);
         }
         ++m_current_;
     }
     return(true);
 }
        // public methods ----------------------------------------------------

        /// <summary>
        /// <p>
        /// Gets the next result for this iteration and returns true if we are not at
        /// the end of the iteration, false otherwise.
        /// </p>
        /// <p>
        /// If the return boolean is a false, the contents of elements will not be
        /// updated.
        /// </p>
        /// </summary>
        ///
        /// <param name="element">for storing the result codepoint and name</param>
        /// <returns>true if we are not at the end of the iteration, false otherwise.</returns>
        /// <seealso cref="null"/>
        /// @draft 2.1
        public virtual bool Next(ValueIterator_Constants.Element element)
        {
            if (m_current_ >= m_limit_)
            {
                return(false);
            }

            if (m_choice_ != IBM.ICU.Impl.UCharacterNameChoice_Constants.UNICODE_10_CHAR_NAME)
            {
                int length = m_name_.GetAlgorithmLength();
                if (m_algorithmIndex_ < length)
                {
                    while (m_algorithmIndex_ < length)
                    {
                        // find the algorithm range that could contain m_current_
                        if (m_algorithmIndex_ < 0 ||
                            m_name_.GetAlgorithmEnd(m_algorithmIndex_) < m_current_)
                        {
                            m_algorithmIndex_++;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (m_algorithmIndex_ < length)
                    {
                        // interleave the data-driven ones with the algorithmic ones
                        // iterate over all algorithmic ranges; assume that they are
                        // in ascending order
                        int start = m_name_.GetAlgorithmStart(m_algorithmIndex_);
                        if (m_current_ < start)
                        {
                            // this should get rid of those codepoints that are not
                            // in the algorithmic range
                            int end = start;
                            if (m_limit_ <= start)
                            {
                                end = m_limit_;
                            }
                            if (!IterateGroup(element, end))
                            {
                                m_current_++;
                                return(true);
                            }
                        }

                        if (m_current_ >= m_limit_)
                        {
                            // after iterateGroup fails, current codepoint may be
                            // greater than limit
                            return(false);
                        }

                        element.integer   = m_current_;
                        element.value_ren = m_name_.GetAlgorithmName(m_algorithmIndex_,
                                                                     m_current_);
                        // reset the group index if we are in the algorithmic names
                        m_groupIndex_ = -1;
                        m_current_++;
                        return(true);
                    }
                }
            }
            // enumerate the character names after the last algorithmic range
            if (!IterateGroup(element, m_limit_))
            {
                m_current_++;
                return(true);
            }
            else if (m_choice_ == IBM.ICU.Impl.UCharacterNameChoice_Constants.EXTENDED_CHAR_NAME)
            {
                if (!IterateExtended(element, m_limit_))
                {
                    m_current_++;
                    return(true);
                }
            }

            return(false);
        }