Exemple #1
0
 public void Add(T result)
 {
     if (!_results.Contains(result))
     {
         _results.Add(result);
     }
 }
Exemple #2
0
        private void MaxPriorityQueueConstructor(MaxPriorityQueue <int> pq)
        {
            Assert.True(pq.IsEmpty);
            var rand  = new Random((int)DateTime.Now.Ticks & 0x0000ffff);
            var set   = new TreeSet <int>();
            var count = 0;

            while (count < 10000)
            {
                var next = rand.Next() % 100000;
                if (!set.Contains(next))
                {
                    pq.Push(next);
                    set.Add(next);
                    count++;
                    Assert.Equal(set.Max, pq.Top);
                }
            }
            Assert.False(pq.IsEmpty);
            Assert.Equal(10000, pq.Count);
            for (var i = 0; i < 1000; i++)
            {
                Assert.Equal(set.Max, pq.Top);
                Assert.Equal(set.Max, pq.Pop());
                set.RemoveMax();
            }
            Assert.Equal(9000, pq.Count);

            var newCount = 0;

            while (newCount < 5000)
            {
                var next = rand.Next() % 100000;
                if (!set.Contains(next))
                {
                    pq.Push(next);
                    set.Add(next);
                    newCount++;
                }
            }
            Assert.Equal(14000, pq.Count);
            for (var i = 0; i < 4000; i++)
            {
                Assert.Equal(set.Max, pq.Top);
                Assert.Equal(set.Max, pq.Pop());
                set.RemoveMax();
            }
            Assert.Equal(10000, pq.Count);
        }
Exemple #3
0
        public void StoreTrigger(Trigger trigger, bool replaceExisting)
        {
            TriggerWrapper tw = new TriggerWrapper(trigger);

            lock (_triggerLock)
            {
                if (_triggersDictionary.Contains(tw.Name))
                {
                    if (!replaceExisting)
                    {
                        throw new NotSupportedException("Object already exists " + trigger.Name);
                    }
                    // don't delete orphaned job, this trigger has the job anyways
                    RemoveTrigger(trigger.Name, false);
                }

                if (RetrieveJob(trigger.JobName) == null)
                {
                    throw new ApplicationException("The job (" + trigger.JobName + ") referenced by the trigger does not exist.");
                }

                // add to triggers array
                _triggers.Add(tw);

                _triggersDictionary[tw.Name] = tw;

                lock (_pausedTriggers)
                {
                    if (_pausedTriggers.Contains(trigger.Name) || _pausedJobs.Contains(trigger.JobName))
                    {
                        tw.State = InternalTriggerState.Paused;
                        if (_blockedJobs.Contains(trigger.JobName))
                        {
                            tw.State = InternalTriggerState.PausedAndBlocked;
                        }
                    }
                    else if (_blockedJobs.Contains(trigger.JobName))
                    {
                        tw.State = InternalTriggerState.Blocked;
                    }
                    else
                    {
                        _timeTriggers.Add(tw);
                    }
                }
            }
        }
Exemple #4
0
        public void TestICollectionTInterface()
        {
            ICollection <int> set = new TreeSet <int>(Enumerable.Range(0, 10));

            Assert.False(set.IsReadOnly);

            Assert.Equal(10, set.Count);
            Assert.True(set.Contains(3));
            set.Add(3);
            Assert.True(set.Contains(3));
            Assert.Equal(10, set.Count);

            Assert.False(set.Contains(12));
            set.Add(12);
            Assert.True(set.Contains(12));
            Assert.Equal(11, set.Count);
        }
Exemple #5
0
 private static void TestBinaryTree()
 {
     structures.common.ISet <int> tree = new TreeSet <int>();
     tree.Add(5);
     tree.Add(6);
     tree.Add(9);
     tree.Add(1);
     tree.Add(4);
     tree.Add(8);
     tree.Add(-15);
     tree.Remove(1);
     Console.Out.WriteLine(tree.Contains(1));
     Console.Out.WriteLine(tree.Contains(9));
     foreach (var elem in tree)
     {
         Console.Out.WriteLine(elem);
     }
 }
        /// <summary>
        /// Determine whether the given time (in milliseconds) is 'included' by the
        /// Calendar.
        /// <p>
        /// Note that this Calendar is only has full-day precision.
        /// </p>
        /// </summary>
        public override bool IsTimeIncluded(DateTime timeStampUtc)
        {
            if (!base.IsTimeIncluded(timeStampUtc))
            {
                return(false);
            }

            DateTime lookFor = timeStampUtc.Date;

            return(!(dates.Contains(lookFor)));
        }
        /// <summary>
        /// Determine whether the given time (in milliseconds) is 'included' by the
        /// Calendar.
        /// <para>
        /// Note that this Calendar is only has full-day precision.
        /// </para>
        /// </summary>
        public override bool IsTimeIncluded(DateTimeOffset timeStampUtc)
        {
            if (!base.IsTimeIncluded(timeStampUtc))
            {
                return(false);
            }

            //apply the timezone
            timeStampUtc = TimeZoneUtil.ConvertTime(timeStampUtc, this.TimeZone);
            DateTime lookFor = timeStampUtc.Date;

            return(!(dates.Contains(lookFor)));
        }
Exemple #8
0
        private void Enumerate(IPriorityQueue <int> pq)
        {
            var set = new TreeSet <int>();

            Fill(pq, set, 5000);
            var count = 0;

            foreach (var item in pq)
            {
                count++;
                Assert.True(set.Contains(item));
            }
            Assert.Equal(5000, count);

            for (var i = 0; i < 2500; i++)
            {
                Assert.True(set.Contains(pq.Pop()));
            }
            Assert.Equal(2500, pq.Count);

            count = 0;
            foreach (var item in pq)
            {
                count++;
                Assert.True(set.Contains(item));
            }
            Assert.Equal(2500, count);

            Fill(pq, set, 1000);
            count = 0;
            foreach (var item in pq)
            {
                count++;
                Assert.True(set.Contains(item));
            }
            Assert.Equal(3500, count);
        }
Exemple #9
0
        public void TestTreeSetSimpleOperations()
        {
            ISortedSet <int> set = new TreeSet <int>();
            var count            = 0;

            foreach (var item in set)
            {
                count++;
            }
            Assert.True(count == 0);
            Assert.True(set.Count == 0);
            set.Add(10);
            set.Add(20);
            set.Add(30);
            set.Add(5);
            set.Add(1);
            Assert.True(set.Contains(20));
            Assert.False(set.Contains(100));
            Assert.Equal(5, set.Count);
            Assert.Equal(30, set.Max);
            Assert.Equal(1, set.Min);

            var list = new List <int>();

            foreach (var item in set)
            {
                list.Add(item);
            }

            Assert.True(list.Count == set.Count);

            foreach (var item in list)
            {
                Assert.True(set.Contains(item));
            }

            var array = new int[5];

            set.CopyTo(array, 0);
            foreach (var item in array)
            {
                Assert.True(set.Contains(item));
            }

            Assert.True(set.Remove(5));
            Assert.Equal(4, set.Count);
            Assert.False(set.Contains(5));

            set.RemoveMin();
            Assert.Equal(3, set.Count);
            Assert.False(set.Contains(1));

            set.Clear();
            Assert.Equal(0, set.Count);
        }
Exemple #10
0
        private void Fill(IPriorityQueue <int> pq, TreeSet <int> set, int count)
        {
            var rand  = new Random((int)DateTime.Now.Ticks & 0x0000ffff);
            var index = 0;

            while (index < count)
            {
                var next = rand.Next();
                if (!set.Contains(next))
                {
                    set.Add(next);
                    pq.Push(next);
                    index++;
                }
            }
        }
Exemple #11
0
        public void TestMaxPriortyQueueConstructor()
        {
            var pq1 = new MaxPriorityQueue <int>();

            MaxPriorityQueueConstructor(pq1);

            var pq2 = new MaxPriorityQueue <Order>(new OrderComparer());

            Assert.True(pq2.IsEmpty);
            MaxPriorityQueueConstructorWithOrder(pq2);
            Assert.False(pq2.IsEmpty);

            var pq3 = new MaxPriorityQueue <Order>((x1, x2) => x1.Id - x2.Id);

            Assert.True(pq3.IsEmpty);
            MaxPriorityQueueConstructorWithOrder(pq3);
            Assert.False(pq3.IsEmpty);

            var rand     = new Random((int)DateTime.Now.Ticks & 0x0000ffff);
            var set      = new TreeSet <int>();
            var orderSet = new TreeSet <Order>(new OrderComparer());
            var count    = 0;

            while (count < 5000)
            {
                var next  = rand.Next();
                var order = new Order {
                    Id = next
                };
                if (!orderSet.Contains(order))
                {
                    set.Add(next);
                    orderSet.Add(order);
                    count++;
                }
            }

            var pq4 = new MaxPriorityQueue <Order>(orderSet, new OrderComparer().Compare);

            Assert.Equal(5000, pq4.Count);
            Push(pq4, set, rand, 1000);
            Assert.Equal(6000, pq4.Count);
            Pop(pq4, set, 2000);
            Assert.Equal(4000, pq4.Count);
            Push(pq4, set, rand, 10000);
            Assert.Equal(14000, pq4.Count);
        }
Exemple #12
0
        public void TestContains()
        {
            Random        random = new Random();
            TreeSet <int> set    = new TreeSet <int>(branchingFactor: 4);

            for (int i = 0; i < 2 * 4 * 4; i++)
            {
                int value = random.Next(set.Count + 1);
                set.Add(i);

                // Use set.Contains(i) since this is a targeted collection API test
#pragma warning disable xUnit2017 // Do not use Contains() to check if a value exists in a collection
                Assert.True(set.Contains(i));
#pragma warning restore xUnit2017 // Do not use Contains() to check if a value exists in a collection
            }

            set.Validate(ValidationRules.None);
        }
Exemple #13
0
        private void Push(MaxPriorityQueue <Order> pq, TreeSet <int> set, Random rand, int count)
        {
            var index = 0;

            while (index < count)
            {
                var next = rand.Next();
                if (!set.Contains(next))
                {
                    var order = new Order {
                        Id = next
                    };
                    pq.Push(order);
                    set.Add(next);
                    index++;
                    Assert.Equal(set.Max, pq.Top.Id);
                }
            }
        }
        protected override void UpdateUserInterface()
        {
            CmdDelete.Enabled = DaysExcluded.SelectedIndex > -1;
            CmdAdd.Enabled    = !mExcludedDates.Contains(ExcludeDay.Value.Date);

            foreach (var excDate in mCalendar.ExcludedDates)
            {
                mCalendar.RemoveExcludedDate(excDate);
            }

            foreach (var excDate in mExcludedDates)
            {
                mCalendar.AddExcludedDate(excDate);
            }

            mCalendar.Description = string.Format("Excluding {0} dates: ", mCalendar.ExcludedDates.Count);
            foreach (var excDate in mCalendar.ExcludedDates)
            {
                mCalendar.Description += excDate.Date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern) + ", ";
            }
            mCalendar.Description = mCalendar.Description.TrimEnd(new[] { ',', ' ' });
        }
Exemple #15
0
 public override int GetItemViewType(int position)
 {
     return(sectionHeaderTreeSet.Contains(position) ? TYPE_SEPARATOR : TYPE_ITEM);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="Option"/> class.
        /// </summary>
        /// <param name="attribute">The attribute describing this option.</param>
        /// <param name="memberInfo">The <see cref="MemberInfo"/> object pointing to the member to which the attribute was applied.</param>
        /// <param name="cmdLineObject">The command line manager object.</param>
        /// <param name="optionGroups">A complete list of all available option groups.</param>
        /// <param name="numberFormatInfo">The number format info to use for parsing numerical arguments.</param>
        public Option(CommandLineOptionAttribute attribute, MemberInfo memberInfo, object cmdLineObject,
                      ICollection <OptionGroup> optionGroups, NumberFormatInfo numberFormatInfo)
        {
            mObject           = cmdLineObject;
            mMember           = memberInfo;
            mUsage            = attribute.BoolFunction;
            mDescription      = attribute.Description;
            mNumberFormatInfo = numberFormatInfo ?? CultureInfo.CurrentCulture.NumberFormat;
            mDefaultValue     = attribute.DefaultAssignmentValue;
            mMinValue         = attribute.MinValue;
            mMaxValue         = attribute.MaxValue;

            // Check the validity of the member for which this attribute was defined
            switch (memberInfo.MemberType)
            {
            case MemberTypes.Field:
                FieldInfo fieldInfo = (FieldInfo)memberInfo;
                if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal field for this attribute; field must be writeable");
                }

                mOptionType = fieldInfo.FieldType;
                break;

            case MemberTypes.Method:
                MethodInfo      method     = (MethodInfo)memberInfo;
                ParameterInfo[] parameters = method.GetParameters();

                if (parameters.Length != 1)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal method for this attribute; the method must accept exactly one parameter");
                }

                if (parameters[0].IsOut)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal method for this attribute; the parameter of the method must not be an out parameter");
                }

                if (IsArray(parameters[0].ParameterType) || IsCollectionType(parameters[0].ParameterType))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal method for this attribute; the parameter of the method must be a non-array and non-collection type");
                }

                mOptionType = parameters[0].ParameterType;
                break;

            case MemberTypes.Property:
                PropertyInfo propInfo = (PropertyInfo)memberInfo;

                if (!propInfo.CanWrite && !IsCollectionType(propInfo.PropertyType))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal property for this attribute; property for non-collection type must be writable");
                }

                if (!propInfo.CanRead && IsCollectionType(propInfo.PropertyType))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal property for this attribute; property for collection type must be readable");
                }

                if (!(propInfo.CanRead && propInfo.CanWrite) && IsArray(propInfo.PropertyType))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                                 "Illegal property for this attribute; property representing array type must be both readable and writeable");
                }

                mOptionType = propInfo.PropertyType;
                break;

            default:
                throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                             "Illegal member for this attribute; member must be a property, method (accepting one parameter) or a field");
            }

            mMinOccurs = attribute.MinOccurs;

            // MaxOccurs does not have a default value (since this is different for various types), so we set it here.
            if (!attribute.IsMaxOccursSet)
            {
                // Use default setting for MaxOccurs
                if (IsArray(mOptionType) || IsCollectionType(mOptionType))
                {
                    mMaxOccurs = 0; // Unlimited
                }
                else
                {
                    mMaxOccurs = 1;
                }
            }
            else
            {
                mMaxOccurs = attribute.MaxOccurs;
            }

            if (mMinOccurs > mMaxOccurs && mMaxOccurs > 0)
            {
                throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                             String.Format(CultureInfo.CurrentUICulture, "MinOccurs ({0}) must not be larger than MaxOccurs ({1})", mMinOccurs, mMaxOccurs));
            }

            if (mMaxOccurs != 1 && !(IsArray(mOptionType) || IsCollectionType(mOptionType)) && mMember.MemberType != MemberTypes.Method)
            {
                throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                                             "Invalid cardinality for member; MaxOccurs must be equal to one (1) for any non-array or non-collection type");
            }

            CommandLineManagerAttribute objectAttr = (CommandLineManagerAttribute)Attribute.GetCustomAttribute(mObject.GetType(), typeof(CommandLineManagerAttribute));

            if (objectAttr == null)
            {
                throw new AttributeException(String.Format(CultureInfo.CurrentUICulture,
                                                           "Class {0} contains a CommandLineOptionAttribute, but does not have the attribute CommandLineObjectAttribute", mObject.GetType().FullName));
            }


            // Assign the name of this option from the member itself if no name is explicitly provided
            if (attribute.Name == null)
            {
                mName = memberInfo.Name;
            }
            else
            {
                mName = attribute.Name;
            }

            // Find the group (if any) that this option belongs to in the list of available option groups
            if (attribute.GroupId != null)
            {
                if (!optionGroups.Find(new Func <OptionGroup, bool>(
                                           delegate(OptionGroup searchGroup)
                {
                    return(attribute.GroupId.Equals(searchGroup.Id));
                }), out mGroup))
                {
                    throw new LogicException(String.Format(CultureInfo.CurrentUICulture, "Undefined group {0} referenced from  member {1} in {2}", attribute.GroupId, memberInfo.Name, cmdLineObject.GetType().FullName));
                }
                mGroup.Options.Add(mName, this);
            }

            // Recursively find out if this option requires explicit assignment
            if (attribute.DoesRequireExplicitAssignment.HasValue)
            {
                mRequireExplicitAssignment = attribute.DoesRequireExplicitAssignment.Value;
            }
            else if (mGroup != null)
            {
                mRequireExplicitAssignment = mGroup.RequireExplicitAssignment;
            }
            else
            {
                mRequireExplicitAssignment = objectAttr.RequireExplicitAssignment;
            }

            // Make sure the type of the field, property or method is supported
            if (!IsTypeSupported(mOptionType))
            {
                throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                             "Unsupported type for command line option.");
            }


            // Make sure MinValue and MaxValue is not specified for any non-numerical type.
            if (mMinValue != null || mMaxValue != null)
            {
                if (!IsNumericalType)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                 "MinValue and MaxValue must not be specified for a non-numerical type");
                }
                else if (!mMinValue.GetType().IsAssignableFrom(GetBaseType(mOptionType)))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                 "Illegal value for MinValue or MaxValue, not the same type as option");
                }
            }

            // Some special checks for numerical types
            if (IsNumericalType)
            {
                // Assign the default MinValue if it was not set and this is a numerical type
                if (IsNumericalType && mMinValue == null)
                {
                    mMinValue = GetBaseType(mOptionType).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
                }

                // Assign the defaul MaxValue if it was not set and this is a numerical type
                if (IsNumericalType && mMaxValue == null)
                {
                    mMaxValue = GetBaseType(mOptionType).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
                }

                // Check that MinValue <= MaxValue
                if (IsNumericalType && ((IComparable)MinValue).CompareTo(MaxValue) > 0)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                 "MinValue must not be greater than MaxValue");
                }
            }

            // Check that the DefaultValue is not set if the option does not require explicit assignment.
            // If it were allowed, it would be ambiguos for an option separated from a value by a white space character
            // since we wouldn't know whether that would set the default value or assign it to the following value.
            if (mDefaultValue != null && !mRequireExplicitAssignment)
            {
                throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                             "DefaultValue must not be specified when RequireExplicitAssignment is set to false");
            }

            // Check that the type of any set default value matches that of this option, or is string, and
            // convert it to the type of this option.
            if (mDefaultValue != null)
            {
                if (mDefaultValue.GetType() == typeof(string))
                {
                    try
                    {
                        mDefaultValue = GetCheckedValueForSetOperation(mDefaultValue);
                    }
                    catch (OverflowException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                     "DefaultValue was less than MinValue or greater than MaxValue for this option");
                    }
                    catch (FormatException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                     "DefaultValue was not specified in the correct format for the type of this option");
                    }
                }
                else if (GetBaseType(mOptionType) != mDefaultValue.GetType())
                {
                    try
                    {
                        mDefaultValue = Convert.ChangeType(mDefaultValue, GetBaseType(mOptionType), mNumberFormatInfo);
                    }
                    catch (InvalidCastException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                     "The type of the DefaultValue specified is not compatible with the type of the member to which this attribute applies");
                    }
                }
            }

            // If this is an enum, check that it doesn't have members only distinguishable by case, and
            // add the members to the mEnumerationValues set for speedy access when checking values assigned
            // to this member.
            Type type = GetBaseType(mOptionType);

            if (type.IsEnum)
            {
                mEnumerationValues = new TreeSet <string>(StringComparer.OrdinalIgnoreCase);
                foreach (FieldInfo field in type.GetFields())
                {
                    if (field.IsLiteral)
                    {
                        if (mEnumerationValues.Contains(field.Name))
                        {
                            throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                                         "This enumeration is not allowed as a command line option since it contains fields that differ only by case");
                        }
                        mEnumerationValues.Add(field.Name);
                    }
                }
            }
        }
Exemple #17
0
        public void TestTreeSetRandomOperations()
        {
            for (int j = 0; j < 10; j++)
            {
                ISortedSet <int> set = new TreeSet <int>();

                Random     randomValue = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF));
                List <int> list        = new List <int>();
                int        testNumber  = 1000;
                while (set.Count < testNumber)
                {
                    int v = randomValue.Next();
                    if (!set.Contains(v))
                    {
                        set.Add(v);
                        list.Add(v);
                    }
                }

                int count = 0;
                foreach (var item in set)
                {
                    Assert.True(list.Contains(item));
                    count++;
                }
                Assert.True(count == set.Count);

                Assert.Equal(testNumber, set.Count);

                Random randomIndex = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF));
                for (int i = 0; i < 100; i++)
                {
                    int index = randomIndex.Next();
                    index  = index < 0 ? (-index) : index;
                    index %= testNumber;
                    int testValue = list[index];
                    Assert.True(set.Contains(testValue));
                }

                for (int i = 0; i < 100; i++)
                {
                    int min = list.Min();
                    Assert.Equal(min, set.Min);
                    set.RemoveMin();
                    Assert.Equal(testNumber - i - 1, set.Count);
                    Assert.False(set.Contains(min));
                    list.Remove(min);
                }

                testNumber -= 100;
                for (int i = 0; i < 100; i++)
                {
                    int max = list.Max();
                    Assert.Equal(max, set.Max);
                    set.RemoveMax();
                    Assert.Equal(testNumber - i - 1, set.Count);
                    Assert.False(set.Contains(max));
                    list.Remove(max);
                }

                testNumber -= 100;
                for (int i = 0; i < 100; i++)
                {
                    int index = randomIndex.Next();
                    index  = index < 0 ? (-index) : index;
                    index %= testNumber - i;
                    int toRemove = list[index];
                    Assert.True(set.Contains(toRemove));
                    Assert.True(set.Remove(toRemove));
                    Assert.False(set.Contains(toRemove));
                    Assert.Equal(testNumber - i - 1, set.Count);
                    list.Remove(toRemove);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Option"/> class.
        /// </summary>
        /// <param name="attribute">The attribute describing this option.</param>
        /// <param name="memberInfo">The <see cref="MemberInfo"/> object pointing to the member to which the attribute was applied.</param>
        /// <param name="cmdLineObject">The command line manager object.</param>
        /// <param name="optionGroups">A complete list of all available option groups.</param>
        /// <param name="numberFormatInfo">The number format info to use for parsing numerical arguments.</param>
        public Option(CommandLineOptionAttribute attribute, MemberInfo memberInfo, object cmdLineObject, 
            ICollection<OptionGroup> optionGroups, NumberFormatInfo numberFormatInfo)
        {            
            mObject = cmdLineObject;
            mMember = memberInfo;
            mUsage = attribute.BoolFunction;
            mDescription = attribute.Description;
            mNumberFormatInfo = numberFormatInfo ?? CultureInfo.CurrentCulture.NumberFormat;
            mDefaultValue = attribute.DefaultAssignmentValue;
            mMinValue = attribute.MinValue;
            mMaxValue = attribute.MaxValue;

            // Check the validity of the member for which this attribute was defined
            switch (memberInfo.MemberType)
            {
                case MemberTypes.Field:
                    FieldInfo fieldInfo = (FieldInfo)memberInfo;
                    if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral)
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal field for this attribute; field must be writeable");

                    mOptionType = fieldInfo.FieldType;
                    break;
                case MemberTypes.Method:
                    MethodInfo method = (MethodInfo)memberInfo;
                    ParameterInfo[] parameters = method.GetParameters();

                    if (parameters.Length != 1)
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal method for this attribute; the method must accept exactly one parameter");

                    if (parameters[0].IsOut)
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal method for this attribute; the parameter of the method must not be an out parameter");

                    if (IsArray(parameters[0].ParameterType) || IsCollectionType(parameters[0].ParameterType))
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal method for this attribute; the parameter of the method must be a non-array and non-collection type");

                    mOptionType = parameters[0].ParameterType;
                    break;
                case MemberTypes.Property:
                    PropertyInfo propInfo = (PropertyInfo)memberInfo;

                    if (!propInfo.CanWrite && !IsCollectionType(propInfo.PropertyType))
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal property for this attribute; property for non-collection type must be writable");

                    if (!propInfo.CanRead && IsCollectionType(propInfo.PropertyType))
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal property for this attribute; property for collection type must be readable");

                    if (!(propInfo.CanRead && propInfo.CanWrite) && IsArray(propInfo.PropertyType))
                        throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                            "Illegal property for this attribute; property representing array type must be both readable and writeable");

                    mOptionType = propInfo.PropertyType;
                    break;
                default:
                    throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                        "Illegal member for this attribute; member must be a property, method (accepting one parameter) or a field");
            }

            mMinOccurs = attribute.MinOccurs;

            // MaxOccurs does not have a default value (since this is different for various types), so we set it here.
            if (!attribute.IsMaxOccursSet)
            {
                // Use default setting for MaxOccurs
                if (IsArray(mOptionType) || IsCollectionType(mOptionType))
                    mMaxOccurs = 0; // Unlimited 
                else
                    mMaxOccurs = 1;
            }
            else
            {
                mMaxOccurs = attribute.MaxOccurs;
            }

            if (mMinOccurs > mMaxOccurs && mMaxOccurs > 0)
                throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo, 
                    String.Format(CultureInfo.CurrentUICulture, "MinOccurs ({0}) must not be larger than MaxOccurs ({1})", mMinOccurs, mMaxOccurs));

            if (mMaxOccurs != 1 && !(IsArray(mOptionType) || IsCollectionType(mOptionType)) && mMember.MemberType != MemberTypes.Method)
                throw new AttributeException(typeof(CommandLineOptionAttribute), memberInfo,
                    "Invalid cardinality for member; MaxOccurs must be equal to one (1) for any non-array or non-collection type");

            CommandLineManagerAttribute objectAttr = (CommandLineManagerAttribute)Attribute.GetCustomAttribute(mObject.GetType(), typeof(CommandLineManagerAttribute));
            if (objectAttr == null)
                throw new AttributeException(String.Format(CultureInfo.CurrentUICulture, 
                    "Class {0} contains a CommandLineOptionAttribute, but does not have the attribute CommandLineObjectAttribute", mObject.GetType().FullName));


            // Assign the name of this option from the member itself if no name is explicitly provided 
            if (attribute.Name == null)
            {
                mName = memberInfo.Name;
            }
            else
            {
                mName = attribute.Name;
            }

            // Find the group (if any) that this option belongs to in the list of available option groups
            if (attribute.GroupId != null)
            {
                if (!optionGroups.Find(new Fun<OptionGroup, bool>(
                    delegate(OptionGroup searchGroup)
                    {
                        return attribute.GroupId.Equals(searchGroup.Id);
                    }), out mGroup)) 
                {
                    throw new LogicException(String.Format(CultureInfo.CurrentUICulture, "Undefined group {0} referenced from  member {1} in {2}", attribute.GroupId, memberInfo.Name, cmdLineObject.GetType().FullName));
                }
                mGroup.Options.Add(mName, this);
            }

            // Recursively find out if this option requires explicit assignment
            if (attribute.DoesRequireExplicitAssignment.HasValue)
            {
                mRequireExplicitAssignment = attribute.DoesRequireExplicitAssignment.Value;
            }
            else if (mGroup != null)
            {
                mRequireExplicitAssignment = mGroup.RequireExplicitAssignment;
            }
            else
            {
                mRequireExplicitAssignment = objectAttr.RequireExplicitAssignment;
            }

            // Make sure the type of the field, property or method is supported
            if (!IsTypeSupported(mOptionType))
                throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                    "Unsupported type for command line option.");


            // Make sure MinValue and MaxValue is not specified for any non-numerical type.
            if (mMinValue != null || mMaxValue != null)
            {
                if (!IsNumericalType)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                        "MinValue and MaxValue must not be specified for a non-numerical type");
                }
                else if (!mMinValue.GetType().IsAssignableFrom(GetBaseType(mOptionType)))
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                        "Illegal value for MinValue or MaxValue, not the same type as option");
                }
            }

            // Some special checks for numerical types
            if (IsNumericalType)
            {
                // Assign the default MinValue if it was not set and this is a numerical type
                if (IsNumericalType && mMinValue == null)
                {
                    mMinValue = GetBaseType(mOptionType).GetField("MinValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
                }

                // Assign the defaul MaxValue if it was not set and this is a numerical type
                if (IsNumericalType && mMaxValue == null)
                {
                    mMaxValue = GetBaseType(mOptionType).GetField("MaxValue", BindingFlags.Static | BindingFlags.Public).GetValue(null);
                }

                // Check that MinValue <= MaxValue
                if (IsNumericalType && ((IComparable)MinValue).CompareTo(MaxValue) > 0)
                {
                    throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                        "MinValue must not be greater than MaxValue");
                }
            }

            // Check that the DefaultValue is not set if the option does not require explicit assignment. 
            // If it were allowed, it would be ambiguos for an option separated from a value by a white space character
            // since we wouldn't know whether that would set the default value or assign it to the following value.
            if (mDefaultValue != null && !mRequireExplicitAssignment)
            {
                throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                    "DefaultValue must not be specified when RequireExplicitAssignment is set to false");
            }

            // Check that the type of any set default value matches that of this option, or is string, and
            // convert it to the type of this option.
            if (mDefaultValue != null)
            {
                if (mDefaultValue.GetType() == typeof(string))
                {
                    try
                    {
                        mDefaultValue = GetCheckedValueForSetOperation(mDefaultValue);
                    }
                    catch (OverflowException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                            "DefaultValue was less than MinValue or greater than MaxValue for this option");
                    }
                    catch (FormatException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                            "DefaultValue was not specified in the correct format for the type of this option");
                    }
                }
                else if (GetBaseType(mOptionType) != mDefaultValue.GetType())
                {
                    try
                    {
                        mDefaultValue = Convert.ChangeType(mDefaultValue, GetBaseType(mOptionType), mNumberFormatInfo);
                    }
                    catch (InvalidCastException)
                    {
                        throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                            "The type of the DefaultValue specified is not compatible with the type of the member to which this attribute applies");
                    }
                }
            }            

            // If this is an enum, check that it doesn't have members only distinguishable by case, and
            // add the members to the mEnumerationValues set for speedy access when checking values assigned 
            // to this member.
            Type type = GetBaseType(mOptionType);
            if (type.IsEnum)
            {
                mEnumerationValues = new TreeSet<string>(StringComparer.OrdinalIgnoreCase);
                foreach (FieldInfo field in type.GetFields())
                {
                    if (field.IsLiteral)
                    {
                        if (mEnumerationValues.Contains(field.Name))
                        {
                            throw new AttributeException(typeof(CommandLineOptionAttribute), mMember,
                                "This enumeration is not allowed as a command line option since it contains fields that differ only by case");
                        }
                        mEnumerationValues.Add(field.Name);
                    }
                }                
            }
        }