You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1431 lines
42 KiB
C#
1431 lines
42 KiB
C#
9 months ago
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.IO;
|
||
|
|
||
|
namespace AutoUpdater
|
||
|
{
|
||
|
[Serializable]
|
||
|
public class DownloadURLCollection : IList, ICloneable
|
||
|
{
|
||
|
#region Private Fields
|
||
|
|
||
|
private const int _defaultCapacity = 16;
|
||
|
|
||
|
private DownloadURL[] _array = null;
|
||
|
|
||
|
private int _count = 0;
|
||
|
|
||
|
[NonSerialized]
|
||
|
private int _version = 0;
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Private Constructors
|
||
|
|
||
|
private enum Tag { Default }
|
||
|
|
||
|
private DownloadURLCollection(Tag tag) { }
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Public Constructors
|
||
|
|
||
|
#region DownloadURLCollection()
|
||
|
|
||
|
public DownloadURLCollection()
|
||
|
{
|
||
|
this._array = new DownloadURL[_defaultCapacity];
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region DownloadURLCollection(Int32)
|
||
|
|
||
|
public DownloadURLCollection(int capacity)
|
||
|
{
|
||
|
if (capacity < 0)
|
||
|
throw new ArgumentOutOfRangeException("capacity", capacity, "Argument cannot be negative.");
|
||
|
this._array = new DownloadURL[capacity];
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region DownloadURLCollection(DownloadURLCollection)
|
||
|
|
||
|
public DownloadURLCollection(DownloadURLCollection collection)
|
||
|
{
|
||
|
if (collection == null)
|
||
|
throw new ArgumentNullException("collection");
|
||
|
|
||
|
this._array = new DownloadURL[collection.Count];
|
||
|
AddRange(collection);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region DownloadURLCollection(DownloadURL[])
|
||
|
|
||
|
public DownloadURLCollection(DownloadURL[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
throw new ArgumentNullException("array");
|
||
|
|
||
|
this._array = new DownloadURL[array.Length];
|
||
|
AddRange(array);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#endregion
|
||
|
|
||
|
#region Protected Properties
|
||
|
#region InnerArray
|
||
|
|
||
|
protected virtual DownloadURL[] InnerArray
|
||
|
{
|
||
|
get { return this._array; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#endregion
|
||
|
|
||
|
#region Public Properties
|
||
|
#region Capacity
|
||
|
|
||
|
public virtual int Capacity
|
||
|
{
|
||
|
get { return this._array.Length; }
|
||
|
set
|
||
|
{
|
||
|
if (value == this._array.Length) return;
|
||
|
|
||
|
if (value < this._count)
|
||
|
throw new ArgumentOutOfRangeException("Capacity", value, "Value cannot be less than Count.");
|
||
|
|
||
|
if (value == 0)
|
||
|
{
|
||
|
this._array = new DownloadURL[_defaultCapacity];
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DownloadURL[] newArray = new DownloadURL[value];
|
||
|
Array.Copy(this._array, newArray, this._count);
|
||
|
this._array = newArray;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Count
|
||
|
|
||
|
public virtual int Count
|
||
|
{
|
||
|
get { return this._count; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IsFixedSize
|
||
|
|
||
|
public virtual bool IsFixedSize
|
||
|
{
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IsReadOnly
|
||
|
|
||
|
public virtual bool IsReadOnly
|
||
|
{
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IsSynchronized
|
||
|
|
||
|
public virtual bool IsSynchronized
|
||
|
{
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IsUnique
|
||
|
|
||
|
public virtual bool IsUnique
|
||
|
{
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Item: DownloadURL
|
||
|
|
||
|
public virtual DownloadURL this[int index]
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
ValidateIndex(index);
|
||
|
return this._array[index];
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
ValidateIndex(index);
|
||
|
++this._version;
|
||
|
this._array[index] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.Item: Object
|
||
|
|
||
|
object IList.this[int index]
|
||
|
{
|
||
|
get { return this[index]; }
|
||
|
set { this[index] = (DownloadURL)value; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region SyncRoot
|
||
|
|
||
|
public virtual object SyncRoot
|
||
|
{
|
||
|
get { return this; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#endregion
|
||
|
|
||
|
#region Public Methods
|
||
|
#region Add(DownloadURL)
|
||
|
|
||
|
public virtual int Add(DownloadURL value)
|
||
|
{
|
||
|
if (this._count == this._array.Length)
|
||
|
EnsureCapacity(this._count + 1);
|
||
|
|
||
|
++this._version;
|
||
|
this._array[this._count] = value;
|
||
|
return this._count++;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.Add(Object)
|
||
|
|
||
|
int IList.Add(object value)
|
||
|
{
|
||
|
return Add((DownloadURL)value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region AddRange(DownloadURLCollection)
|
||
|
|
||
|
public virtual void AddRange(DownloadURLCollection collection)
|
||
|
{
|
||
|
if (collection == null)
|
||
|
throw new ArgumentNullException("collection");
|
||
|
|
||
|
if (collection.Count == 0) return;
|
||
|
if (this._count + collection.Count > this._array.Length)
|
||
|
EnsureCapacity(this._count + collection.Count);
|
||
|
|
||
|
++this._version;
|
||
|
Array.Copy(collection.InnerArray, 0,
|
||
|
this._array, this._count, collection.Count);
|
||
|
this._count += collection.Count;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region AddRange(DownloadURL[])
|
||
|
|
||
|
public virtual void AddRange(DownloadURL[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
throw new ArgumentNullException("array");
|
||
|
|
||
|
if (array.Length == 0) return;
|
||
|
if (this._count + array.Length > this._array.Length)
|
||
|
EnsureCapacity(this._count + array.Length);
|
||
|
|
||
|
++this._version;
|
||
|
Array.Copy(array, 0, this._array, this._count, array.Length);
|
||
|
this._count += array.Length;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region BinarySearch
|
||
|
|
||
|
public virtual int BinarySearch(DownloadURL value)
|
||
|
{
|
||
|
return Array.BinarySearch(this._array, 0, this._count, value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Clear
|
||
|
|
||
|
public virtual void Clear()
|
||
|
{
|
||
|
if (this._count == 0) return;
|
||
|
|
||
|
++this._version;
|
||
|
Array.Clear(this._array, 0, this._count);
|
||
|
this._count = 0;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Clone
|
||
|
|
||
|
public virtual object Clone()
|
||
|
{
|
||
|
DownloadURLCollection collection = new DownloadURLCollection(this._count);
|
||
|
|
||
|
Array.Copy(this._array, 0, collection._array, 0, this._count);
|
||
|
collection._count = this._count;
|
||
|
collection._version = this._version;
|
||
|
|
||
|
return collection;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Contains(DownloadURL)
|
||
|
|
||
|
public bool Contains(DownloadURL value)
|
||
|
{
|
||
|
return (IndexOf(value) >= 0);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.Contains(Object)
|
||
|
|
||
|
bool IList.Contains(object value)
|
||
|
{
|
||
|
return Contains((DownloadURL)value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region CopyTo(DownloadURL[])
|
||
|
|
||
|
public virtual void CopyTo(DownloadURL[] array)
|
||
|
{
|
||
|
CheckTargetArray(array, 0);
|
||
|
Array.Copy(this._array, array, this._count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region CopyTo(DownloadURL[], Int32)
|
||
|
|
||
|
public virtual void CopyTo(DownloadURL[] array, int arrayIndex)
|
||
|
{
|
||
|
CheckTargetArray(array, arrayIndex);
|
||
|
Array.Copy(this._array, 0, array, arrayIndex, this._count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region ICollection.CopyTo(Array, Int32)
|
||
|
|
||
|
void ICollection.CopyTo(Array array, int arrayIndex)
|
||
|
{
|
||
|
CheckTargetArray(array, arrayIndex);
|
||
|
CopyTo((DownloadURL[])array, arrayIndex);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region GetEnumerator: IDownloadURLEnumerator
|
||
|
|
||
|
public virtual DownloadURLCollection.Enumerator GetEnumerator()
|
||
|
{
|
||
|
return new Enumerator(this);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IEnumerable.GetEnumerator: IEnumerator
|
||
|
|
||
|
|
||
|
IEnumerator IEnumerable.GetEnumerator()
|
||
|
{
|
||
|
return (IEnumerator)GetEnumerator();
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IndexOf(DownloadURL)
|
||
|
|
||
|
public virtual int IndexOf(DownloadURL value)
|
||
|
{
|
||
|
return Array.IndexOf(this._array, value, 0, this._count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.IndexOf(Object)
|
||
|
|
||
|
int IList.IndexOf(object value)
|
||
|
{
|
||
|
return IndexOf((DownloadURL)value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Insert(Int32, DownloadURL)
|
||
|
|
||
|
public virtual void Insert(int index, DownloadURL value)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
throw new ArgumentOutOfRangeException("index", index, "Argument cannot be negative.");
|
||
|
|
||
|
if (index > this._count)
|
||
|
throw new ArgumentOutOfRangeException("index", index, "Argument cannot exceed Count.");
|
||
|
|
||
|
if (this._count == this._array.Length)
|
||
|
EnsureCapacity(this._count + 1);
|
||
|
|
||
|
++this._version;
|
||
|
if (index < this._count)
|
||
|
Array.Copy(this._array, index,
|
||
|
this._array, index + 1, this._count - index);
|
||
|
|
||
|
this._array[index] = value;
|
||
|
++this._count;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.Insert(Int32, Object)
|
||
|
|
||
|
void IList.Insert(int index, object value)
|
||
|
{
|
||
|
Insert(index, (DownloadURL)value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region ReadOnly
|
||
|
|
||
|
public static DownloadURLCollection ReadOnly(DownloadURLCollection collection)
|
||
|
{
|
||
|
if (collection == null)
|
||
|
throw new ArgumentNullException("collection");
|
||
|
|
||
|
return new ReadOnlyList(collection);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Remove(DownloadURL)
|
||
|
|
||
|
public virtual void Remove(DownloadURL value)
|
||
|
{
|
||
|
int index = IndexOf(value);
|
||
|
if (index >= 0) RemoveAt(index);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region IList.Remove(Object)
|
||
|
|
||
|
void IList.Remove(object value)
|
||
|
{
|
||
|
Remove((DownloadURL)value);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region RemoveAt
|
||
|
|
||
|
public virtual void RemoveAt(int index)
|
||
|
{
|
||
|
ValidateIndex(index);
|
||
|
|
||
|
++this._version;
|
||
|
if (index < --this._count)
|
||
|
Array.Copy(this._array, index + 1,
|
||
|
this._array, index, this._count - index);
|
||
|
|
||
|
this._array[this._count] = null;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region RemoveRange
|
||
|
|
||
|
public virtual void RemoveRange(int index, int count)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
throw new ArgumentOutOfRangeException("index",
|
||
|
index, "Argument cannot be negative.");
|
||
|
|
||
|
if (count < 0)
|
||
|
throw new ArgumentOutOfRangeException("count",
|
||
|
count, "Argument cannot be negative.");
|
||
|
|
||
|
if (index + count > this._count)
|
||
|
throw new ArgumentException(
|
||
|
"Arguments denote invalid range of elements.");
|
||
|
|
||
|
if (count == 0) return;
|
||
|
|
||
|
++this._version;
|
||
|
this._count -= count;
|
||
|
|
||
|
if (index < this._count)
|
||
|
Array.Copy(this._array, index + count,
|
||
|
this._array, index, this._count - index);
|
||
|
|
||
|
Array.Clear(this._array, this._count, count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Reverse()
|
||
|
|
||
|
public virtual void Reverse()
|
||
|
{
|
||
|
if (this._count <= 1) return;
|
||
|
++this._version;
|
||
|
Array.Reverse(this._array, 0, this._count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Reverse(Int32, Int32)
|
||
|
|
||
|
public virtual void Reverse(int index, int count)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
throw new ArgumentOutOfRangeException("index",
|
||
|
index, "Argument cannot be negative.");
|
||
|
|
||
|
if (count < 0)
|
||
|
throw new ArgumentOutOfRangeException("count",
|
||
|
count, "Argument cannot be negative.");
|
||
|
|
||
|
if (index + count > this._count)
|
||
|
throw new ArgumentException(
|
||
|
"Arguments denote invalid range of elements.");
|
||
|
|
||
|
if (count <= 1 || this._count <= 1) return;
|
||
|
++this._version;
|
||
|
Array.Reverse(this._array, index, count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Sort()
|
||
|
|
||
|
/// <overloads>
|
||
|
/// Sorts the elements in the <see cref="DownloadURLCollection"/> or a portion of it.
|
||
|
/// </overloads>
|
||
|
/// <summary>
|
||
|
/// Sorts the elements in the entire <see cref="DownloadURLCollection"/>
|
||
|
/// using the <see cref="IComparable"/> implementation of each element.
|
||
|
/// </summary>
|
||
|
/// <exception cref="NotSupportedException">
|
||
|
/// The <see cref="DownloadURLCollection"/> is read-only.</exception>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.Sort"/> for details.</remarks>
|
||
|
|
||
|
public virtual void Sort()
|
||
|
{
|
||
|
if (this._count <= 1) return;
|
||
|
++this._version;
|
||
|
Array.Sort(this._array, 0, this._count);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Sort(IComparer)
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sorts the elements in the entire <see cref="DownloadURLCollection"/>
|
||
|
/// using the specified <see cref="IComparer"/> interface.
|
||
|
/// </summary>
|
||
|
/// <param name="comparer">
|
||
|
/// <para>The <see cref="IComparer"/> implementation to use when comparing elements.</para>
|
||
|
/// <para>-or-</para>
|
||
|
/// <para>A null reference to use the <see cref="IComparable"/> implementation
|
||
|
/// of each element.</para></param>
|
||
|
/// <exception cref="NotSupportedException">
|
||
|
/// The <see cref="DownloadURLCollection"/> is read-only.</exception>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.Sort"/> for details.</remarks>
|
||
|
|
||
|
public virtual void Sort(IComparer comparer)
|
||
|
{
|
||
|
if (this._count <= 1) return;
|
||
|
++this._version;
|
||
|
Array.Sort(this._array, 0, this._count, comparer);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Sort(Int32, Int32, IComparer)
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sorts the elements in the specified range
|
||
|
/// using the specified <see cref="IComparer"/> interface.
|
||
|
/// </summary>
|
||
|
/// <param name="index">The zero-based starting index of the range
|
||
|
/// of elements to sort.</param>
|
||
|
/// <param name="count">The number of elements to sort.</param>
|
||
|
/// <param name="comparer">
|
||
|
/// <para>The <see cref="IComparer"/> implementation to use when comparing elements.</para>
|
||
|
/// <para>-or-</para>
|
||
|
/// <para>A null reference to use the <see cref="IComparable"/> implementation
|
||
|
/// of each element.</para></param>
|
||
|
/// <exception cref="ArgumentException">
|
||
|
/// <paramref name="index"/> and <paramref name="count"/> do not denote a
|
||
|
/// valid range of elements in the <see cref="DownloadURLCollection"/>.</exception>
|
||
|
/// <exception cref="ArgumentOutOfRangeException">
|
||
|
/// <para><paramref name="index"/> is less than zero.</para>
|
||
|
/// <para>-or-</para>
|
||
|
/// <para><paramref name="count"/> is less than zero.</para>
|
||
|
/// </exception>
|
||
|
/// <exception cref="NotSupportedException">
|
||
|
/// The <see cref="DownloadURLCollection"/> is read-only.</exception>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.Sort"/> for details.</remarks>
|
||
|
|
||
|
public virtual void Sort(int index, int count, IComparer comparer)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
throw new ArgumentOutOfRangeException("index",
|
||
|
index, "Argument cannot be negative.");
|
||
|
|
||
|
if (count < 0)
|
||
|
throw new ArgumentOutOfRangeException("count",
|
||
|
count, "Argument cannot be negative.");
|
||
|
|
||
|
if (index + count > this._count)
|
||
|
throw new ArgumentException(
|
||
|
"Arguments denote invalid range of elements.");
|
||
|
|
||
|
if (count <= 1 || this._count <= 1) return;
|
||
|
++this._version;
|
||
|
Array.Sort(this._array, index, count, comparer);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Synchronized
|
||
|
|
||
|
/// <summary>
|
||
|
/// Returns a synchronized (thread-safe) wrapper
|
||
|
/// for the specified <see cref="DownloadURLCollection"/>.
|
||
|
/// </summary>
|
||
|
/// <param name="collection">The <see cref="DownloadURLCollection"/> to synchronize.</param>
|
||
|
/// <returns>
|
||
|
/// A synchronized (thread-safe) wrapper around <paramref name="collection"/>.
|
||
|
/// </returns>
|
||
|
/// <exception cref="ArgumentNullException">
|
||
|
/// <paramref name="collection"/> is a null reference.</exception>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.Synchronized"/> for details.</remarks>
|
||
|
|
||
|
public static DownloadURLCollection Synchronized(DownloadURLCollection collection)
|
||
|
{
|
||
|
if (collection == null)
|
||
|
throw new ArgumentNullException("collection");
|
||
|
|
||
|
return new SyncList(collection);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region ToArray
|
||
|
|
||
|
/// <summary>
|
||
|
/// Copies the elements of the <see cref="DownloadURLCollection"/> to a new
|
||
|
/// <see cref="Array"/> of <see cref="DownloadURL"/> elements.
|
||
|
/// </summary>
|
||
|
/// <returns>A one-dimensional <see cref="Array"/> of <see cref="DownloadURL"/>
|
||
|
/// elements containing copies of the elements of the <see cref="DownloadURLCollection"/>.</returns>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.ToArray"/> for details.</remarks>
|
||
|
|
||
|
public virtual DownloadURL[] ToArray()
|
||
|
{
|
||
|
DownloadURL[] array = new DownloadURL[this._count];
|
||
|
Array.Copy(this._array, array, this._count);
|
||
|
return array;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region TrimToSize
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sets the capacity to the actual number of elements in the <see cref="DownloadURLCollection"/>.
|
||
|
/// </summary>
|
||
|
/// <exception cref="NotSupportedException">
|
||
|
/// <para>The <see cref="DownloadURLCollection"/> is read-only.</para>
|
||
|
/// <para>-or-</para>
|
||
|
/// <para>The <b>DownloadURLCollection</b> has a fixed size.</para></exception>
|
||
|
/// <remarks>Please refer to <see cref="ArrayList.TrimToSize"/> for details.</remarks>
|
||
|
|
||
|
public virtual void TrimToSize()
|
||
|
{
|
||
|
Capacity = this._count;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Unique
|
||
|
|
||
|
/// <summary>
|
||
|
/// Returns a wrapper for the specified <see cref="DownloadURLCollection"/>
|
||
|
/// ensuring that all elements are unique.
|
||
|
/// </summary>
|
||
|
/// <param name="collection">The <see cref="DownloadURLCollection"/> to wrap.</param>
|
||
|
/// <returns>
|
||
|
/// A wrapper around <paramref name="collection"/> ensuring that all elements are unique.
|
||
|
/// </returns>
|
||
|
/// <exception cref="ArgumentException">
|
||
|
/// <paramref name="collection"/> contains duplicate elements.</exception>
|
||
|
/// <exception cref="ArgumentNullException">
|
||
|
/// <paramref name="collection"/> is a null reference.</exception>
|
||
|
/// <remarks><para>
|
||
|
/// The <b>Unique</b> wrapper provides a set-like collection by ensuring
|
||
|
/// that all elements in the <see cref="DownloadURLCollection"/> are unique.
|
||
|
/// </para><para>
|
||
|
/// <b>Unique</b> raises an <see cref="ArgumentException"/> if the specified
|
||
|
/// <paramref name="collection"/> contains any duplicate elements. The returned
|
||
|
/// wrapper raises a <see cref="NotSupportedException"/> whenever the user attempts
|
||
|
/// to add an element that is already contained in the <b>DownloadURLCollection</b>.
|
||
|
/// </para><para>
|
||
|
/// <strong>Note:</strong> The <b>Unique</b> wrapper reflects any changes made
|
||
|
/// to the underlying <paramref name="collection"/>, including the possible
|
||
|
/// creation of duplicate elements. The uniqueness of all elements is therefore
|
||
|
/// no longer assured if the underlying collection is manipulated directly.
|
||
|
/// </para></remarks>
|
||
|
|
||
|
public static DownloadURLCollection Unique(DownloadURLCollection collection)
|
||
|
{
|
||
|
if (collection == null)
|
||
|
throw new ArgumentNullException("collection");
|
||
|
|
||
|
for (int i = collection.Count - 1; i > 0; i--)
|
||
|
if (collection.IndexOf(collection[i]) < i)
|
||
|
throw new ArgumentException("collection",
|
||
|
"Argument cannot contain duplicate elements.");
|
||
|
|
||
|
return new UniqueList(collection);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#endregion
|
||
|
|
||
|
#region Private Methods
|
||
|
#region CheckEnumIndex
|
||
|
|
||
|
private void CheckEnumIndex(int index)
|
||
|
{
|
||
|
if (index < 0 || index >= this._count)
|
||
|
throw new InvalidOperationException(
|
||
|
"Enumerator is not on a collection element.");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region CheckEnumVersion
|
||
|
|
||
|
private void CheckEnumVersion(int version)
|
||
|
{
|
||
|
if (version != this._version)
|
||
|
throw new InvalidOperationException(
|
||
|
"Enumerator invalidated by modification to collection.");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region CheckTargetArray
|
||
|
|
||
|
private void CheckTargetArray(Array array, int arrayIndex)
|
||
|
{
|
||
|
if (array == null)
|
||
|
throw new ArgumentNullException("array");
|
||
|
if (array.Rank > 1)
|
||
|
throw new ArgumentException(
|
||
|
"Argument cannot be multidimensional.", "array");
|
||
|
|
||
|
if (arrayIndex < 0)
|
||
|
throw new ArgumentOutOfRangeException("arrayIndex",
|
||
|
arrayIndex, "Argument cannot be negative.");
|
||
|
if (arrayIndex >= array.Length)
|
||
|
throw new ArgumentException(
|
||
|
"Argument must be less than array length.", "arrayIndex");
|
||
|
|
||
|
if (this._count > array.Length - arrayIndex)
|
||
|
throw new ArgumentException(
|
||
|
"Argument section must be large enough for collection.", "array");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region EnsureCapacity
|
||
|
|
||
|
private void EnsureCapacity(int minimum)
|
||
|
{
|
||
|
int newCapacity = (this._array.Length == 0 ?
|
||
|
_defaultCapacity : this._array.Length * 2);
|
||
|
|
||
|
if (newCapacity < minimum) newCapacity = minimum;
|
||
|
Capacity = newCapacity;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region ValidateIndex
|
||
|
|
||
|
private void ValidateIndex(int index)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
throw new ArgumentOutOfRangeException("index",
|
||
|
index, "Argument cannot be negative.");
|
||
|
|
||
|
if (index >= this._count)
|
||
|
throw new ArgumentOutOfRangeException("index",
|
||
|
index, "Argument must be less than Count.");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#endregion
|
||
|
|
||
|
#region Class Enumerator
|
||
|
|
||
|
[Serializable]
|
||
|
public sealed class Enumerator : IEnumerator
|
||
|
{
|
||
|
#region Private Fields
|
||
|
|
||
|
private readonly DownloadURLCollection _collection;
|
||
|
private readonly int _version;
|
||
|
private int _index;
|
||
|
|
||
|
#endregion
|
||
|
#region Internal Constructors
|
||
|
|
||
|
internal Enumerator(DownloadURLCollection collection)
|
||
|
{
|
||
|
this._collection = collection;
|
||
|
this._version = collection._version;
|
||
|
this._index = -1;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Properties
|
||
|
|
||
|
public DownloadURL Current
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
this._collection.CheckEnumIndex(this._index);
|
||
|
this._collection.CheckEnumVersion(this._version);
|
||
|
return this._collection[this._index];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
object IEnumerator.Current
|
||
|
{
|
||
|
get { return Current; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Methods
|
||
|
|
||
|
public bool MoveNext()
|
||
|
{
|
||
|
this._collection.CheckEnumVersion(this._version);
|
||
|
return (++this._index < this._collection.Count);
|
||
|
}
|
||
|
|
||
|
public void Reset()
|
||
|
{
|
||
|
this._collection.CheckEnumVersion(this._version);
|
||
|
this._index = -1;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Class ReadOnlyList
|
||
|
|
||
|
[Serializable]
|
||
|
private sealed class ReadOnlyList : DownloadURLCollection
|
||
|
{
|
||
|
#region Private Fields
|
||
|
|
||
|
private DownloadURLCollection _collection;
|
||
|
|
||
|
#endregion
|
||
|
#region Internal Constructors
|
||
|
|
||
|
internal ReadOnlyList(DownloadURLCollection collection)
|
||
|
:
|
||
|
base(Tag.Default)
|
||
|
{
|
||
|
this._collection = collection;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Protected Properties
|
||
|
|
||
|
protected override DownloadURL[] InnerArray
|
||
|
{
|
||
|
get { return this._collection.InnerArray; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Properties
|
||
|
|
||
|
public override int Capacity
|
||
|
{
|
||
|
get { return this._collection.Capacity; }
|
||
|
set
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override int Count
|
||
|
{
|
||
|
get { return this._collection.Count; }
|
||
|
}
|
||
|
|
||
|
public override bool IsFixedSize
|
||
|
{
|
||
|
get { return true; }
|
||
|
}
|
||
|
|
||
|
public override bool IsReadOnly
|
||
|
{
|
||
|
get { return true; }
|
||
|
}
|
||
|
|
||
|
public override bool IsSynchronized
|
||
|
{
|
||
|
get { return this._collection.IsSynchronized; }
|
||
|
}
|
||
|
|
||
|
public override bool IsUnique
|
||
|
{
|
||
|
get { return this._collection.IsUnique; }
|
||
|
}
|
||
|
|
||
|
public override DownloadURL this[int index]
|
||
|
{
|
||
|
get { return this._collection[index]; }
|
||
|
set
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override object SyncRoot
|
||
|
{
|
||
|
get { return this._collection.SyncRoot; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Methods
|
||
|
|
||
|
public override int Add(DownloadURL value)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURLCollection collection)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURL[] array)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override int BinarySearch(DownloadURL value)
|
||
|
{
|
||
|
return this._collection.BinarySearch(value);
|
||
|
}
|
||
|
|
||
|
public override void Clear()
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override object Clone()
|
||
|
{
|
||
|
return new ReadOnlyList((DownloadURLCollection)this._collection.Clone());
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array)
|
||
|
{
|
||
|
this._collection.CopyTo(array);
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array, int arrayIndex)
|
||
|
{
|
||
|
this._collection.CopyTo(array, arrayIndex);
|
||
|
}
|
||
|
|
||
|
public override DownloadURLCollection.Enumerator GetEnumerator()
|
||
|
{
|
||
|
return this._collection.GetEnumerator();
|
||
|
}
|
||
|
|
||
|
public override int IndexOf(DownloadURL value)
|
||
|
{
|
||
|
return this._collection.IndexOf(value);
|
||
|
}
|
||
|
|
||
|
public override void Insert(int index, DownloadURL value)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Remove(DownloadURL value)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void RemoveAt(int index)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void RemoveRange(int index, int count)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Reverse()
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Reverse(int index, int count)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Sort()
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Sort(IComparer comparer)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override void Sort(int index, int count, IComparer comparer)
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
public override DownloadURL[] ToArray()
|
||
|
{
|
||
|
return this._collection.ToArray();
|
||
|
}
|
||
|
|
||
|
public override void TrimToSize()
|
||
|
{
|
||
|
throw new NotSupportedException(
|
||
|
"Read-only collections cannot be modified.");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Class SyncList
|
||
|
|
||
|
[Serializable]
|
||
|
private sealed class SyncList : DownloadURLCollection
|
||
|
{
|
||
|
#region Private Fields
|
||
|
|
||
|
private DownloadURLCollection _collection;
|
||
|
private object _root;
|
||
|
|
||
|
#endregion
|
||
|
#region Internal Constructors
|
||
|
|
||
|
internal SyncList(DownloadURLCollection collection)
|
||
|
:
|
||
|
base(Tag.Default)
|
||
|
{
|
||
|
|
||
|
this._root = collection.SyncRoot;
|
||
|
this._collection = collection;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Protected Properties
|
||
|
|
||
|
protected override DownloadURL[] InnerArray
|
||
|
{
|
||
|
get { lock (this._root) return this._collection.InnerArray; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Properties
|
||
|
|
||
|
public override int Capacity
|
||
|
{
|
||
|
get { lock (this._root) return this._collection.Capacity; }
|
||
|
set { lock (this._root) this._collection.Capacity = value; }
|
||
|
}
|
||
|
|
||
|
public override int Count
|
||
|
{
|
||
|
get { lock (this._root) return this._collection.Count; }
|
||
|
}
|
||
|
|
||
|
public override bool IsFixedSize
|
||
|
{
|
||
|
get { return this._collection.IsFixedSize; }
|
||
|
}
|
||
|
|
||
|
public override bool IsReadOnly
|
||
|
{
|
||
|
get { return this._collection.IsReadOnly; }
|
||
|
}
|
||
|
|
||
|
public override bool IsSynchronized
|
||
|
{
|
||
|
get { return true; }
|
||
|
}
|
||
|
|
||
|
public override bool IsUnique
|
||
|
{
|
||
|
get { return this._collection.IsUnique; }
|
||
|
}
|
||
|
|
||
|
public override DownloadURL this[int index]
|
||
|
{
|
||
|
get { lock (this._root) return this._collection[index]; }
|
||
|
set { lock (this._root) this._collection[index] = value; }
|
||
|
}
|
||
|
|
||
|
public override object SyncRoot
|
||
|
{
|
||
|
get { return this._root; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Methods
|
||
|
|
||
|
public override int Add(DownloadURL value)
|
||
|
{
|
||
|
lock (this._root) return this._collection.Add(value);
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURLCollection collection)
|
||
|
{
|
||
|
lock (this._root) this._collection.AddRange(collection);
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURL[] array)
|
||
|
{
|
||
|
lock (this._root) this._collection.AddRange(array);
|
||
|
}
|
||
|
|
||
|
public override int BinarySearch(DownloadURL value)
|
||
|
{
|
||
|
lock (this._root) return this._collection.BinarySearch(value);
|
||
|
}
|
||
|
|
||
|
public override void Clear()
|
||
|
{
|
||
|
lock (this._root) this._collection.Clear();
|
||
|
}
|
||
|
|
||
|
public override object Clone()
|
||
|
{
|
||
|
lock (this._root)
|
||
|
return new SyncList((DownloadURLCollection)this._collection.Clone());
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array)
|
||
|
{
|
||
|
lock (this._root) this._collection.CopyTo(array);
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array, int arrayIndex)
|
||
|
{
|
||
|
lock (this._root) this._collection.CopyTo(array, arrayIndex);
|
||
|
}
|
||
|
|
||
|
public override DownloadURLCollection.Enumerator GetEnumerator()
|
||
|
{
|
||
|
lock (this._root) return this._collection.GetEnumerator();
|
||
|
}
|
||
|
|
||
|
public override int IndexOf(DownloadURL value)
|
||
|
{
|
||
|
lock (this._root) return this._collection.IndexOf(value);
|
||
|
}
|
||
|
|
||
|
public override void Insert(int index, DownloadURL value)
|
||
|
{
|
||
|
lock (this._root) this._collection.Insert(index, value);
|
||
|
}
|
||
|
|
||
|
public override void Remove(DownloadURL value)
|
||
|
{
|
||
|
lock (this._root) this._collection.Remove(value);
|
||
|
}
|
||
|
|
||
|
public override void RemoveAt(int index)
|
||
|
{
|
||
|
lock (this._root) this._collection.RemoveAt(index);
|
||
|
}
|
||
|
|
||
|
public override void RemoveRange(int index, int count)
|
||
|
{
|
||
|
lock (this._root) this._collection.RemoveRange(index, count);
|
||
|
}
|
||
|
|
||
|
public override void Reverse()
|
||
|
{
|
||
|
lock (this._root) this._collection.Reverse();
|
||
|
}
|
||
|
|
||
|
public override void Reverse(int index, int count)
|
||
|
{
|
||
|
lock (this._root) this._collection.Reverse(index, count);
|
||
|
}
|
||
|
|
||
|
public override void Sort()
|
||
|
{
|
||
|
lock (this._root) this._collection.Sort();
|
||
|
}
|
||
|
|
||
|
public override void Sort(IComparer comparer)
|
||
|
{
|
||
|
lock (this._root) this._collection.Sort(comparer);
|
||
|
}
|
||
|
|
||
|
public override void Sort(int index, int count, IComparer comparer)
|
||
|
{
|
||
|
lock (this._root) this._collection.Sort(index, count, comparer);
|
||
|
}
|
||
|
|
||
|
public override DownloadURL[] ToArray()
|
||
|
{
|
||
|
lock (this._root) return this._collection.ToArray();
|
||
|
}
|
||
|
|
||
|
public override void TrimToSize()
|
||
|
{
|
||
|
lock (this._root) this._collection.TrimToSize();
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Class UniqueList
|
||
|
|
||
|
[Serializable]
|
||
|
private sealed class UniqueList : DownloadURLCollection
|
||
|
{
|
||
|
#region Private Fields
|
||
|
|
||
|
private DownloadURLCollection _collection;
|
||
|
|
||
|
#endregion
|
||
|
#region Internal Constructors
|
||
|
|
||
|
internal UniqueList(DownloadURLCollection collection)
|
||
|
:
|
||
|
base(Tag.Default)
|
||
|
{
|
||
|
this._collection = collection;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Protected Properties
|
||
|
|
||
|
protected override DownloadURL[] InnerArray
|
||
|
{
|
||
|
get { return this._collection.InnerArray; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Properties
|
||
|
|
||
|
public override int Capacity
|
||
|
{
|
||
|
get { return this._collection.Capacity; }
|
||
|
set { this._collection.Capacity = value; }
|
||
|
}
|
||
|
|
||
|
public override int Count
|
||
|
{
|
||
|
get { return this._collection.Count; }
|
||
|
}
|
||
|
|
||
|
public override bool IsFixedSize
|
||
|
{
|
||
|
get { return this._collection.IsFixedSize; }
|
||
|
}
|
||
|
|
||
|
public override bool IsReadOnly
|
||
|
{
|
||
|
get { return this._collection.IsReadOnly; }
|
||
|
}
|
||
|
|
||
|
public override bool IsSynchronized
|
||
|
{
|
||
|
get { return this._collection.IsSynchronized; }
|
||
|
}
|
||
|
|
||
|
public override bool IsUnique
|
||
|
{
|
||
|
get { return true; }
|
||
|
}
|
||
|
|
||
|
public override DownloadURL this[int index]
|
||
|
{
|
||
|
get { return this._collection[index]; }
|
||
|
set
|
||
|
{
|
||
|
CheckUnique(index, value);
|
||
|
this._collection[index] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override object SyncRoot
|
||
|
{
|
||
|
get { return this._collection.SyncRoot; }
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Public Methods
|
||
|
|
||
|
public override int Add(DownloadURL value)
|
||
|
{
|
||
|
CheckUnique(value);
|
||
|
return this._collection.Add(value);
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURLCollection collection)
|
||
|
{
|
||
|
foreach (DownloadURL value in collection)
|
||
|
CheckUnique(value);
|
||
|
|
||
|
this._collection.AddRange(collection);
|
||
|
}
|
||
|
|
||
|
public override void AddRange(DownloadURL[] array)
|
||
|
{
|
||
|
foreach (DownloadURL value in array)
|
||
|
CheckUnique(value);
|
||
|
|
||
|
this._collection.AddRange(array);
|
||
|
}
|
||
|
|
||
|
public override int BinarySearch(DownloadURL value)
|
||
|
{
|
||
|
return this._collection.BinarySearch(value);
|
||
|
}
|
||
|
|
||
|
public override void Clear()
|
||
|
{
|
||
|
this._collection.Clear();
|
||
|
}
|
||
|
|
||
|
public override object Clone()
|
||
|
{
|
||
|
return new UniqueList((DownloadURLCollection)this._collection.Clone());
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array)
|
||
|
{
|
||
|
this._collection.CopyTo(array);
|
||
|
}
|
||
|
|
||
|
public override void CopyTo(DownloadURL[] array, int arrayIndex)
|
||
|
{
|
||
|
this._collection.CopyTo(array, arrayIndex);
|
||
|
}
|
||
|
|
||
|
public override DownloadURLCollection.Enumerator GetEnumerator()
|
||
|
{
|
||
|
return this._collection.GetEnumerator();
|
||
|
}
|
||
|
|
||
|
public override int IndexOf(DownloadURL value)
|
||
|
{
|
||
|
return this._collection.IndexOf(value);
|
||
|
}
|
||
|
|
||
|
public override void Insert(int index, DownloadURL value)
|
||
|
{
|
||
|
CheckUnique(value);
|
||
|
this._collection.Insert(index, value);
|
||
|
}
|
||
|
|
||
|
public override void Remove(DownloadURL value)
|
||
|
{
|
||
|
this._collection.Remove(value);
|
||
|
}
|
||
|
|
||
|
public override void RemoveAt(int index)
|
||
|
{
|
||
|
this._collection.RemoveAt(index);
|
||
|
}
|
||
|
|
||
|
public override void RemoveRange(int index, int count)
|
||
|
{
|
||
|
this._collection.RemoveRange(index, count);
|
||
|
}
|
||
|
|
||
|
public override void Reverse()
|
||
|
{
|
||
|
this._collection.Reverse();
|
||
|
}
|
||
|
|
||
|
public override void Reverse(int index, int count)
|
||
|
{
|
||
|
this._collection.Reverse(index, count);
|
||
|
}
|
||
|
|
||
|
public override void Sort()
|
||
|
{
|
||
|
this._collection.Sort();
|
||
|
}
|
||
|
|
||
|
public override void Sort(IComparer comparer)
|
||
|
{
|
||
|
this._collection.Sort(comparer);
|
||
|
}
|
||
|
|
||
|
public override void Sort(int index, int count, IComparer comparer)
|
||
|
{
|
||
|
this._collection.Sort(index, count, comparer);
|
||
|
}
|
||
|
|
||
|
public override DownloadURL[] ToArray()
|
||
|
{
|
||
|
return this._collection.ToArray();
|
||
|
}
|
||
|
|
||
|
public override void TrimToSize()
|
||
|
{
|
||
|
this._collection.TrimToSize();
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
#region Private Methods
|
||
|
|
||
|
private void CheckUnique(DownloadURL value)
|
||
|
{
|
||
|
if (IndexOf(value) >= 0)
|
||
|
throw new NotSupportedException(
|
||
|
"Unique collections cannot contain duplicate elements.");
|
||
|
}
|
||
|
|
||
|
private void CheckUnique(int index, DownloadURL value)
|
||
|
{
|
||
|
int existing = IndexOf(value);
|
||
|
if (existing >= 0 && existing != index)
|
||
|
throw new NotSupportedException(
|
||
|
"Unique collections cannot contain duplicate elements.");
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
}
|