/// <summary>
 /// Traverses through each option within an option contract and performs specific operation.
 /// </summary>
 /// <param name="optionContract">The option contract to be traversed.</param>
 /// <param name="handler">The operation which should be taken on the option.</param>
 private void TraverseOptions(OptionContractBase optionContract, OptionTraversalEventHandler handler)
 {
     foreach (PropertyInfo property in optionContract.GetType().GetProperties())
     {
         //foreach (object customAttribute in property.GetCustomAttributes(false))
         //{
         //    if (customAttribute is OptionAttribute)
         //    {
         //        handler(optionContract, property, customAttribute as OptionAttribute);
         //        break;
         //    }
         //}
         object[] customAttributes = property.GetCustomAttributes(typeof(OptionAttribute), false);
         if (customAttributes.Length > 0)
         {
             OptionAttribute optionAttribute = customAttributes.First() as OptionAttribute;
             handler(optionContract, property, optionAttribute);
         }
     }
 }
        /// <summary>
        /// Populates the property of a patternized contract with the values which come from the 
        /// command line argument.
        /// </summary>
        /// <param name="target">The instance of an option contract to be populated.</param>
        /// <param name="property">The reflection information of the property to which the value should be populated.</param>
        /// <param name="attribute">The option attribute on the property.</param>
        /// <exception cref="AdaptiveConsole.ArgumentMissingException">Throws when an option is a required option but it is not specified in the command line arguments.</exception>
        /// <exception cref="AdaptiveConsole.InvalidOptionException">Throws when an invalid option type is provided.</exception>
        private void PopulateContractOption(OptionContractBase target, PropertyInfo property, OptionAttribute attribute)
        {
            bool containsOption = false;
            string optionName = string.Empty;

            switch (attribute.Type)
            {
                // If the option is a swith, and there is an occurrence in the command line argument,
                // that means the swith is turn on and we set the property to True. If there is no
                // occurrence of the option in the command line argument, it means that the switch
                // is turn off.
                case OptionType.Switch:
                    foreach (ArgumentInfo arg in this.Arguments)
                    {
                        if (this.ContainsOption(attribute.Name, arg.Argument, attribute.CaseSensitive, OPTION_ATTRIBUTE_NAME_SEP))
                        {
                            arg.Category = ArgumentCategory.Option;
                            containsOption = true;
                            break;
                        }
                    }
                    if (containsOption)
                        property.SetValue(target, true, null);
                    else
                        property.SetValue(target, false, null);
                    break;
                // If the option is a single value option, for each command line argument, we firstly
                // try getting the option name and value from the argument. If failed in getting the name
                // and value, that means current argument is not a single value option, we iterates to
                // the next command line argument. If we successfully get the name and value from the
                // single value option, we then check if the option name contains the name of the argument.
                // If it does, that means this is the command line argument that we want and we should populate
                // the option value to the property of the option.
                case OptionType.SingleValue:
                    optionName = string.Empty;
                    string optionValue = string.Empty;
                    foreach (ArgumentInfo arg in this.Arguments)
                    {
                        if (!this.GetSingleValue(arg.Argument, ref optionName, ref optionValue, OPTION_NAME_VALUE_SEP))
                            continue;
                        if (this.ContainsOption(attribute.Name, optionName, attribute.CaseSensitive, OPTION_ATTRIBUTE_NAME_SEP))
                        {
                            arg.Category = ArgumentCategory.Option;
                            containsOption = true;
                            break;
                        }
                    }
                    if (containsOption)
                        property.SetValue(target, optionValue, null);
                    else
                    {
                        if (!attribute.Required)
                        {
                            // Sunny Chen Modified Begin - 9/20/2008 - Added for handling the Default field of the option.
                            if (!attribute.Default.Equals(string.Empty))
                                property.SetValue(target, attribute.Default, null);
                            else
                                property.SetValue(target, string.Empty, null);
                            // Sunny Chen Modified End
                        }
                        else
                            throw new ArgumentMissingException("Argument {0} is required.", attribute.Name);
                    }
                    break;
                // If the option is a multiple value option, for each command line argument, we firstly
                // try getting the option name and values from the argument. If failed in getting the name
                // and values, that means current argument is not a multiple value option, we iterates to
                // the next command line argument. If we successfully get the name and values from the
                // multiple value option, we then check if the option name contains the name of the argument.
                // If it does, that means this is the command line argument that we want and we should populate
                // the option values to the property of the option.
                case OptionType.ValueList:
                    optionName = string.Empty;
                    string[] optionValues = null;
                    foreach (ArgumentInfo arg in this.Arguments)
                    {
                        if (!this.GetMultipleValues(arg.Argument, ref optionName, ref optionValues, OPTION_NAME_VALUE_SEP, attribute.ValueSeparator))
                            continue;
                        if (this.ContainsOption(attribute.Name, optionName, attribute.CaseSensitive, OPTION_ATTRIBUTE_NAME_SEP))
                        {
                            arg.Category = ArgumentCategory.Option;
                            containsOption = true;
                            break;
                        }
                    }
                    if (containsOption)
                        property.SetValue(target, optionValues, null);
                    else
                    {
                        if (!attribute.Required)
                            property.SetValue(target, null, null);
                        else
                            throw new ArgumentMissingException("Argument {0} is required.", attribute.Name);
                    }
                    break;
                default:
                    throw new InvalidOptionException("The option is of the invalid type.");
            }
        }