Collections Data Structure C#

using System;
using System.Collections.Generic;
namespace TradeHelp.Utilities
{
    /// 
    /// Sequence is an abstraction of a data reseqeuncer
    /// 

    public class Sequencer
    {
        private int? _curNum;
        private int _subIndex;
        private readonly List _data = new List();
        /// 
        /// Takes as input data of type T and returns all data as a contiguous
        /// block of reseqeunced data.  
        /// 

        /// the data to be re-sequenced
        /// the seqence number associated with the data
        /// indicates if this sequenceNum is the first in the sequence
        /// contiguous sequence of data
        public IEnumerable Resequence(T data, int sequenceNum, bool initial)
        {
            if (initial)
            {
                if (_curNum.HasValue)
                    throw new Exception();
                _curNum = sequenceNum;
            }
            else if (sequenceNum < _curNum)
            {
                throw new ArgumentOutOfRangeException();
            }
            var temp = new Data(data, sequenceNum, ++_subIndex);
            var index = _data.BinarySearch(temp);
            if (index > 0)
                throw new Exception();
            _data.Insert(~index, temp);
            return Enumerate();
        }
        /// 
        /// Takes as input a collection of data of type T and returns all data as a contiguous
        /// block of reseqeunced data.
        /// 

        /// the data to be re-sequenced
        /// the seqence number associated with the data
        /// indicates if this sequenceNum is the first in the sequence
        /// contiguous sequence of data
        public IEnumerable Resequence(ICollection collection, int sequenceNum, bool initial)
        {
            Invariant.CheckIsNull(collection, "collection");
            
            if (initial)
            {
                if (_curNum.HasValue)
                    throw new Exception();
                _curNum = sequenceNum;
            }
            else if (sequenceNum < _curNum)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (collection.Count == 0)
            {
                var temp = new Data(sequenceNum, ++_subIndex);
                var index = _data.BinarySearch(temp);
                if (index > 0)
                    throw new Exception();
                _data.Insert(~index, temp);
            }
            else
            {
                foreach (var data in collection)
                {
                    var temp = new Data(data, sequenceNum, ++_subIndex);
                    var index = _data.BinarySearch(temp);
                    if (index > 0)
                        throw new Exception();
                    _data.Insert(~index, temp);
                }
            }
            return Enumerate();
        }
        private IEnumerable Enumerate()
        {
            while (_data.Count > 0 && _data[0].Index1 == _curNum)
            {
                while (_data.Count > 0 && _data[0].Index1 == _curNum)
                {
                    if (_data[0].HasData)
                    {
                        yield return _data[0].TData;
                    }
                    _data.RemoveAt(0);
                }
                _curNum++;
            }
        }
        private struct Data : IComparable
        {
            public Data(int index1, int index2)
            {
                Index1 = index1;
                Index2 = index2;
                HasData = false;
                TData = default(T);
            }
            public Data(T data, int index1, int index2)
            {
                TData = data;
                Index1 = index1;
                Index2 = index2;
                HasData = true;
            }
            public readonly T TData;
            public readonly int Index1;
            public readonly int Index2;
            public readonly bool HasData;
            public int CompareTo(Data other)
            {
                if (Index1 == other.Index1)
                {
                    return Comparer.Default.Compare(Index2, other.Index2);
                }
                return Comparer.Default.Compare(Index1, other.Index1);
            }
        }
    }
}