dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/Generics Algorithm.cs,NONE,1.1 Array


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/Generics Algorithm.cs,NONE,1.1 ArrayList.cs,NONE,1.1 BuiltinComparer.cs,NONE,1.1 CollectionAdapter.cs,NONE,1.1 CollectionWrapper.cs,NONE,1.1 ComparableAdapter.cs,NONE,1.1 ComparableWrapper.cs,NONE,1.1 Comparer.cs,NONE,1.1 ComparerAdapter.cs,NONE,1.1 ComparerWrapper.cs,NONE,1.1 Complex.cs,NONE,1.1 DictionaryAdapter.cs,NONE,1.1 DictionaryEntry.cs,NONE,1.1 DictionaryEnumeratorAdapter.cs,NONE,1.1 DictionaryEnumeratorWrapper.cs,NONE,1.1 DictionaryWrapper.cs,NONE,1.1 EnumerableAdapter.cs,NONE,1.1 EnumerableWrapper.cs,NONE,1.1 EnumeratorAdapter.cs,NONE,1.1 EnumeratorWrapper.cs,NONE,1.1 Generics.txt,NONE,1.1 HashCodeProviderAdapter.cs,NONE,1.1 HashCodeProviderWrapper.cs,NONE,1.1 Hashtable.cs,NONE,1.1 ICollection.cs,NONE,1.1 IComparable.cs,NONE,1.1 IComparer.cs,NONE,1.1 IDictionary.cs,NONE,1.1 IDictionaryEnumerator.cs,NONE,1.1 IEnumerable.cs,NONE,1.1 IEnumerator.cs,NONE,1.1 IHashCodeProvider.cs,NONE,1.1 IIterable.cs,NONE,1.1 IIterator.cs,NONE,1.1 IList.cs,NONE,1.1 List.cs,NONE,1.1 ListAdapter.cs,NONE,1.1 ListWrapper.cs,NONE,1.1 Predicate.cs,NONE,1.1 Queue.cs,NONE,1.1 README,NONE,1.1 ReverseIterator.cs,NONE,1.1 S.cs,NONE,1.1 Stack.cs,NONE,1.1 SynchronizedDictEnumerator.cs,NONE,1.1 SynchronizedEnumerator.cs,NONE,1.1 SynchronizedIterator.cs,NONE,1.1
Date: Fri, 21 Feb 2003 21:56:22 -0500

Update of /cvsroot/dotgnu-pnet/pnetlib/Generics
In directory subversions:/tmp/cvs-serv9980/Generics

Added Files:
        Algorithm.cs ArrayList.cs BuiltinComparer.cs 
        CollectionAdapter.cs CollectionWrapper.cs ComparableAdapter.cs 
        ComparableWrapper.cs Comparer.cs ComparerAdapter.cs 
        ComparerWrapper.cs Complex.cs DictionaryAdapter.cs 
        DictionaryEntry.cs DictionaryEnumeratorAdapter.cs 
        DictionaryEnumeratorWrapper.cs DictionaryWrapper.cs 
        EnumerableAdapter.cs EnumerableWrapper.cs EnumeratorAdapter.cs 
        EnumeratorWrapper.cs Generics.txt HashCodeProviderAdapter.cs 
        HashCodeProviderWrapper.cs Hashtable.cs ICollection.cs 
        IComparable.cs IComparer.cs IDictionary.cs 
        IDictionaryEnumerator.cs IEnumerable.cs IEnumerator.cs 
        IHashCodeProvider.cs IIterable.cs IIterator.cs IList.cs 
        List.cs ListAdapter.cs ListWrapper.cs Predicate.cs Queue.cs 
        README ReverseIterator.cs S.cs Stack.cs 
        SynchronizedDictEnumerator.cs SynchronizedEnumerator.cs 
        SynchronizedIterator.cs 
Log Message:


Initial check-in of the generic C# collection library.


--- NEW FILE ---
/*
 * Algorithm.cs - Useful generic algorithms.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public class Algorithm
{

        // Swap two items.
        public static void Swap<T>(ref T x, ref T y)
                        {
                                T temp = x;
                                x = y;
                                y = temp;
                        }

        // Swap two items, defined by iterator positions.
        public static void Swap<T>(IIterator<T> iter1, IIterator<T> iter2)
                        {
                                T temp = iter1.Current;
                                iter1.Current = iter2.Current;
                                iter2.Current = temp;
                        }

        // Determine the minimum of two items.
        public static T Min<T>(T x, T y)
                        {
                                if(x < y)
                                {
                                        return x;
                                }
                                else
                                {
                                        return y;
                                }
                        }
        public static T Min<T>(T x, T y, IComparer<T> cmp)
                        {
                                if(cmp.Compare(x, y) < 0)
                                {
                                        return x;
                                }
                                else
                                {
                                        return y;
                                }
                        }

        // Determine the maximum of two items.
        public static T Max<T>(T x, T y)
                        {
                                if(x > y)
                                {
                                        return x;
                                }
                                else
                                {
                                        return y;
                                }
                        }
        public static T Max<T>(T x, T y, IComparer<T> cmp)
                        {
                                if(cmp.Compare(x, y) > 0)
                                {
                                        return x;
                                }
                                else
                                {
                                        return y;
                                }
                        }

        // Determine the median of three values.
        public static T Median<T>(T x, T y, T z)
                        {
                                if(x < y)
                                {
                                        if(y < z)
                                        {
                                                return y;
                                        }
                                        else if(x < z)
                                        {
                                                return z;
                                        }
                                        else
                                        {
                                                return x;
                                        }
                                }
                                else if(x < z)
                                {
                                        return x;
                                }
                                else if(y < z)
                                {
                                        return z;
                                }
                                else
                                {
                                        return y;
                                }
                        }
        public static T Median<T>(T x, T y, T z, IComparer<T> cmp)
                        {
                                if(cmp.Compare(x, y) < 0)
                                {
                                        if(cmp.Compare(y, z) < 0)
                                        {
                                                return y;
                                        }
                                        else if(cmp.Compare(x, z) < 0)
                                        {
                                                return z;
                                        }
                                        else
                                        {
                                                return x;
                                        }
                                }
                                else if(cmp.Compare(x, z) < 0)
                                {
                                        return x;
                                }
                                else if(cmp.Compare(y, z) < 0)
                                {
                                        return z;
                                }
                                else
                                {
                                        return y;
                                }
                        }

        // Determine if the content of two enumerations are equal.
        public static bool Equals<T>(IEnumerator<T> e1, IEnumerator<T> e2)
                        {
                                for(;;)
                                {
                                        if(!e1.MoveNext())
                                        {
                                                return !(e2.MoveNext());
                                        }
                                        if(!e2.MoveNext())
                                        {
                                                return false;
                                        }
                                        if(e1.Current != e2.Current)
                                        {
                                                return false;
                                        }
                                }
                        }
        public static bool Equals<T>(IEnumerator<T> e1, IEnumerator<T> e2,
                                                                 IComparer<T> 
cmp)
                        {
                                for(;;)
                                {
                                        if(!e1.MoveNext())
                                        {
                                                return !(e2.MoveNext());
                                        }
                                        if(!e2.MoveNext())
                                        {
                                                return false;
                                        }
                                        if(cmp.Compare(e1.Current, e2.Current) 
!= 0)
                                        {
                                                return false;
                                        }
                                }
                        }

        // Determine if the content of two enumerations are not equal.
        public static bool NotEquals<T>(IEnumerator<T> e1, IEnumerator<T> e2)
                        {
                                for(;;)
                                {
                                        if(!e1.MoveNext())
                                        {
                                                return e2.MoveNext();
                                        }
                                        if(!e2.MoveNext())
                                        {
                                                return true;
                                        }
                                        if(e1.Current == e2.Current)
                                        {
                                                return false;
                                        }
                                }
                        }
        public static bool NotEquals<T>(IEnumerator<T> e1, IEnumerator<T> e2,
                                                                    
IComparer<T> cmp)
                        {
                                for(;;)
                                {
                                        if(!e1.MoveNext())
                                        {
                                                return e2.MoveNext();
                                        }
                                        if(!e2.MoveNext())
                                        {
                                                return true;
                                        }
                                        if(cmp.Compare(e1.Current, e2.Current) 
== 0)
                                        {
                                                return false;
                                        }
                                }
                        }

        // Determine if two collections are equal.
        public static bool Equals<T>(ICollection<T> c1, ICollection<T> c2)
                        {
                                return Equals<T>(c1.GetEnumerator(), 
c2.GetEnumerator());
                        }
        public static bool Equals<T>(ICollection<T> c1, ICollection<T> c2,
                                                                 IComparer<T> 
cmp)
                        {
                                return Equals<T>(c1.GetEnumerator(), 
c2.GetEnumerator(), cmp);
                        }

        // Determine if two collections are not equal.
        public static bool NotEquals<T>(ICollection<T> c1, ICollection<T> c2)
                        {
                                return NotEquals<T>(c1.GetEnumerator(), 
c2.GetEnumerator());
                        }
        public static bool NotEquals<T>(ICollection<T> c1, ICollection<T> c2,
                                                                    
IComparer<T> cmp)
                        {
                                return NotEquals<T>(c1.GetEnumerator(),
                                                                        
c2.GetEnumerator(), cmp);
                        }

        // Find a particular value in an enumeration, beginning with
        // the next item.  The enumerator will be positioned on the
        // found value, or the end of the enumeration.
        public static bool Find<T>(IEnumerator<T> e, T value)
                        {
                                while(e.MoveNext())
                                {
                                        if(e.Current == value)
                                        {
                                                return true;
                                        }
                                }
                                return false;
                        }
        public static bool Find<T>(IEnumerator<T> e, T value, IComparer<T> cmp)
                        {
                                while(e.MoveNext())
                                {
                                        if(cmp.Compare(e.Current, value) == 0)
                                        {
                                                return true;
                                        }
                                }
                                return false;
                        }

        // Find the position within an enumeration that satisfies a
        // particular predicate condition.
        public static bool Find<T>(IEnumerator<T> e, Predicate<T> pred)
                        {
                                while(e.MoveNext())
                                {
                                        if(pred(e.Current))
                                        {
                                                return true;
                                        }
                                }
                                return false;
                        }

}; // class Algorithm

}; // namespace Generics

--- NEW FILE ---
/*
 * ArrayList.cs - Generic array list class.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
[...2395 lines suppressed...]
                                        lock(SyncRoot)
                                        {
                                                return new 
SynchronizedIterator<T>
                                                        (SyncRoot, 
list.GetIterator());
                                        }
                                }
                public override IIterator<T> GetIterator(int index, int count)
                                {
                                        lock(SyncRoot)
                                        {
                                                return new 
SynchronizedIterator<T>
                                                        (SyncRoot, 
list.GetIterator(index, count));
                                        }
                                }

        }; // class SynchronizedWrapper<T>

}; // class ArrayList<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * BuiltinComparer.cs - Default generic comparer implementation.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class BuiltinComparer<T> : IComparer<T>
{

        // Compare two items using the builtin comparison operators.
        public int Compare(T x, T y)
                        {
                                if(x < y)
                                {
                                        return -1;
                                }
                                else if(x > y)
                                {
                                        return 1;
                                }
                                else
                                {
                                        return 0;
                                }
                        }

}; // class BuiltinComparer<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * CollectionAdapter.cs - Adapt a generic collection into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class CollectionAdapter<T>
        : System.Collections.ICollection, System.Collections.IEnumerable
{

        // Internal state.
        private ICollection<T> coll;

        // Constructor.
        public CollectionAdapter(ICollection<T> coll)
                        {
                                if(coll == null)
                                {
                                        throw new ArgumentNullException("coll");
                                }
                                this.coll = coll;
                        }

        // Implement the non-generic ICollection interface.
        public void CopyTo(Array array, int index)
                        {
                                IEnumerator<T> e = coll.GetEnumerator();
                                while(e.MoveNext())
                                {
                                        array.SetValue(e.Current, index++);
                                }
                        }
        public int Count
                        {
                                get
                                {
                                        return coll.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return coll.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return coll.SyncRoot;
                                }
                        }

        // Implement the non-generic IEnumerable interface.
        public System.Collections.IEnumerator GetEnumerator()
                        {
                                return new 
EnumeratorAdapter<T>(coll.GetEnumerator());
                        }

}; // class CollectionAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * CollectionWrapper.cs - Wrap a non-generic collection and make it generic.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class CollectionWrapper<T> : ICollection<T>
{
        // Internal state.
        private System.Collections.ICollection coll;

        // Constructor.
        public CollectionWrapper(System.Collections.ICollection coll)
                        {
                                if(coll == null)
                                {
                                        throw new ArgumentNullException("coll");
                                }
                                this.coll = coll;
                        }

        // Implement the ICollection<T> interface.
        public void CopyTo(T[] array, int index)
                        {
                                coll.CopyTo(array, index);
                        }
        public int Count
                        {
                                get
                                {
                                        return coll.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return coll.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return coll.SyncRoot;
                                }
                        }

        // Implement the IEnumerable<T> interface.
        public IEnumerator<T> GetEnumerator()
                        {
                                return new 
EnumeratorWrapper(coll.GetEnumerator());
                        }

}; // class CollectionWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ComparableAdapter.cs - Adapt a generic compable into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ComparableAdapter<T> : System.Collections.IComparable
{

        // Internal state.
        private IComparable<T> cmp;

        // Constructor.
        public ComparableAdapter(IComparable<T> cmp)
                        {
                                if(cmp == null)
                                {
                                        throw new ArgumentNullException("cmp");
                                }
                                this.cmp = cmp;
                        }

        // Implement the non-generic IComparable interface.
        public int CompareTo(Object obj)
                        {
                                return cmp.CompareTo((T)obj);
                        }

}; // class ComparableAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ComparableWrapper.cs - Wrap a non-generic compable and make it generic.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ComparableWrapper<T> : IComparable<T>
{

        // Internal state.
        private System.Collections.IComparable cmp;

        // Constructor.
        public ComparableWrapper(System.Collections.IComparable cmp)
                        {
                                if(cmp == null)
                                {
                                        throw new ArgumentNullException("cmp");
                                }
                                this.cmp = cmp;
                        }

        // Implement the IComparable<T> interface.
        public int CompareTo(T obj)
                        {
                                return cmp.CompareTo(obj);
                        }

}; // class ComparableWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * Comparer.cs - Default generic comparer implementation.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class Comparer<T> : IComparer<T>
{

        // Compare two items using the IComparable<T> or IComparable interfaces.
        public int Compare(T a, T b)
                        {
                                IComparable<T> cmp;
                                System.IComparable cmp2;

                                // Deal with the "null" cases if T is not a 
value type.
                                if(!(typeof(T).IsValueType))
                                {
                                        if(a == null)
                                        {
                                                if(b == null)
                                                {
                                                        return 0;
                                                }
                                                else
                                                {
                                                        return -1;
                                                }
                                        }
                                        else if(b == null)
                                        {
                                                return 1;
                                        }
                                }

                                // Try using the IComparable<T> interface.
                                cmp = (a as IComparable<T>);
                                if(cmp != null)
                                {
                                        return cmp.CompareTo(b);
                                }
                                cmp = (b as IComparable<T>);
                                if(cmp != null)
                                {
                                        return -(cmp.CompareTo(a));
                                }

                                // Try using the System.IComparable interface.
                                cmp2 = (a as System.IComparable);
                                if(cmp2 != null)
                                {
                                        return cmp2.CompareTo(b);
                                }
                                cmp2 = (b as System.IComparable);
                                if(cmp2 != null)
                                {
                                        return -(cmp2.CompareTo(a));
                                }

                                // We were unable to compare the values.
                                throw new 
ArgumentException(_("Arg_ABMustBeComparable"));
                        }

}; // class Comparer<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ComparerAdapter.cs - Adapt a generic comparer into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ComparerAdapter<T> : System.Collections.IComparer
{

        // Internal state.
        private IComparer<T> cmp;

        // Constructor.
        public ComparerAdapter(IComparer<T> cmp)
                        {
                                if(cmp == null)
                                {
                                        throw new ArgumentNullException("cmp");
                                }
                                this.cmp = cmp;
                        }

        // Implement the non-generic IComparer interface.
        public int Compare(Object x, Object y)
                        {
                                return cmp.Compare((T)x, (T)y);
                        }

}; // class ComparerAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ComparerWrapper.cs - Wrap a non-generic comparer and make it generic.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ComparerWrapper<T> : IComparer<T>
{

        // Internal state.
        private System.Collections.IComparer cmp;

        // Constructor.
        public ComparerWrapper(System.Collections.IComparer cmp)
                        {
                                if(cmp == null)
                                {
                                        throw new ArgumentNullException("cmp");
                                }
                                this.cmp = cmp;
                        }

        // Implement the IComparer<T> interface.
        public int Compare(T x, T y)
                        {
                                return cmp.Compare(x, y);
                        }

}; // class ComparerWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * Complex.cs - Generic complex number types.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

// It only makes sense to use Complex<T> on a numeric type that can
// be explicitly converted to and from "double".  Other types may
// lead to verification errors at runtime.

public struct Complex<T>
{
        // Internal state.
        private T real, imag;

        // Constructor.
        public Complex(T real, T imag)
                        {
                                this.real = real;
                                this.imag = imag;
                        }

        // Extract the real and imaginary components.
        public T Real
                        {
                                get
                                {
                                        return real;
                                }
                        }
        public T Imag
                        {
                                get
                                {
                                        return imag;
                                }
                        }

        // Basic arithmetic operators.
        public static Complex<T> operator+<T>(Complex<T> x, Complex<T> y)
                        {
                                return new Complex<T>(x.real + y.real, x.imag + 
y.imag);
                        }
        public static Complex<T> operator-<T>(Complex<T> x, Complex<T> y)
                        {
                                return new Complex<T>(x.real - y.real, x.imag - 
y.imag);
                        }
        public static Complex<T> operator*<T>(Complex<T> x, Complex<T> y)
                        {
                                return new Complex<T>(x.real * y.real - x.imag 
* y.imag,
                                                                          
x.real * y.imag + x.imag * y.real);
                        }
        public static Complex<T> operator/<T>(Complex<T> x, Complex<T> y)
                        {
                                T div = y.real * y.real + y.imag * y.imag;
                                return new Complex<T>
                                                ((x.real * y.real + x.imag * 
y.imag) / div,
                                                 (x.imag * y.real - x.real * 
y.imag) / div);
                        }
        public static Complex<T> operator-<T>(Complex<T> x)
                        {
                                return new Complex<T>(-(x.real), -(y.real));
                        }

        // Comparison operators.
        public static bool operator==<T>(Complex<T> x, Complex<T> y)
                        {
                                return (x.real == y.real && x.imag == y.imag);
                        }
        public static bool operator!=<T>(Complex<T> x, Complex<T> y)
                        {
                                return (x.real != y.real || x.imag != y.imag);
                        }

        // Conversion operators.
        public static implicit operator<T> Complex<T>(T x)
                        {
                                return new Complex<T>(x, 0);
                        }
        public static explicit operator<T> T(Complex<T> x)
                        {
                                return x.real;
                        }

        // Get the absolute value of a complex number.
        public T Abs()
                        {
                                return (T)(Math.Sqrt((double)(real * real + 
imag * imag)));
                        }

        // Get the conjugate form of a complex number.
        public Complex<T> Conj()
                        {
                                return new Complex<T>(x.real, -(y.real));
                        }

        // Create a complex number from polar co-ordinates.
        public static Complex<T> FromPolar<T>(T r, T t)
                        {
                                return new Complex<T>((T)(((double)r) * 
Math.Cos((double)t)),
                                                                          
(T)(((double)r) * Math.Sin((double)t)));
                        }

}; // struct Complex

}; // namespace Generics

--- NEW FILE ---
/*
 * DictionaryAdapter.cs - Adapt a generic dictionary into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class DictionaryAdapter<KeyT, ValueT>
        : System.Collections.IDictionary, System.Collections.ICollection,
          System.Collections.IEnumerable
{

        // Internal state.
        private IDictionary<KeyT, ValueT> dict;

        // Constructor.
        public DictionaryAdapter(IDictionary<KeyT, ValueT> dict)
                        {
                                if(dict == null)
                                {
                                        throw new ArgumentNullException("dict");
                                }
                                this.dict = dict;
                        }

        // Implement the non-generic IDictionary interface.
        public void Add(Object key, Object value)
                        {
                                if(key == null)
                                {
                                        // Cannot use null keys with 
non-generic dictionaries.
                                        throw new ArgumentNullException("key");
                                }
                                else if(!(key is KeyT))
                                {
                                        // Wrong type of key to add to this 
dictionary.
                                        throw new InvalidOperationException
                                                (S._("Invalid_KeyType"));
                                }
                                if(typeof(ValueT).IsValueType)
                                {
                                        if(value == null || !(value is ValueT))
                                        {
                                                // Wrong type of value to add 
to this dictionary.
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_ValueType"));
                                        }
                                }
                                else
                                {
                                        if(value != null && !(value is ValueT))
                                        {
                                                // Wrong type of value to add 
to this dictionary.
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_ValueType"));
                                        }
                                }
                                dict.Add((KeyT)key, (ValueT)value);
                        }
        public void Clear()
                        {
                                dict.Clear();
                        }
        public bool Contains(Object key)
                        {
                                if(key == null)
                                {
                                        throw new ArgumentNullException("key");
                                }
                                else if(key is KeyT)
                                {
                                        return dict.Contains((KeyT)key);
                                }
                                else
                                {
                                        return false;
                                }
                        }
        public IDictionaryEnumerator GetEnumerator()
                        {
                                return new 
DictionaryEnumeratorAdapter(dict.GetEnumerator());
                        }
        public void Remove(Object key)
                        {
                                if(key == null)
                                {
                                        throw new ArgumentNullException("key");
                                }
                                else if(key is KeyT)
                                {
                                        dict.Remove((KeyT)key);
                                }
                        }
        public bool IsFixedSize
                        {
                                get
                                {
                                        return dict.IsFixedSize;
                                }
                        }
        public bool IsReadOnly
                        {
                                get
                                {
                                        return dict.IsReadOnly;
                                }
                        }
        public Object this[Object key]
                        {
                                get
                                {
                                        return dict[(KeyT)key];
                                }
                                set
                                {
                                        if(key == null)
                                        {
                                                // Cannot use null keys with 
non-generic dictionaries.
                                                throw new 
ArgumentNullException("key");
                                        }
                                        else if(!(key is KeyT))
                                        {
                                                // Wrong type of key to add to 
this dictionary.
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_KeyType"));
                                        }
                                        if(typeof(ValueT).IsValueType)
                                        {
                                                if(value == null || !(value is 
ValueT))
                                                {
                                                        // Wrong type of value 
to add to this dictionary.
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_ValueType"));
                                                }
                                        }
                                        else
                                        {
                                                if(value != null && !(value is 
ValueT))
                                                {
                                                        // Wrong type of value 
to add to this dictionary.
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_ValueType"));
                                                }
                                        }
                                        dict[(KeyT)key] = (ValueT)value;
                                }
                        }
        public ICollection Keys
                        {
                                get
                                {
                                        return new 
CollectionAdapter<KeyT>(dict.Keys);
                                }
                        }
        public ICollection Values
                        {
                                get
                                {
                                        return new 
CollectionAdapter<ValueT>(dict.Values);
                                }
                        }

        // Implement the non-generic ICollection interface.
        public void CopyTo(Array array, int index)
                        {
                                IDictionaryEnumerator<KeyT, ValueT> e = 
dict.GetEnumerator();
                                while(e.MoveNext())
                                {
                                        array.SetValue(e.Value, index++);
                                }
                        }
        public int Count
                        {
                                get
                                {
                                        return dict.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return dict.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return dict.SyncRoot;
                                }
                        }

        // Implement the non-generic IEnumerable interface.
        public System.Collections.IEnumerator
                                System.Collections.IEnumerable.GetEnumerator()
                        {
                                return new EnumeratorAdapter<ValueT>
                                        
(((ICollection<ValueT>)dict).GetEnumerator());
                        }

}; // class DictionaryAdapter<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * DictionaryEntry.cs - Generic dictionary entries.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public struct DictionaryEntry<KeyT, ValueT>
{
        // Instance fields.  "key_" is an Object so that we can detect null 
values.
        private Object key_;
        private ValueT value_;

        // Construct a dictionary entry.
        public DictionaryEntry(KeyT key, ValueT value)
                        {
                                key_ = key;
                                if(key_ == null)
                                {
                                        throw new ArgumentNullException("key");
                                }
                                value_ = value;
                        }

        // DictionaryEntry properties.
        public KeyT Key
                        {
                                get
                                {
                                        return (KeyT)key_;
                                }
                                set
                                {
                                        key_ = value;
                                        if(key_ == null)
                                        {
                                                throw new 
ArgumentNullException("value");
                                        }
                                }
                        }
        public ValueT Value
                        {
                                get
                                {
                                        return value_;
                                }
                                set
                                {
                                        value_ = value;
                                }
                        }

}; // struct DictionaryEntry<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * DictionaryEnumeratorAdapter.cs - Adapt a generic dictionary enumerator
 *              into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class DictionaryEnumeratorAdapter<KeyT, ValueT>
        : System.Collections.IDictionaryEnumerator, 
System.Collections.IEnumerator
{

        // Internal state.
        private IDictionaryEnumerator<KeyT, ValueT> e;

        // Constructor.
        public DictionaryEnumeratorAdapter(IDictionaryEnumerator<KeyT, ValueT> 
e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the non-generic IEnumerator interface.
        public bool MoveNext()
                        {
                                return e.MoveNext();
                        }
        public void Reset()
                        {
                                e.Reset();
                        }
        public Object Current
                        {
                                get
                                {
                                        return e.Current;
                                }
                        }

        // Implement the non-generic IDictionaryEnumerator interface.
        public System.Collections.DictionaryEntry Entry
                        {
                                get
                                {
                                        DictionaryEntry<KeyT, ValueT> entry = 
e.Entry;
                                        return new 
System.Collections.DictionaryEntry
                                                (e.Key, e.Value);
                                }
                        }
        public Object Key
                        {
                                get
                                {
                                        return e.Key;
                                }
                        }
        public Object Value
                        {
                                get
                                {
                                        return e.Value;
                                }
                        }

}; // class DictionaryEnumeratorAdapter<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * DictionaryEnumeratorWrapper.cs - Wrap a non-generic dictionary enumerator
 *              to turn it into a generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class DictionaryEnumeratorWrapper<KeyT, ValueT>
        : IDictionaryEnumerator<KeyT, ValueT>
{

        // Internal state.
        private System.Collections.IDictionaryEnumerator e;

        // Constructor.
        public DictionaryEnumeratorWrapper
                                (System.Collections.IDictionaryEnumerator e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the IEnumerator<ValueT> interface.
        public bool MoveNext()
                        {
                                return e.MoveNext();
                        }
        public void Reset()
                        {
                                e.Reset();
                        }
        public ValueT Current
                        {
                                get
                                {
                                        // Cannot use "e.Current", because that 
is the
                                        // DictionaryEntry, not the entry's 
value.
                                        return (ValueT)(e.Value);
                                }
                        }

        // Implement the IDictionaryEnumerator<T> interface.
        public DictionaryEntry<KeyT, ValueT> Entry
                        {
                                get
                                {
                                        System.Collections.DictionaryEntry 
entry = e.Entry;
                                        return new DictionaryEntry<KeyT, 
ValueT>(e.Key, e.Value);
                                }
                        }
        public KeyT Key
                        {
                                get
                                {
                                        return (KeyT)(e.Key);
                                }
                        }
        public ValueT Value
                        {
                                get
                                {
                                        return (ValueT)(e.Value);
                                }
                        }

}; // class DictionaryEnumeratorAdapter<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * DictionaryWrapper.cs - Wrap a non-generic dictionary and make it generic.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class DictionaryWrapper<KeyT, ValueT> : IDictionary<KeyT, ValueT>
{
        // Internal state.
        private System.Collections.IDictionary dict;

        // Constructor.
        public DictionaryWrapper(System.Collections.IDictionary dict)
                        {
                                if(dict == null)
                                {
                                        throw new ArgumentNullException("dict");
                                }
                                this.dict = dict;
                        }

        // Implement the IDictionary<KeyT, ValueT> interface.
        public void Add(KeyT key, ValueT value)
                        {
                                dict.Add(key, value);
                        }
        public void Clear()
                        {
                                dict.Clear();
                        }
        public bool Contains(KeyT key)
                        {
                                return dict.Contains(key);
                        }
        public IDictionaryEnumerator<KeyT, ValueT> GetEnumerator()
                        {
                                return new DictionaryEnumeratorWrapper<KeyT, 
ValueT>
                                                (dict.GetEnumerator());
                        }
        public void Remove(KeyT key)
                        {
                                dict.Remove(key);
                        }
        public bool IsFixedSize
                        {
                                get
                                {
                                        return dict.IsFixedSize;
                                }
                        }
        public bool IsReadOnly
                        {
                                get
                                {
                                        return dict.IsReadOnly;
                                }
                        }
        public ValueT this[KeyT key]
                        {
                                get
                                {
                                        return (ValueT)(dict[key]);
                                }
                                set
                                {
                                        dict[key] = value;
                                }
                        }
        public ICollection<KeyT> Keys
                        {
                                get
                                {
                                        return new 
CollectionWrapper<KeyT>(dict.Keys);
                                }
                        }
        public ICollection<ValueT> Values
                        {
                                get
                                {
                                        return new 
CollectionWrapper<ValueT>(dict.Values);
                                }
                        }

        // Implement the ICollection<ValueT> interface.
        public void CopyTo(ValueT[] array, int index)
                        {
                                dict.CopyTo(array, index);
                        }
        public int Count
                        {
                                get
                                {
                                        return dict.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return dict.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return dict.SyncRoot;
                                }
                        }

        // Implement the IEnumerable<ValueT> interface.
        public IEnumerator<ValueT> IEnumerable<ValueT>.GetEnumerator()
                        {
                                return new EnumeratorWrapper
                                        
(((IEnumerable<ValueT>)dict).GetEnumerator());
                        }

}; // class DictionaryWrapper<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * EnumerableAdapter.cs - Adapt a generic enumerable into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class EnumerableAdapter<T> : System.Collections.IEnumerable
{

        // Internal state.
        private IEnumerable<T> e;

        // Constructor.
        public EnumerableAdapter(IEnumerable<T> e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the non-generic IEnumerable interface.
        public IEnumerator GetEnumerator()
                        {
                                return new 
EnumeratorAdapter<T>(e.GetEnumerator());
                        }

}; // class EnumerableAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * EnumerableWrapper.cs - Wrap a non-generic enumerable to turn it
 *                      into a generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class EnumerableWrapper<T> : IEnumerable<T>
{

        // Internal state.
        private System.Collections.IEnumerable e;

        // Constructor.
        public EnumerableWrapper(System.Collections.IEnumerable e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the IEnumerable<T> interface.
        public IEnumerator<T> GetEnumerator()
                        {
                                return new 
EnumeratorWrapper<T>(e.GetEnumerator());
                        }

}; // class EnumerableWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * EnumeratorAdapter.cs - Adapt a generic enumerator into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class EnumeratorAdapter<T> : System.Collections.IEnumerator
{

        // Internal state.
        private IEnumerator<T> e;

        // Constructor.
        public EnumeratorAdapter(IEnumerator<T> e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the non-generic IEnumerator interface.
        public bool MoveNext()
                        {
                                return e.MoveNext();
                        }
        public void Reset()
                        {
                                e.Reset();
                        }
        public Object Current
                        {
                                get
                                {
                                        return e.Current;
                                }
                        }

}; // class EnumeratorAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * EnumeratorWrapper.cs - Wrap a non-generic enumerator to turn it
 *                      into a generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class EnumeratorWrapper<T> : IEnumerator<T>
{

        // Internal state.
        private System.Collections.IEnumerator e;

        // Constructor.
        public EnumeratorWrapper(System.Collections.IEnumerator e)
                        {
                                if(e == null)
                                {
                                        throw new ArgumentNullException("e");
                                }
                                this.e = e;
                        }

        // Implement the IEnumerator<T> interface.
        public bool MoveNext()
                        {
                                return e.MoveNext();
                        }
        public void Reset()
                        {
                                e.Reset();
                        }
        public T Current
                        {
                                get
                                {
                                        return (T)(e.Current);
                                }
                        }

}; // class EnumeratorWrapper<T>

}; // namespace Generics

--- NEW FILE ---
#
# Generics.txt - String resources for the "Generics" library.
#
# Copyright (c) 2003  Southern Storm Software, Pty Ltd
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
Arg_ABMustBeComparable=a or b must implement IComparable<T>
Arg_InvalidArrayIndex=Array index is invalid
Arg_InvalidArrayRange=Array range is invalid
ArgRange_Array=Array position or length is out of range
ArgRange_HashLoadFactor=Invalid hash table load factor
ArgRange_NonNegative=Value must not be negative
ArgRange_QueueGrowFactor=Invalid growth factor for queues
Invalid_BadEnumeratorPosition=The enumerator is not positioned on an element
Invalid_BadIteratorPosition=The iterator is not positioned on an element
Invalid_CollectionModified=The collection has been modified
Invalid_EmptyQueue=The requested operation is invalid on an empty queue
Invalid_EmptyStack=The requested operation is invalid on an empty stack
Invalid_EmptyList=The requested operation is invalid on an empty list
Invalid_KeyType=Invalid type for dictionary key
Invalid_UnderlyingModified=The underlying collection has been modified
Invalid_ValueType=Invalid type for collection value
NotSupp_FixedSizeCollection=Operation not supported on fixed sized objects
NotSupp_ReadOnly=Operation not supported on read-only objects

--- NEW FILE ---
/*
 * HashCodeProviderAdapter.cs - Adapt a generic hash code provider
 *                      into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class HashCodeProviderAdapter<T>
        : System.Collections.IHashCodeProvider
{

        // Internal state.
        private IHashCodeProvider<T> provider;

        // Constructor.
        public HashCodeProviderAdapter(IHashCodeProvider<T> provider)
                        {
                                if(provider == null)
                                {
                                        throw new 
ArgumentNullException("provider");
                                }
                                this.provider = provider;
                        }

        // Implement the non-generic IHashCodeProvider interface.
        public int GetHashCode(Object obj)
                        {
                                return provider.GetHashCode((T)obj);
                        }

}; // class HashCodeProviderAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * HashCodeProviderWrapper.cs - Wrap a non-generic hash code provider
 *                      to turn it into a generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class HashCodeProviderWrapper<T> : IHashCodeProvider<T>
{

        // Internal state.
        private System.Collections.IHashCodeProvider provider;

        // Constructor.
        public HashCodeProviderWrapper
                                (System.Collections.IHashCodeProvider provider)
                        {
                                if(provider == null)
                                {
                                        throw new 
ArgumentNullException("provider");
                                }
                                this.provider = provider;
                        }

        // Implement the IHashCodeProvider<T> interface.
        public int GetHashCode(T obj)
                        {
                                return provider.GetHashCode(obj);
                        }

}; // class HashCodeProviderWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * Hashtable.cs - Generic hash table class.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
[...1199 lines suppressed...]
                                        {
                                                if(table.generation != 
generation)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_CollectionModified"));
                                                }
                                                if(posn < 0 || posn >= 
table.capacity)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadEnumeratorPosition"));
                                                }
                                                return table.table[posn].value;
                                        }
                                }

        }; // HashtableEnum<KeyT, ValueT>

}; // class Hashtable<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * ICollection.cs - Generic collections.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface ICollection<T> : IEnumerable<T>
{

        void CopyTo(T[] array, int index);
        int Count { get; }
        bool IsSynchronized { get; }
        Object SyncRoot { get; }

}; // interface ICollection<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IComparable.cs - Generic comparable interface.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IComparable<T>
{

        int CompareTo(T obj);

}; // interface ICompaable<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IComparer.cs - Generic comparison interface.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IComparer<T>
{

        int Compare(T x, T y);

}; // interface IComparer<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IDictionary.cs - Generic dictionaries.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IDictionary<KeyT, ValueT>
        : IEnumerable<ValueT>, ICollection<ValueT>
{

        void Add(KeyT key, ValueT value);
        void Clear();
        bool Contains(KeyT key);
        new IDictionaryEnumerator<KeyT, ValueT> GetEnumerator();
        void Remove(KeyT key);
        bool IsFixedSize { get; }
        bool IsReadOnly { get; }
        ValueT this[KeyT key] { get; set; }
        ICollection<KeyT> Keys { get; }
        ICollection<ValueT> Values { get; }

}; // interface IDictionary<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * IDictionaryEnumerator.cs - Generic dictionary enumerators.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IDictionaryEnumerator<KeyT, ValueT> : IEnumerator<ValueT>
{

        DictionaryEntry<KeyT, ValueT> Entry { get; }
        KeyT Key { get; }
        ValueT Value { get; }

}; // interface IDictionaryEnumerator<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * IEnumerable.cs - Generic enumerable collections.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IEnumerable<T>
{

        IEnumerator<T> GetEnumerator();

}; // interface IEnumerable<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IEnumerator.cs - Generic collection enumerators.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IEnumerator<T>
{

        bool MoveNext();
        void Reset();
        T Current { get; }

}; // interface IEnumerator<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IHashCodeProvider.cs - Generic hash code providers.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IHashCodeProvider<T>
{

        int GetHashCode(T obj);

}; // interface IHashCodeProvider<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IIterable.cs - Generic iterable collections.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IIterable<T>
{

        IIterator<T> GetIterator();

}; // interface IIterable<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IIterator.cs - Generic collection iterators.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

// Iterators are similar to enumerators, except that they are writable,
// and it is possible to move both forwards and backwards.

public interface IIterator<T> : IEnumerator<T>
{

        bool MovePrev();
        new T Current { get; set; }

}; // interface IIterator<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * IList.cs - Generic lists.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public interface IList<T> : ICollection<T>, IEnumerable<T>, IIterable<T>
{

        int  Add(T value);
        void Clear();
        bool Contains(T value);
        int  IndexOf(T value);
        void Insert(int index, T value);
        void Remove(T value);
        void RemoveAt(int index);
        bool IsFixedSize { get; }
        bool IsReadOnly { get; }
        T this[int index] { get; set; }

}; // interface IList<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * List.cs - Generic doubly-linked list class.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public class List<T>
        : ICollection<T>, IList<T>, IEnumerable<T>, IIterable<T>, ICloneable
{
        // Structure of a list node.
        private class Node<T>
        {
                public T       data;
                public Node<T> next;
                public Node<T> prev;

                public Node(T data)
                                {
                                        this.data = data;
                                        this.next = null;
                                        this.prev = null;
                                }

        }; // class Node

        // Internal state.
        private Node<T> first;
        private Node<T> last;
        private int     count;

        // Constructor.
        public List()
                        {
                                first = null;
                                last = null;
                                count = 0;
                        }

        // Get a particular node in the list by index.
        private Node<T> Get(int index)
                        {
                                Node<T> current;
                                if(index < 0 || index >= count)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("index", 
S._("ArgRange_Array"));
                                }
                                if(index <= (count / 2))
                                {
                                        // Search forwards from the start of 
the list.
                                        current = first;
                                        while(index > 0)
                                        {
                                                current = current.next;
                                                --index;
                                        }
                                        return current;
                                }
                                else
                                {
                                        // Search backwards from the end of the 
list.
                                        current = last;
                                        ++index;
                                        while(index < count)
                                        {
                                                current = current.prev;
                                                ++index;
                                        }
                                        return current;
                                }
                        }

        // Implement the ICollection<T> interface.
        public virtual void CopyTo(T[] array, int index)
                        {
                                IEnumerator<T> e = GetEnumerator();
                                while(e.MoveNext())
                                {
                                        array[index++] = e.Current;
                                }
                        }
        public virtual int Count
                        {
                                get
                                {
                                        return count;
                                }
                        }
        public virtual bool IsSynchronized
                        {
                                get
                                {
                                        return false;
                                }
                        }
        public virtual Object SyncRoot
                        {
                                get
                                {
                                        return this;
                                }
                        }

        // Implement the IList<T> interface.
        public virtual int Add(T value)
                        {
                                int index = count;
                                AddLast(value);
                                return index;
                        }
        public virtual void Clear()
                        {
                                first = null;
                                last = null;
                                count = 0;
                        }
        public virtual bool Contains(T value)
                        {
                                Node<T> current = first;
                                if(typeof(T).IsValueType)
                                {
                                        while(current != null)
                                        {
                                                if(value.Equals(current.data))
                                                {
                                                        return true;
                                                }
                                        }
                                        return false;
                                }
                                else
                                {
                                        if(((Object)value) != null)
                                        {
                                                while(current != null)
                                                {
                                                        
if(value.Equals(current.data))
                                                        {
                                                                return true;
                                                        }
                                                }
                                                return false;
                                        }
                                        else
                                        {
                                                while(current != null)
                                                {
                                                        
if(((Object)(current.data)) == null)
                                                        {
                                                                return true;
                                                        }
                                                }
                                                return false;
                                        }
                                }
                        }
        public virtual int IndexOf(T value)
                        {
                                int index = 0;
                                Node<T> current = first;
                                if(typeof(T).IsValueType)
                                {
                                        while(current != null)
                                        {
                                                if(value.Equals(current.data))
                                                {
                                                        return index;
                                                }
                                                ++index;
                                        }
                                        return -1;
                                }
                                else
                                {
                                        if(((Object)value) != null)
                                        {
                                                while(current != null)
                                                {
                                                        
if(value.Equals(current.data))
                                                        {
                                                                return index;
                                                        }
                                                        ++index;
                                                }
                                                return -1;
                                        }
                                        else
                                        {
                                                while(current != null)
                                                {
                                                        
if(((Object)(current.data)) == null)
                                                        {
                                                                return index;
                                                        }
                                                        ++index;
                                                }
                                                return -1;
                                        }
                                }
                        }
        public virtual void Insert(int index, T value)
                        {
                                if(index == count)
                                {
                                        AddList(value);
                                }
                                else
                                {
                                        Node<T> current = Get(index);
                                        InsertBefore(current, value);
                                }
                        }
        public virtual void Remove(T value)
                        {
                                Node<T> current = first;
                                if(typeof(T).IsValueType)
                                {
                                        while(current != null)
                                        {
                                                if(value.Equals(current.data))
                                                {
                                                        Remove(current);
                                                        return;
                                                }
                                        }
                                }
                                else
                                {
                                        if(((Object)value) != null)
                                        {
                                                while(current != null)
                                                {
                                                        
if(value.Equals(current.data))
                                                        {
                                                                Remove(current);
                                                                return;
                                                        }
                                                }
                                        }
                                        else
                                        {
                                                while(current != null)
                                                {
                                                        
if(((Object)(current.data)) == null)
                                                        {
                                                                Remove(current);
                                                                return;
                                                        }
                                                }
                                        }
                                }
                        }
        public virtual void RemoveAt(int index)
                        {
                                Remove(Get(index));
                        }
        public virtual bool IsFixedSize
                        {
                                get
                                {
                                        return false;
                                }
                        }
        public virtual bool IsReadOnly
                        {
                                get
                                {
                                        return false;
                                }
                        }
        public virtual T this[int index]
                        {
                                get
                                {
                                        return Get(index).data;
                                }
                                set
                                {
                                        Get(index).data = value;
                                }
                        }

        // Implement the IEnumerable<T> interface.
        public virtual IEnumerator<T> GetEnumerator()
                        {
                                return new ListEnumerator<T>(this);
                        }

        // Implement the IIterable<T> interface.
        public virtual IIterator<T> GetIterator()
                        {
                                return new ListEnumerator<T>(this);
                        }

        // Implement the ICloneable interface.
        public virtual Object Clone()
                        {
                                List<T> clone = new List<T>();
                                IEnumerator<T> e = GetEnumerator();
                                while(e.MoveNext())
                                {
                                        clone.AddLast(e.Current);
                                }
                                return clone;
                        }

        // Add a data item to the end of this list.
        public virtual void AddLast(T data)
                        {
                                Node<T> node = new Node<T>(item);
                                node.prev = last;
                                if(last != null)
                                {
                                        last.next = node;
                                }
                                else
                                {
                                        first = node;
                                }
                                last = node;
                                ++count;
                        }

        // Add a data item to the front of this list.
        public virtual void AddFirst(T data)
                        {
                                Node<T> node = new Node<T>(item);
                                node.next = first;
                                if(first != null)
                                {
                                        first.prev = node;
                                }
                                else
                                {
                                        last = node;
                                }
                                first = node;
                                ++count;
                        }

        // Remove the last data item in the list.
        public virtual T RemoveLast()
                        {
                                if(last != null)
                                {
                                        Node<T> node = last;
                                        if(node.prev != null)
                                        {
                                                node.prev.next = null;
                                        }
                                        else
                                        {
                                                first = null;
                                        }
                                        last = node.prev;
                                        --count;
                                        return node.data;
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyList"));
                                }
                        }

        // Remove the first data item in the list.
        public virtual T RemoveFirst()
                        {
                                if(first != null)
                                {
                                        Node<T> node = first;
                                        if(node.next != null)
                                        {
                                                node.next.prev = null;
                                        }
                                        else
                                        {
                                                last = null;
                                        }
                                        first = node.next;
                                        --count;
                                        return node.data;
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyList"));
                                }
                        }

        // Remove a data item from the list (from the front).
        public T Remove()
                        {
                                return RemoveFirst();
                        }

        // Insert a data item just before the current position
        // that is expressed by an enumerator.  If the enumerator
        // position is invalid, then this will insert at the
        // front of the list.
        public virtual void InsertBefore(IEnumerator<T> e, T data)
                        {
                                // TODO
                        }

        // Insert a data item just after the current position
        // that is expressed by an enumerator.  If the enumerator
        // position is invalid, then this will insert at the
        // end of the list.
        public virtual void InsertAfter(IEnumerator<T> e, T data)
                        {
                                // TODO
                        }

        // Remove the item at the current position that is expressed
        // by an enumerator.  The enumerator's position will be updated
        // to point at the next item in the list.  Returns false if
        // there is no next item.
        public virtual bool Remove(IEnumerator<T> e)
                        {
                                // TODO
                        }

        // Remove the item at the current position and move the
        // enumerator to the previous item instead of the next.
        // Returns false if there is no previous item.
        public virtual bool RemoveAndMoveToPrev(IEnumerator<T> e)
                        {
                                // TODO
                        }

        // Wrap a list to make it synchronized.
        public static List<T> Synchronized<T>(List<T> list)
                        {
                                if(list == null)
                                {
                                        throw new ArgumentNullException("list");
                                }
                                return new SynchronizedList<T>(list);
                        }

        // Wrap a list to make it read-only.
        public static List<T> ReadOnly<T>(List<T> list)
                        {
                                if(list == null)
                                {
                                        throw new ArgumentNullException("list");
                                }
                                return new ReadOnlyList<T>(list);
                        }

        // Enumerator and iterator class for lists.
        private class ListEnumerator<T> : IEnumerator<T>, IIterator<T>
        {
                // Internal state, accessible to "List<T>".
                public List<T> list;
                public Node<T> posn;
                public bool    reset;

                // Constructor.
                public ListEnumerator(List<T> list)
                                {
                                        this.list = list;
                                        this.posn = null;
                                        this.reset = true;
                                }

                // Implement the IEnumerator<T> interface.
                public bool MoveNext()
                                {
                                        if(reset)
                                        {
                                                posn = list.first;
                                                reset = false;
                                        }
                                        else if(posn != null)
                                        {
                                                posn = posn.next;
                                        }
                                        return (posn != null);
                                }
                public void Reset()
                                {
                                        posn = null;
                                        reset = true;
                                }
                T IEnumerator<T>.Current
                                {
                                        get
                                        {
                                                if(posn == null)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadEnumeratorPosition"));
                                                }
                                                return posn.data;
                                        }
                                }

                // Implement the IIterator<T> interface.
                public bool MovePrev()
                                {
                                        if(reset)
                                        {
                                                posn = list.last;
                                                reset = false;
                                        }
                                        else if(posn != null)
                                        {
                                                posn = posn.prev;
                                        }
                                        return (posn != null);
                                }
                public T Current
                                {
                                        get
                                        {
                                                if(posn == null)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadIteratorPosition"));
                                                }
                                                return posn.data;
                                        }
                                        set
                                        {
                                                if(posn == null)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadIteratorPosition"));
                                                }
                                                posn.data = value;
                                        }
                                }

        }; // class ListEnumerator<T>

        // TODO: synchonized and read-only wrappers

}; // class List<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ListAdapter.cs - Adapt a generic list into a non-generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ListAdapter<T>
        : System.Collections.IList, System.Collections.ICollection,
          System.Collections.IEnumerable
{

        // Internal state.
        private IList<T> list;

        // Constructor.
        public ListAdapter(IList<T> list)
                        {
                                if(list == null)
                                {
                                        throw new ArgumentNullException("list");
                                }
                                this.list = list;
                        }

        // Determine if a value is type-compatible with the generic list.
        private bool CheckType(Object value)
                        {
                                if(typeof(T).IsValueType)
                                {
                                        if(value == null || !(value is T))
                                        {
                                                return false;
                                        }
                                }
                                else
                                {
                                        if(value != null && !(value is T))
                                        {
                                                return false;
                                        }
                                }
                                return true;
                        }

        // Check type compatibility and throw an exception if invalid.
        private void CheckTypeAndThrow(Object value)
                        {
                                if(!CheckType(value))
                                {
                                        // The value is not type-compatible 
with the list.
                                        throw new InvalidOperationException
                                                (S._("Invalid_ValueType"));
                                }
                        }

        // Implement the non-generic IList interface.
        public int Add(Object value)
                        {
                                CheckTypeAndThrow(value);
                                return list.Add((T)value);
                        }
        public void Clear()
                        {
                                list.Clear();
                        }
        public bool Contains(Object value)
                        {
                                if(CheckType(value))
                                {
                                        return list.Contains((T)value);
                                }
                                else
                                {
                                        return false;
                                }
                        }
        public int IndexOf(Object value)
                        {
                                if(CheckType(value))
                                {
                                        return list.IndexOf((T)value);
                                }
                                else
                                {
                                        return -1;
                                }
                        }
        public void Insert(int index, Object value)
                        {
                                CheckTypeAndThrow(value);
                                list.Insert(index, (T)value);
                        }
        public void Remove(Object value)
                        {
                                if(CheckType(value))
                                {
                                        list.Remove((T)value);
                                }
                        }
        public void RemoveAt(int index)
                        {
                                list.RemoveAt(index);
                        }
        public bool IsFixedSize
                        {
                                get
                                {
                                        return list.IsFixedSize;
                                }
                        }
        public bool IsReadOnly
                        {
                                get
                                {
                                        return list.IsReadOnly;
                                }
                        }
        public Object this[int index]
                        {
                                get
                                {
                                        return list[index];
                                }
                                set
                                {
                                        CheckTypeAndThrow(value);
                                        list[index] = (T)value;
                                }
                        }

        // Implement the non-generic ICollection interface.
        public void CopyTo(Array array, int index)
                        {
                                IEnumerator<T> e = list.GetEnumerator();
                                while(e.MoveNext())
                                {
                                        array.SetValue(e.Current, index++);
                                }
                        }
        public int Count
                        {
                                get
                                {
                                        return list.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return list.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return list.SyncRoot;
                                }
                        }

        // Implement the non-generic IEnumerable interface.
        public System.Collections.IEnumerator GetEnumerator()
                        {
                                return new 
EnumeratorAdapter<T>(list.GetEnumerator());
                        }

}; // class ListAdapter<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * ListWrapper.cs - Wrap a non-generic list to turn it into a generic one.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public sealed class ListWrapper<T>
        : IList<T>, ICollection<T>, IEnumerable<T>, IIterable<T>
{

        // Internal state.
        private System.Collections.IList list;

        // Constructor.
        public ListWrapper(System.Collections.IList list)
                        {
                                if(list == null)
                                {
                                        throw new ArgumentNullException("list");
                                }
                                this.list = list;
                        }

        // Implement the IList<T> interface.
        public int Add(T value)
                        {
                                return list.Add(value);
                        }
        public void Clear()
                        {
                                list.Clear();
                        }
        public bool Contains(T value)
                        {
                                return list.Contains(value);
                        }
        public int IndexOf(T value)
                        {
                                return list.IndexOf(value);
                        }
        public void Insert(int index, T value)
                        {
                                list.Insert(index, value);
                        }
        public void Remove(T value)
                        {
                                list.Remove(value);
                        }
        public void RemoveAt(int index)
                        {
                                list.RemoveAt(index);
                        }
        public bool IsFixedSize
                        {
                                get
                                {
                                        return list.IsFixedSize;
                                }
                        }
        public bool IsReadOnly
                        {
                                get
                                {
                                        return list.IsReadOnly;
                                }
                        }
        public T this[int index]
                        {
                                get
                                {
                                        return (T)(list[index]);
                                }
                                set
                                {
                                        list[index] = value;
                                }
                        }

        // Implement the ICollection<T> interface.
        public void CopyTo(T[] array, int index)
                        {
                                list.CopyTo(array, index);
                        }
        public int Count
                        {
                                get
                                {
                                        return list.Count;
                                }
                        }
        public bool IsSynchronized
                        {
                                get
                                {
                                        return list.IsSynchronized;
                                }
                        }
        public Object SyncRoot
                        {
                                get
                                {
                                        return list.SyncRoot;
                                }
                        }

        // Implement the IEnumerable<T> interface.
        public IEnumerator<T> GetEnumerator()
                        {
                                return new 
EnumeratorWrapper<T>(list.GetEnumerator());
                        }

        // Implement the IIterable<T> interface.
        public IIterator<T> GetIterator()
                        {
                                return new ListIterator<T>(list);
                        }

        // Private list iterator implementation.
        private sealed class ListIterator<T> : IEnumerator<T>, IIterator<T>
        {
                // Internal state.
                private IList list;
                private int posn;
                private bool reset;

                // Constructor.
                public ListIterator(IList list)
                                {
                                        this.list = list;
                                        posn = -1;
                                        reset = true;
                                }

                // Implement the IEnumerator<T> interface.
                public bool MoveNext()
                                {
                                        if(reset)
                                        {
                                                // Start at the beginning of 
the list.
                                                posn = -1;
                                                reset = false;
                                        }
                                        ++posn;
                                        return (posn < list.Count);
                                }
                public void Reset()
                                {
                                        posn = -1;
                                        reset = true;
                                }
                T IEnumertor<T>.Current
                                {
                                        get
                                        {
                                                if(posn >= 0 && posn < 
list.Count)
                                                {
                                                        return (T)(list[posn]);
                                                }
                                                else
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadIteratorPosition"));
                                                }
                                        }
                                }

                // Implement the IIterator<T> interface.
                public bool MovePrev()
                                {
                                        if(reset)
                                        {
                                                // Start at the end of the list.
                                                posn = list.Count;
                                                reset = false;
                                        }
                                        --posn;
                                        return (posn >= 0);
                                }
                public T Current
                                {
                                        get
                                        {
                                                if(posn >= 0 && posn < 
list.Count)
                                                {
                                                        return (T)(list[posn]);
                                                }
                                                else
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadIteratorPosition"));
                                                }
                                        }
                                        set
                                        {
                                                if(posn >= 0 && posn < 
list.Count)
                                                {
                                                        list[posn] = value;
                                                }
                                                else
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadIteratorPosition"));
                                                }
                                        }
                                }

        }; // class ListIterator<T>

}; // class ListWrapper<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * Predicate.cs - Generic predicate delegate.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

// Predicates return true if their argument satisfies the predicate condition.
public delegate bool Predicate<T>(T x);

}; // namespace Generics

--- NEW FILE ---
/*
 * Queue.cs - Generic queue class.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public class Queue<T> : ICollection<T>, IEnumerable<T>, ICloneable
{
        // Internal state.
        private T[]   items;
        private int   add, remove, size;
        private float growFactor;
        private int   generation;

        // The default capacity for queues.
        private const int DefaultCapacity = 32;

        // Constructors.
        public Queue()
                        {
                                items = new Object [DefaultCapacity];
                                add = 0;
                                remove = 0;
                                size = 0;
                                growFactor = 2.0f;
                                generation = 0;
                        }
        public Queue(int capacity)
                        {
                                if(capacity < 0)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("capacity", 
S._("ArgRange_NonNegative"));
                                }
                                items = new T [capacity];
                                add = 0;
                                remove = 0;
                                size = 0;
                                growFactor = 2.0f;
                                generation = 0;
                        }
        public Queue(int capacity, float growFactor)
                        {
                                if(capacity < 0)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("capacity", 
S._("ArgRange_NonNegative"));
                                }
                                if(growFactor < 1.0f || growFactor > 10.0f)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("growFactor", 
S._("ArgRange_QueueGrowFactor"));
                                }
                                items = new T [capacity];
                                add = 0;
                                remove = 0;
                                size = 0;
                                this.growFactor = growFactor;
                                generation = 0;
                        }
        public Queue(ICollection<T> col)
                        {
                                if(col == null)
                                {
                                        throw new ArgumentNullException("col");
                                }
                                items = new T [col.Count];
                                col.CopyTo(items, 0);
                                add = 0;
                                remove = 0;
                                size = items.Length;
                                growFactor = 2.0f;
                                generation = 0;
                        }

        // Implement the ICollection<T> interface.
        public virtual void CopyTo(T[] array, int index)
                        {
                                if(array == null)
                                {
                                        throw new 
ArgumentNullException("array");
                                }
                                else if(index < 0)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("index", 
S._("ArgRange_Array"));
                                }
                                else if((array.Length - index) < size)
                                {
                                        throw new 
ArgumentException(S._("Arg_InvalidArrayRange"));
                                }
                                else if(size > 0)
                                {
                                        if((remove + size) <= items.Length)
                                        {
                                                Array.Copy(items, remove, 
array, index, size);
                                        }
                                        else
                                        {
                                                Array.Copy(items, remove, 
array, index,
                                                                   items.Length 
- remove);
                                                Array.Copy(items, 0, array,
                                                                   index + 
items.Length - remove, add);
                                        }
                                }
                        }
        public virtual int Count
                        {
                                get
                                {
                                        return size;
                                }
                        }
        public virtual bool IsSynchronized
                        {
                                get
                                {
                                        return false;
                                }
                        }
        public virtual Object SyncRoot
                        {
                                get
                                {
                                        return this;
                                }
                        }

        // Implement the ICloneable<T> interface.
        public virtual Object Clone()
                        {
                                Queue<T> queue = (Queue<T>)MemberwiseClone();
                                queue.items = (T[])items.Clone();
                                return queue;
                        }

        // Implement the IEnumerable<T> interface.
        public virtual IEnumerator<T> GetEnumerator()
                        {
                                return new QueueEnumerator<T>(this);
                        }

        // Determine if this queue is read-only.
        public virtual bool IsReadOnly
                        {
                                get
                                {
                                        return false;
                                }
                        }

        // Clear the contents of this queue.
        public virtual void Clear()
                        {
                                add = 0;
                                remove = 0;
                                size = 0;
                                ++generation;
                        }

        // Determine if this queue contains a specific object.
        public virtual bool Contains(T obj)
                        {
                                int index = remove;
                                int capacity = items.Length;
                                int count = size;
                                if(typeof(T).IsValueType)
                                {
                                        while(count > 0)
                                        {
                                                if(obj.Equals(items[index]))
                                                {
                                                        return true;
                                                }
                                                index = (index + 1) % capacity;
                                                --count;
                                        }
                                }
                                else
                                {
                                        while(count > 0)
                                        {
                                                if(items[index] != null && obj 
!= null)
                                                {
                                                        
if(obj.Equals(items[index]))
                                                        {
                                                                return true;
                                                        }
                                                }
                                                else if(items[index] == null && 
obj == null)
                                                {
                                                        return true;
                                                }
                                                index = (index + 1) % capacity;
                                                --count;
                                        }
                                }
                                return false;
                        }

        // Dequeue an item.
        public virtual T Dequeue()
                        {
                                if(size > 0)
                                {
                                        T value = items[remove];
                                        remove = (remove + 1) % items.Length;
                                        --size;
                                        ++generation;
                                        return value;
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyQueue"));
                                }
                        }

        // Enqueue an item.
        public virtual void Enqueue(T obj)
                        {
                                if(size < items.Length)
                                {
                                        // The queue is big enough to hold the 
new item.
                                        items[add] = obj;
                                        add = (add + 1) % items.Length;
                                        ++size;
                                }
                                else
                                {
                                        // We need to increase the size of the 
queue.
                                        int newCapacity = (int)(items.Length * 
growFactor);
                                        if(newCapacity <= items.Length)
                                        {
                                                newCapacity = items.Length + 1;
                                        }
                                        T[] newItems = new T [newCapacity];
                                        if(remove < size)
                                        {
                                                Array.Copy(items, remove, 
newItems, 0, size - remove);
                                        }
                                        if(remove > 0)
                                        {
                                                Array.Copy(items, 0, newItems, 
size - remove, remove);
                                        }
                                        items = newItems;
                                        add = size;
                                        remove = 0;
                                }
                                ++generation;
                        }

        // Peek at the first item without dequeuing it.
        public virtual T Peek()
                        {
                                if(size > 0)
                                {
                                        return items[remove];
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyQueue"));
                                }
                        }

        // Convert the contents of this queue into an array.
        public virtual T[] ToArray()
                        {
                                T[] array = new T [size];
                                if(size > 0)
                                {
                                        if((remove + size) <= items.Length)
                                        {
                                                Array.Copy(items, remove, 
array, 0, size);
                                        }
                                        else
                                        {
                                                Array.Copy(items, remove, 
array, 0,
                                                                   items.Length 
- remove);
                                                Array.Copy(items, 0, array,
                                                                   items.Length 
- remove, add);
                                        }
                                }
                                return array;
                        }

        // Convert this queue into a synchronized queue.
        public static Queue<T> Synchronized(Queue<T> queue)
                        {
                                if(queue == null)
                                {
                                        throw new 
ArgumentNullException("queue");
                                }
                                else if(queue.IsSynchronized)
                                {
                                        return queue;
                                }
                                else
                                {
                                        return new SynchronizedQueue<T>(queue);
                                }
                        }

        // Private class that implements synchronized queues.
        private class SynchronizedQueue : Queue
        {
                // Internal state.
                private Queue<T> queue;

                // Constructor.
                public SynchronizedQueue(Queue<T> queue)
                                {
                                        this.queue = queue;
                                }

                // Implement the ICollection<T> interface.
                public override void CopyTo(T[] array, int index)
                                {
                                        lock(SyncRoot)
                                        {
                                                queue.CopyTo(array, index);
                                        }
                                }
                public override int Count
                                {
                                        get
                                        {
                                                lock(SyncRoot)
                                                {
                                                        return queue.Count;
                                                }
                                        }
                                }
                public override bool IsSynchronized
                                {
                                        get
                                        {
                                                return true;
                                        }
                                }
                public override Object SyncRoot
                                {
                                        get
                                        {
                                                return queue.SyncRoot;
                                        }
                                }

                // Implement the ICloneable interface.
                public override Object Clone()
                                {
                                        return new 
SynchronizedQueue<T>((Queue<T>)(queue.Clone()));
                                }

                // Implement the IEnumerable<T> interface.
                public override IEnumerator<T> GetEnumerator()
                                {
                                        lock(SyncRoot)
                                        {
                                                return new 
SynchronizedEnumerator<T>
                                                        (SyncRoot, 
queue.GetEnumerator());
                                        }
                                }

                // Clear the contents of this queue.
                public override void Clear()
                                {
                                        lock(SyncRoot)
                                        {
                                                queue.Clear();
                                        }
                                }

                // Determine if this queue contains a specific object.
                public override bool Contains(T obj)
                                {
                                        lock(SyncRoot)
                                        {
                                                return queue.Contains(obj);
                                        }
                                }

                // Dequeue an item.
                public override T Dequeue()
                                {
                                        lock(SyncRoot)
                                        {
                                                return queue.Dequeue();
                                        }
                                }

                // Enqueue an item.
                public override void Enqueue(T obj)
                                {
                                        lock(SyncRoot)
                                        {
                                                queue.Enqueue(obj);
                                        }
                                }

                // Peek at the first item without dequeuing it.
                public override T Peek()
                                {
                                        lock(SyncRoot)
                                        {
                                                return queue.Peek();
                                        }
                                }

                // Convert the contents of this queue into an array.
                public override T[] ToArray()
                                {
                                        lock(SyncRoot)
                                        {
                                                return queue.ToArray();
                                        }
                                }

        }; // class SynchronizedQueue

        // Private class for implementing queue enumeration.
        private class QueueEnumerator<T> : IEnumerator
        {
                // Internal state.
                private Queue<T> queue;
                private int      generation;
                private int      position;

                // Constructor.
                public QueueEnumerator(Queue<T> queue)
                                {
                                        this.queue = queue;
                                        generation = queue.generation;
                                        position   = -1;
                                }

                // Implement the IEnumerator interface.
                public bool MoveNext()
                                {
                                        if(generation != queue.generation)
                                        {
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_CollectionModified"));
                                        }
                                        ++position;
                                        if(position < queue.size)
                                        {
                                                return true;
                                        }
                                        position = queue.size;
                                        return false;
                                }
                public void Reset()
                                {
                                        if(generation != queue.generation)
                                        {
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_CollectionModified"));
                                        }
                                        position = -1;
                                }
                public T Current
                                {
                                        get
                                        {
                                                if(generation != 
queue.generation)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_CollectionModified"));
                                                }
                                                if(position < 0 || position >= 
queue.size)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadEnumeratorPosition"));
                                                }
                                                return queue.items
                                                        [(queue.remove + 
position) % queue.size];
                                        }
                                }

        }; // class QueueEnumerator<T>

}; // class Queue<T>

}; // namespace Generics

--- NEW FILE ---

The classes in this directory implement generic counterparts to the
non-generic classes in the "System.Collections" namespace, plus some
extras that are modelled on the C++ Standard Template Library.

Also included are a number of "Adapter" classes, that can be used to
convert a generic collection into a non-generic collection.  This is
useful when trying to use generic collections with existing API's
that expect a non-generic collection.

Finally, there are a number of "Wrapper" classes that can be used to
convert a non-generic collection into a generic collection.  This is
useful to get a type-safe interface to an existing non-generic
collection class.

The license on these classes is the MIT X11 license.  This license
was chosen to maximize the number of people who can use the generic
class library.  We only ask that if you fix bugs or add new functionality
that you consider contributing the changes back to the Portable.NET
development team, but this isn't mandatory.

--- NEW FILE ---
/*
 * ReverseIterator.cs - Wrap an iterator to reverse its traversal direction.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace Generics
{

using System;

public sealed class ReverseIterator<T> : IEnumerator<T>, IIterator<T>
{
        // Internal state.
        protected IIterator<T> iterator;

        // Constructor.
        public ReverseIterator(IIterator<T> iterator)
                        {
                                this.iterator = iterator;
                        }

        // Implement the IEnumerator<T> interface.
        public bool MoveNext()
                        {
                                lock(syncRoot)
                                {
                                        return iterator.MovePrev();
                                }
                        }
        public void Reset()
                        {
                                lock(syncRoot)
                                {
                                        iterator.Reset();
                                }
                        }
        T IEnumerator<T>.Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return 
((IEnumerator<T>)iterator).Current;
                                        }
                                }
                        }

        // Implement the IIterator<T> interface.
        public bool MovePrev()
                        {
                                lock(syncRoot)
                                {
                                        return iterator.MoveNext();
                                }
                        }
        public T Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return iterator.Current;
                                        }
                                }
                                set
                                {
                                        lock(syncRoot)
                                        {
                                                iterator.Current = value;
                                        }
                                }
                        }

}; // class ReverseIterator<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * S.cs - String resources.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System.Reflection;
using System.Resources;

// This class provides string resource support to the rest
// of the "Generics" library assembly.  It is accessed using
// the "S._(tag)" convention.

internal sealed class S
{
        // Cached copy of the resources for this assembly.
        private static ResourceManager genericsResources = null;

        // Helper for obtaining string resources for this assembly.
        public static String _(String tag)
                        {
                                lock(typeof(S))
                                {
                                        String value;
                                        if(genericsResources == null)
                                        {
                                                genericsResources = new 
ResourceManager
                                                        ("Generics", 
(typeof(S)).Assembly);
                                        }
                                        return genericsResources.GetString(tag, 
null);
                                }
                        }

}; // class S

}; // namespace Generics

--- NEW FILE ---
/*
 * Stack.cs - Generic stack class.
 *
 * Copyright (c) 2003  Southern Storm Software, Pty Ltd
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

namespace Generics
{

using System;

public class Stack<T> : ICollection<T>, IEnumerable<T>, ICloneable
{
        // Internal state.
        private T[] items;
        private int size;
        private int generation;

        // The default capacity for stacks.
        private const int DefaultCapacity = 10;

        // The amount to grow the stack by each time.
        private const int GrowSize = 10;

        // Constructors.
        public Stack()
                        {
                                items = new T [DefaultCapacity];
                                size = 0;
                                generation = 0;
                        }
        public Stack(int initialCapacity)
                        {
                                if(initialCapacity < 0)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("initialCapacity", 
S._("ArgRange_NonNegative"));
                                }
                                items = new T [initialCapacity];
                                size = 0;
                                generation = 0;
                        }
        public Stack(ICollection<T> col)
                        {
                                if(col == null)
                                {
                                        throw new ArgumentNullException("col");
                                }
                                items = new T [col.Count];
                                col.CopyTo(items, 0);
                                size = items.Length;
                                generation = 0;
                        }

        // Implement the ICollection<T> interface.
        public virtual void CopyTo(T[] array, int index)
                        {
                                if(array == null)
                                {
                                        throw new 
ArgumentNullException("array");
                                }
                                else if(index < 0)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("index", 
S._("ArgRange_Array"));
                                }
                                else if((array.Length - index) < size)
                                {
                                        throw new 
ArgumentException(S._("Arg_InvalidArrayRange"));
                                }
                                else if(size > 0)
                                {
                                        Array.Copy(items, 0, array, index, 
size);
                                }
                        }
        public virtual int Count
                        {
                                get
                                {
                                        return size;
                                }
                        }
        public virtual bool IsSynchronized
                        {
                                get
                                {
                                        return false;
                                }
                        }
        public virtual Object SyncRoot
                        {
                                get
                                {
                                        return this;
                                }
                        }

        // Implement the ICloneable interface.
        public virtual Object Clone()
                        {
                                Stack<T> stack = (Stack<T>)MemberwiseClone();
                                stack.items = (T[])items.Clone();
                                return stack;
                        }

        // Implement the IEnumerable<T> interface.
        public virtual IEnumerator<T> GetEnumerator()
                        {
                                return new StackEnumerator<T>(this);
                        }

        // Determine if this stack is read-only.
        public virtual bool IsReadOnly
                        {
                                get
                                {
                                        return false;
                                }
                        }

        // Clear the contents of this stack.
        public virtual void Clear()
                        {
                                size = 0;
                                ++generation;
                        }

        // Determine if this stack contains a specific object.
        public virtual bool Contains(T obj)
                        {
                                int index;
                                if(typeof(T).IsValueType)
                                {
                                        for(index = 0; index < size; ++index)
                                        {
                                                if(obj.Equals(items[index]))
                                                {
                                                        return true;
                                                }
                                        }
                                }
                                else
                                {
                                        for(index = 0; index < size; ++index)
                                        {
                                                if(items[index] != null && obj 
!= null)
                                                {
                                                        
if(obj.Equals(items[index]))
                                                        {
                                                                return true;
                                                        }
                                                }
                                                else if(items[index] == null && 
obj == null)
                                                {
                                                        return true;
                                                }
                                        }
                                }
                                return false;
                        }

        // Pop an item.
        public virtual T Pop()
                        {
                                if(size > 0)
                                {
                                        ++generation;
                                        return items[--size];
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyStack"));
                                }
                        }

        // Push an item.
        public virtual void Push(T obj)
                        {
                                if(size < items.Length)
                                {
                                        // The stack is big enough to hold the 
new item.
                                        items[size++] = obj;
                                }
                                else
                                {
                                        // We need to increase the size of the 
stack.
                                        int newCapacity = items.Length + 
GrowSize;
                                        T[] newItems = new T [newCapacity];
                                        if(size > 0)
                                        {
                                                Array.Copy(items, newItems, 
size);
                                        }
                                        items = newItems;
                                }
                                ++generation;
                        }

        // Peek at the top-most item without popping it.
        public virtual T Peek()
                        {
                                if(size > 0)
                                {
                                        return items[size - 1];
                                }
                                else
                                {
                                        throw new InvalidOperationException
                                                (S._("Invalid_EmptyStack"));
                                }
                        }

        // Convert the contents of this stack into an array.
        public virtual T[] ToArray()
                        {
                                T[] array = new T [size];
                                int index;
                                for(index = 0; index < size; ++index)
                                {
                                        array[index] = items[size - index - 1];
                                }
                                return array;
                        }

        // Convert this stack into a synchronized stack.
        public static Stack<T> Synchronized(Stack<T> stack)
                        {
                                if(stack == null)
                                {
                                        throw new 
ArgumentNullException("stack");
                                }
                                else if(stack.IsSynchronized)
                                {
                                        return stack;
                                }
                                else
                                {
                                        return new SynchronizedStack<T>(stack);
                                }
                        }

        // Private class that implements synchronized stacks.
        private class SynchronizedStack<T> : Stack<T>
        {
                // Internal state.
                private Stack<T> stack;

                // Constructor.
                public SynchronizedStack(Stack<T> stack)
                                {
                                        this.stack = stack;
                                }

                // Implement the ICollection<T> interface.
                public override void CopyTo(T[] array, int index)
                                {
                                        lock(SyncRoot)
                                        {
                                                stack.CopyTo(array, index);
                                        }
                                }
                public override int Count
                                {
                                        get
                                        {
                                                lock(SyncRoot)
                                                {
                                                        return stack.Count;
                                                }
                                        }
                                }
                public override bool IsSynchronized
                                {
                                        get
                                        {
                                                return true;
                                        }
                                }
                public override Object SyncRoot
                                {
                                        get
                                        {
                                                return stack.SyncRoot;
                                        }
                                }

                // Implement the ICloneable interface.
                public override Object Clone()
                                {
                                        return new 
SynchronizedStack<T>((Stack<T>)(stack.Clone()));
                                }

                // Implement the IEnumerable interface.
                public override IEnumerator<T> GetEnumerator()
                                {
                                        lock(SyncRoot)
                                        {
                                                return new 
SynchronizedEnumerator<T>
                                                        (SyncRoot, 
stack.GetEnumerator());
                                        }
                                }

                // Clear the contents of this stack.
                public override void Clear()
                                {
                                        lock(SyncRoot)
                                        {
                                                stack.Clear();
                                        }
                                }

                // Determine if this stack contains a specific object.
                public override bool Contains(T obj)
                                {
                                        lock(SyncRoot)
                                        {
                                                return stack.Contains(obj);
                                        }
                                }

                // Pop an item.
                public override T Pop()
                                {
                                        lock(SyncRoot)
                                        {
                                                return stack.Pop();
                                        }
                                }

                // Push an item.
                public override void Push(T obj)
                                {
                                        lock(SyncRoot)
                                        {
                                                stack.Push(obj);
                                        }
                                }

                // Peek at the top-most item without popping it.
                public override T Peek()
                                {
                                        lock(SyncRoot)
                                        {
                                                return stack.Peek();
                                        }
                                }

                // Convert the contents of this stack into an array.
                public override T[] ToArray()
                                {
                                        lock(SyncRoot)
                                        {
                                                return stack.ToArray();
                                        }
                                }

        }; // class SynchronizedStack<T>

        // Private class for implementing stack enumeration.
        private class StackEnumerator<T> : IEnumerator<T>
        {
                // Internal state.
                private Stack<T> stack;
                private int      generation;
                private int      position;

                // Constructor.
                public StackEnumerator(Stack<T> stack)
                                {
                                        this.stack = stack;
                                        generation = stack.generation;
                                        position   = -1;
                                }

                // Implement the IEnumerator interface.
                public bool MoveNext()
                                {
                                        if(generation != stack.generation)
                                        {
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_CollectionModified"));
                                        }
                                        ++position;
                                        if(position < stack.size)
                                        {
                                                return true;
                                        }
                                        position = stack.size;
                                        return false;
                                }
                public void Reset()
                                {
                                        if(generation != stack.generation)
                                        {
                                                throw new 
InvalidOperationException
                                                        
(S._("Invalid_CollectionModified"));
                                        }
                                        position = -1;
                                }
                public T Current
                                {
                                        get
                                        {
                                                if(generation != 
stack.generation)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_CollectionModified"));
                                                }
                                                if(position < 0 || position >= 
stack.size)
                                                {
                                                        throw new 
InvalidOperationException
                                                                
(S._("Invalid_BadEnumeratorPosition"));
                                                }
                                                return stack.items[stack.size - 
position - 1];
                                        }
                                }

        }; // class StackEnumerator<T>

}; // class Stack<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * SynchronizedDictEnumerator.cs - Wrap an enumerator to synchronize it.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace Generics
{

using System;

internal sealed class SynchronizedDictEnumerator<KeyT, ValueT>
                : IDictionaryEnumerator<KeyT, ValueT>
{
        // Internal state.
        protected Object syncRoot;
        protected IDictionaryEnumerator<KeyT, ValueT> enumerator;

        // Constructor.
        public SynchronizedDictEnumerator
                                (Object syncRoot,
                                 IDictionaryEnumerator<KeyT, ValueT> enumerator)
                        {
                                this.syncRoot = syncRoot;
                                this.enumerator = enumerator;
                        }

        // Implement the IEnumerator<ValueT> interface.
        public bool MoveNext()
                        {
                                lock(syncRoot)
                                {
                                        return enumerator.MoveNext();
                                }
                        }
        public void Reset()
                        {
                                lock(syncRoot)
                                {
                                        enumerator.Reset();
                                }
                        }
        public ValueT Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return enumerator.Value;
                                        }
                                }
                        }

        // Implement the IDictionaryEnumerator<KeyT, ValueT> interface.
        public DictionaryEntry<KeyT, ValueT> Entry
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return enumerator.Entry;
                                        }
                                }
                        }
        public KeyT Key
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return enumerator.Key;
                                        }
                                }
                        }
        public ValueT Value
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return enumerator.Value;
                                        }
                                }
                        }

}; // class SynchronizedDictEnumerator<KeyT, ValueT>

}; // namespace Generics

--- NEW FILE ---
/*
 * SynchronizedEnumerator.cs - Wrap an enumerator to synchronize it.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace Generics
{

using System;

internal sealed class SynchronizedEnumerator<T> : IEnumerator<T>
{
        // Internal state.
        protected Object         syncRoot;
        protected IEnumerator<T> enumerator;

        // Constructor.
        public SynchronizedEnumerator(Object syncRoot, IEnumerator<T> 
enumerator)
                        {
                                this.syncRoot = syncRoot;
                                this.enumerator = enumerator;
                        }

        // Implement the IEnumerator<T> interface.
        public bool MoveNext()
                        {
                                lock(syncRoot)
                                {
                                        return enumerator.MoveNext();
                                }
                        }
        public void Reset()
                        {
                                lock(syncRoot)
                                {
                                        enumerator.Reset();
                                }
                        }
        public T Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return enumerator.Current;
                                        }
                                }
                        }

}; // class SynchronizedEnumerator<T>

}; // namespace Generics

--- NEW FILE ---
/*
 * SynchronizedIterator.cs - Wrap an iterator to synchronize it.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace Generics
{

using System;

internal sealed class SynchronizedIterator<T> : IEnumerator<T>, IIterator<T>
{
        // Internal state.
        protected Object       syncRoot;
        protected IIterator<T> iterator;

        // Constructor.
        public SynchronizedIterator(Object syncRoot, IIterator<T> iterator)
                        {
                                this.syncRoot = syncRoot;
                                this.iterator = iterator;
                        }

        // Implement the IEnumerator<T> interface.
        public bool MoveNext()
                        {
                                lock(syncRoot)
                                {
                                        return iterator.MoveNext();
                                }
                        }
        public void Reset()
                        {
                                lock(syncRoot)
                                {
                                        iterator.Reset();
                                }
                        }
        T IEnumerator<T>.Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return 
((IEnumerator<T>)iterator).Current;
                                        }
                                }
                        }

        // Implement the IIterator<T> interface.
        public bool MovePrev()
                        {
                                lock(syncRoot)
                                {
                                        return iterator.MovePrev();
                                }
                        }
        public T Current
                        {
                                get
                                {
                                        lock(syncRoot)
                                        {
                                                return iterator.Current;
                                        }
                                }
                                set
                                {
                                        lock(syncRoot)
                                        {
                                                iterator.Current = value;
                                        }
                                }
                        }

}; // class SynchronizedIterator<T>

}; // namespace Generics





reply via email to

[Prev in Thread] Current Thread [Next in Thread]