Collections Data Structure C#

//http://isotopescreencapture.codeplex.com/
//The MIT License (MIT)
using System.Collections.Generic;
using System.Linq;
namespace Isotope.Collections
{
    public static partial class EnumerableUtil
    {
        public static IEnumerable Single(T item)
        {
            yield return item;
        }
        
        /// 
        /// Given a range (start,end) and a number of steps, will yield that a number for each step
        /// 

        /// 
        /// 
        /// 
        /// 
        public static IEnumerable RangeSteps(double start, double end, int steps)
        {
            // for non-positive number of steps, yield no points
            if (steps < 1)
            {
                yield break;
            }
            // for exactly 1 step, yield the start value
            if (steps == 1)
            {
                yield return start;
                yield break;
            }
            // for exactly 2 stesp, yield the start value, and then the end value
            if (steps == 2)
            {
                yield return start;
                yield return end;
                yield break;
            }
            // for 3 steps or above, start yielding the segments
            // notice that the start and end values are explicitly returned so that there
            // is no possibility of rounding error affecting their values
            int segments = steps - 1;
            double total_length = end - start;
            double stepsize = total_length / segments;
            yield return start;
            for (int i = 1; i < (steps-1); i++)
            {
                double p = start + (stepsize*i);
                yield return p;
            }
            yield return end;
        }
        public static IEnumerable GroupByCount(
            IEnumerable items, 
            int group_size,
            System.Func func_new_col,
            System.Action func_add) where TGROUP : class
        {
            if (items == null)
            {
                throw new System.ArgumentNullException("items");
            }
            if (group_size < 1 )
            {
                throw new System.ArgumentOutOfRangeException("group_size");
            }
            if (func_new_col == null)
            {
                throw new System.ArgumentNullException("func_new_col");
            }
            if (func_add == null)
            {
                throw new System.ArgumentNullException("func_add");
            }
            int cur_group_size = 0;
            TGROUP cur_group =null;
            foreach (var item in items)
            {
                if (cur_group_size==0)
                {
                    if (cur_group == null)
                    {
                        cur_group = func_new_col(group_size);
                    }
                    else
                    {
                        throw new System.InvalidOperationException();
                    }
                }
                func_add(cur_group, cur_group_size, item);
                cur_group_size++;
                if (cur_group_size==group_size)
                {
                    yield return cur_group;
                    cur_group = null;
                    cur_group_size = 0;
                }
                
            }
            if (cur_group_size>0)
            {
                if (cur_group==null)
                {
                    throw new System.InvalidOperationException();                  
                }
                yield return cur_group;
            }
        }
        public static IEnumerable GroupByCount(ICollection items, ICollection group_sizes, System.Func func_new_col, System.Action func_add)
        {
            if (items == null)
            {
                throw new System.ArgumentNullException("items");
            }
            if (group_sizes == null)
            {
                throw new System.ArgumentNullException("group_sizes");
            }
            if (func_new_col == null)
            {
                throw new System.ArgumentNullException("func_new_col");
            }
            if (func_add == null)
            {
                throw new System.ArgumentNullException("func_add");
            }
            int total_group_sizes = group_sizes.Sum();
            if (total_group_sizes != items.Count)
            {
                throw new System.ArgumentException("group_sizes must account for all items");
            }
            int items_added = 0;
            for (int group_index = 0; group_index < group_sizes.Count; group_index++)
            {
                int cur_group_size = group_sizes.ElementAt(group_index);
                if (cur_group_size < 0)
                {
                    throw new System.ArgumentException("group_sizes contains a negative numver");
                }
                var cur_group = func_new_col(cur_group_size);
                for (int row_index = 0; row_index < cur_group_size; row_index++)
                {
                    var cur_item = items.ElementAt(items_added);
                    func_add(cur_group, row_index, cur_item);
                    items_added++;
                }
                yield return cur_group;
            }
        }
        public static IDictionary> Bucketize(IEnumerable items, System.Func func_get_key, IEqualityComparer ieq)
        {
            if (items == null)
            {
                throw new System.ArgumentNullException("items");
            }
            if (func_get_key == null)
            {
                throw new System.ArgumentNullException("func_get_key");
            }
            var dic = new Dictionary>(ieq);
            foreach (var item in items)
            {
                var key = func_get_key(item);
                List list = null;
                bool found = dic.TryGetValue(key, out list);
                if (!found)
                {
                    list = new List();
                    dic[key] = list;
                }
                list.Add(item);
            }
            return dic;
        }
        public static IDictionary> Bucketize(IEnumerable items, System.Func func_get_key)
        {
            IEqualityComparer ieq = null;
            return Bucketize(items,func_get_key,ieq);
        }
        public static IDictionary Histogram(IEnumerable items, System.Func func_get_key, IEqualityComparer ieq)
        {
            if (items == null)
            {
                throw new System.ArgumentNullException("items");
            }
            if (func_get_key == null)
            {
                throw new System.ArgumentNullException("func_get_key");
            }
            var dic = new Dictionary(ieq);
            foreach (var item in items)
            {
                var key = func_get_key(item);
                int old_value = 0;
                bool found = dic.TryGetValue(key, out old_value);
                if (!found)
                {
                    dic[key] = 1;
                }
                else
                {
                    dic[key] = old_value + 1;
                }
            }
            return dic;
        }
        public static IDictionary Histogram(IEnumerable items) 
        {
           var dic = Histogram(items, i => i, null);
           return dic;
        }
        public static List> Chunkify(IEnumerable items, int chunksize)
        {
            var chunks = new List>();
            List cur_chunk = null;
            Chunkify(items, chunksize, 
                () =>
                    {
                        cur_chunk = new List(chunksize); chunks.Add(cur_chunk);
                    }, 
                item =>
                    {
                        cur_chunk.Add(item);
                    });
            return chunks;
        }
        public static void Chunkify(IEnumerable items, int chunksize, System.Action create_chunk, System.Action add_item)
        {
            if (items == null)
            {
                throw new System.ArgumentNullException("items");
            }
            if (chunksize < 1)
            {
                throw new System.ArgumentOutOfRangeException("chunksize");
            }
            int item_count = 0;
            int curchunk_size = 0;
            foreach (T item in items)
            {
                if ((item_count % chunksize) == 0)
                {
                    create_chunk();
                    curchunk_size = 0;
                }
                add_item(item);
                item_count++;
                curchunk_size++;
            }
 
        }
    }
}