context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Runtime.Serialization;
  using System.Threading;
  
  namespace Kalman.Collections
  {
  	/// <summary>
  	/// Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.
  	/// </summary>
  	/// <typeparam name="T">The type of elements in the list.</typeparam>
  	public class SynchronizedList<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
  	{
  		private ReaderWriterLock rwLock;
  		private List<T> list;
  
  		#region Constructors
  		/// <summary>
  		/// Initializes a new instance of the List class that is empty and has the default initial capacity.
  		/// </summary>
  		public SynchronizedList()
  		{
  			rwLock = new ReaderWriterLock();
  			list = new List<T>();
  		}
  
  		/// <summary>
  		/// Initializes a new instance of the List class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
  		/// </summary>
  		/// <param name="collection">The collection whose elements are copied to the new list.</param>
  		public SynchronizedList(IEnumerable<T> collection)
  		{
  			rwLock = new ReaderWriterLock();
  			list = new List<T>(collection);
  		}
  
  		/// <summary>
  		/// Initializes a new instance of the List class that is empty and has the specified initial capacity.
  		/// </summary>
  		/// <param name="capacity">The number of elements that the new list can initially store.</param>
  		public SynchronizedList(int capacity)
  		{
  			rwLock = new ReaderWriterLock();
  			list = new List<T>(capacity);
  		}
  		#endregion
  
  		#region Public Properties
  		/// <summary>
  		/// Gets or sets the total number of elements the internal data structure can hold without resizing.
  		/// </summary>
  		public int Capacity
  		{
  			get
  			{
  				try
  				{
  					rwLock.AcquireReaderLock(Timeout.Infinite);
  					return list.Capacity;
  				}
  				finally
  				{
  					rwLock.ReleaseReaderLock();
  				}
  			}
  
  			set
  			{
  				try
  				{
  					rwLock.AcquireWriterLock(Timeout.Infinite);
  					list.Capacity = value;
  				}
  				finally
  				{
  					rwLock.ReleaseWriterLock();
  				}
  			}
  		}
  
  		/// <summary>
  		/// Gets the number of elements actually contained in the List.
  		/// </summary>
  		public int Count
  		{
  			get
  			{
  				try
  				{
  					rwLock.AcquireReaderLock(Timeout.Infinite);
  					return list.Count;
  				}
  				finally
  				{
  					rwLock.ReleaseReaderLock();
  				}
  			}
  		}
  
  		/// <summary>
  		/// Gets or sets the element at the specified index.
  		/// </summary>
  		/// <param name="index">The zero-based index of the element to get or set.</param>
  		/// <returns>The element at the specified index.</returns>
  		public T this[int index]
  		{
  			get
  			{
  				try
  				{
  					rwLock.AcquireReaderLock(Timeout.Infinite);
  					return list[index];
  				}
  				finally
  				{
  					rwLock.ReleaseReaderLock();
  				}
  			}
  
  			set
  			{
  				try
  				{
  					rwLock.AcquireWriterLock(Timeout.Infinite);
  					list[index] = value;
  				}
  				finally
  				{
  					rwLock.ReleaseWriterLock();
  				}
  			}
  		}
  		#endregion
  
  		#region Public Methods
  		/// <summary>
  		/// Adds an object to the end of the List.
  		/// </summary>
  		/// <param name="item">object to be added to the end of the List. The value can be a null reference (Nothing in Visual Basic) for reference types.</param>
  		public void Add(T item)
  		{
  			try
  			{
  				rwLock.AcquireWriterLock(Timeout.Infinite);
  				list.Add(item);
  			}
  			finally
  			{
  				rwLock.ReleaseWriterLock();
  			}
  		}
  
  		/// <summary>
  		/// Adds the elements of the specified collection to the end of the List.
  		/// </summary>
  		/// <param name="collection">The collection whose elements should be added to the end of the List. The collection itself cannot be a null reference (Nothing in Visual Basic), but it can contain elements that are a null reference (Nothing in Visual Basic), if type T is a reference type.</param>
  		public void AddRange(IEnumerable<T> collection)
  		{
  			try
  			{
  				rwLock.AcquireWriterLock(Timeout.Infinite);
  				list.AddRange(collection);
  			}
  			finally
  			{
  				rwLock.ReleaseWriterLock();
  			}
  		}
  
  		/// <summary>
  		/// Returns a read-only IList wrapper for the current collection.
  		/// </summary>
  		/// <returns>A ReadOnlyCollection that acts as a read-only wrapper around the current List.</returns>
  		public ReadOnlyCollection<T> AsReadOnly()
  		{
  			try
  			{
  				rwLock.AcquireReaderLock(Timeout.Infinite);
  				return list.AsReadOnly();
  			}
  			finally
  			{
  				rwLock.ReleaseReaderLock();
  			}
  		}
  
  		/// <summary>
  		/// Searches the entire sorted List for an element using the default comparer and returns the zero-based index of the element.
  		/// </summary>
  		/// <param name="item">The object to locate. The value can be a null reference (Nothing in Visual Basic) for reference types.</param>
  		/// <returns>The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count.</returns>
  		public int BinarySearch(T item)
  		{
  			try
  			{
  				rwLock.AcquireReaderLock(Timeout.Infinite);
  				return list.BinarySearch(item);
  			}
  			finally
  			{
  				rwLock.ReleaseReaderLock();
  			}
  		}
  
  		/// <summary>
  		/// Searches the entire sorted List for an element using the specified comparer and returns the zero-based index of the element.
  		/// </summary>
  		/// <param name="item">The object to locate. The value can be a null reference (Nothing in Visual Basic) for reference types.</param>
  		/// <param name="comparer">The IComparer implementation to use when comparing elements, or a null reference (Nothing in Visual Basic) to use the default comparer Comparer.</param>
  		/// <returns>The zero-based index of item in the sorted List, if item is found; otherwise, a negative number that is the bitwise complement of the index of the next element that is larger than item or, if there is no larger element, the bitwise complement of Count.</returns>
  		public int BinarySearch(T item, IComparer<T> comparer)
  		{
  			try
  			{
  				rwLock.AcquireReaderLock(Timeout.Infinite);
  
gt: 				return list.BinarySearch(item, comparer);