/// <summary>
        /// Adds a range of items to the end of the list
        /// </summary>
        /// <param name="range"></param>
        public void AddRange(IEnumerable <T> range)
        {
            if (range == null)
            {
                throw new ArgumentNullException();
            }

            int dataSize = Marshal.SizeOf(typeof(T));

            if (range is GPUList <T> && range != this)
            {
                GPUList <T> list = range as GPUList <T>;

                if (list.Count == 0)
                {
                    return;
                }
                if (Count + list.Count > Capacity)
                {
                    setCapacity(2 * Count + list.Count);
                }

                count += list.Count;

                list.CopyRangeTo(0, list.Count, this, Count - list.Count);
            }
            else
            {
                T[] data = null;
                if (range is T[])
                {
                    data = (T[])range;
                }
                else if (range is List <T> )
                {
                    data = (range as List <T>).ToArray();
                }
                else
                {
                    List <T> dataList = new List <T>(range);
                    data = dataList.ToArray();
                }

                if (data.Length == 0)
                {
                    return;
                }
                if (Count + data.Length > Capacity)
                {
                    setCapacity(2 * Count + data.Length);
                }

                count += data.Length;

                SetRange(Count - data.Length, data, 0, data.Length);
            }
        }
        /// <summary>
        /// Copies a range of data to another GPUList
        /// </summary>
        /// <param name="index">Index from which to start copying</param>
        /// <param name="count">Number of elements to copy</param>
        /// <param name="list">Destination list to copy to</param>
        /// <param name="listIndex">Destination list index to copy to</param>
        public void CopyRangeTo(int index, int count, GPUList <T> list, int listIndex)
        {
            if (count == 0)
            {
                return;
            }

            if (list == this)
            {
                throw new Exception("Cannot copy range into self...yet");
            }

            if (count < 0)
            {
                throw new IndexOutOfRangeException();
            }
            if (index < 0 || index >= Count)
            {
                throw new IndexOutOfRangeException();
            }
            if (index + count < 0 || index + count > Count)
            {
                throw new IndexOutOfRangeException();
            }

            if (list == null)
            {
                throw new ArgumentNullException();
            }
            if (listIndex < 0 || listIndex >= list.Count)
            {
                throw new IndexOutOfRangeException();
            }
            if (listIndex + list.Count < 0 || listIndex + count > list.Count)
            {
                throw new IndexOutOfRangeException();
            }

            int dataSize = Marshal.SizeOf(typeof(T));

            context.CopySubresourceRegion(buffer, 0,
                                          new ResourceRegion(dataSize * index, 0, 0, dataSize * (index + count), 1, 1),
                                          list.buffer, 0, dataSize * listIndex, 0, 0);
        }
        /// <summary>
        /// Removes a range of items from the list
        /// </summary>
        /// <param name="index">Index to start removing</param>
        /// <param name="count">Number of items to remove</param>
        public void RemoveRange(int index, int count)
        {
            if (count == 0)
            {
                return;
            }

            if (count < 0)
            {
                throw new IndexOutOfRangeException();
            }
            if (index < 0 || index >= Count)
            {
                throw new IndexOutOfRangeException();
            }
            if (index + count < 0 || index + count > Count)
            {
                throw new IndexOutOfRangeException();
            }

            if (index + count == Count)
            {
                this.count -= count;
                return;
            }

            GPUList <T> newList = new GPUList <T>(Context, Capacity);

            newList.count = this.count - count;
            this.CopyRangeTo(0, index, newList, 0);
            this.CopyRangeTo(index + count, this.count - (index + count), newList, index);

            setCapacity(0);
            this.count               = newList.count;
            this.capacity            = newList.capacity;
            this.buffer              = newList.buffer;
            this.shaderResourceView  = newList.shaderResourceView;
            this.unorderedAccessView = newList.unorderedAccessView;
        }
 /// <summary>
 /// Copys the list to another GPUList
 /// </summary>
 /// <param name="array">The list to copy data to</param>
 /// <param name="arrayIndex">The starting index in the array</param>
 public void CopyTo(GPUList <T> list, int listIndex)
 {
     CopyRangeTo(0, count, list, listIndex);
 }
        /// <summary>
        /// Inserts a range of items into the list
        /// </summary>
        /// <param name="index">Position in the list to insert items</param>
        /// <param name="range">The range of items to insert</param>
        public void InsertRange(int index, IEnumerable <T> range)
        {
            if (range == null)
            {
                throw new ArgumentNullException();
            }
            if (index < 0 || index > Count)
            {
                throw new IndexOutOfRangeException();
            }

            if (index == Count)
            {
                AddRange(range);
            }
            else
            {
                GPUList <T> newList = null;

                if (range is GPUList <T> )
                {
                    GPUList <T> list = range as GPUList <T>;

                    if (list.Count == 0)
                    {
                        return;
                    }

                    newList       = new GPUList <T>(Context, list.Count + Count);
                    newList.count = list.Count + Count;
                    this.CopyRangeTo(0, index, newList, 0);
                    list.CopyTo(newList, index);
                    this.CopyRangeTo(index, Count - index, newList, index + list.Count);
                }
                else
                {
                    T[] data = null;
                    if (range is T[])
                    {
                        data = (T[])range;
                    }
                    else if (range is List <T> )
                    {
                        data = (range as List <T>).ToArray();
                    }
                    else
                    {
                        List <T> dataList = new List <T>(range);
                        data = dataList.ToArray();
                    }

                    if (data.Length == 0)
                    {
                        return;
                    }

                    newList       = new GPUList <T>(Context, data.Length + Count);
                    newList.count = data.Length + Count;
                    this.CopyRangeTo(0, index, newList, 0);
                    newList.SetRange(index, data, 0, data.Length);
                    this.CopyRangeTo(index, Count - index, newList, index + data.Length);
                }

                setCapacity(0);
                count               = newList.count;
                capacity            = newList.capacity;
                buffer              = newList.buffer;
                shaderResourceView  = newList.shaderResourceView;
                unorderedAccessView = newList.unorderedAccessView;
            }
        }