/// <summary>
        /// Adds the segment to the list.
        /// </summary>
        /// <param name="array">The array.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param>
        public void AddSegment(T[] array, int offset, int length, bool toBeCopied)
        {
            if (length <= 0)
            {
                return;
            }

            var currentTotal = m_count;

            ArraySegmentEx <T> segment = !toBeCopied
                                 ? new ArraySegmentEx <T>(array, offset, length)
                                 : new ArraySegmentEx <T>(array.CloneRange(offset, length), 0, length);

            segment.From = currentTotal;
            m_count      = currentTotal + segment.Count;
            segment.To   = m_count - 1;

            m_segments.Add(segment);
        }
        /// <summary>
        /// Removes the segment at.
        /// </summary>
        /// <param name="index">The index.</param>
        public void RemoveSegmentAt(int index)
        {
            var removedSegment = m_segments[index];
            int removedLen     = removedSegment.To - removedSegment.From + 1;

            m_segments.RemoveAt(index);

            m_prevSegment = null;

            //the removed item is not the the last item
            if (index != m_segments.Count)
            {
                for (int i = index; i < m_segments.Count; i++)
                {
                    m_segments[i].From -= removedLen;
                    m_segments[i].To   -= removedLen;
                }
            }

            m_count -= removedLen;
        }
 /// <summary>
 /// Clears all the segements.
 /// </summary>
 public void ClearSegements()
 {
     m_segments.Clear();
     m_prevSegment = null;
     m_count       = 0;
 }
        private int GetElementInternalIndex(int index, out ArraySegmentEx <T> segment)
        {
            segment = null;

            if (index < 0 || index > Count - 1)
            {
                return(-1);
            }

            if (index == 0)
            {
                m_prevSegment      = m_segments[0];
                m_prevSegmentIndex = 0;
                segment            = m_prevSegment;
                return(m_prevSegment.Offset);
            }

            int compareValue = 0;

            if (m_prevSegment != null)
            {
                if (index >= m_prevSegment.From)
                {
                    if (index <= m_prevSegment.To)
                    {
                        segment = m_prevSegment;
                        return(m_prevSegment.Offset + index - m_prevSegment.From);
                    }
                    compareValue = 1;
                }
                else
                {
                    compareValue = -1;
                }
            }

            int from, to;

            if (compareValue != 0)
            {
                from = m_prevSegmentIndex + compareValue;

                var trySegment = m_segments[from];

                if (index >= trySegment.From && index <= trySegment.To)
                {
                    segment = trySegment;
                    return(trySegment.Offset + index - trySegment.From);
                }

                from += compareValue;

                var currentSegment = m_segments[from];
                if (index >= currentSegment.From && index <= currentSegment.To)
                {
                    m_prevSegment      = currentSegment;
                    m_prevSegmentIndex = from;
                    segment            = currentSegment;
                    return(currentSegment.Offset + index - currentSegment.From);
                }

                if (compareValue > 0)
                {
                    from++;
                    to = m_segments.Count - 1;
                }
                else
                {
                    var tmp = from - 1;
                    from = 0;
                    to   = tmp;
                }
            }
            else
            {
                from = 0;
                to   = m_segments.Count - 1;
            }

            int segmentIndex;

            var result = QuickSearchSegment(from, to, index, out segmentIndex);

            if (result != null)
            {
                m_prevSegment      = result;
                m_prevSegmentIndex = segmentIndex;
                segment            = m_prevSegment;
                return(result.Offset + index - result.From);
            }

            m_prevSegment = null;

            return(-1);
        }