private static void Validate(CommandInfo?command) { if (command == null) { return; } // Get duplicate options for command. var duplicateOptions = GetDuplicates(command); if (duplicateOptions.Length > 0) { throw ConfigurationException.DuplicateOption(command, duplicateOptions); } // No children? if (command.IsBranch && command.Children.Count == 0) { throw ConfigurationException.BranchHasNoChildren(command); } // Multiple vector arguments? var arguments = command.Parameters.OfType <CommandArgument>(); if (arguments.Any(x => x.ParameterKind == ParameterKind.Vector)) { // Multiple vector arguments for command? if (arguments.Count(x => x.ParameterKind == ParameterKind.Vector) > 1) { throw ConfigurationException.TooManyVectorArguments(command); } // Make sure that vector arguments are specified last. if (arguments.Last().ParameterKind != ParameterKind.Vector) { throw ConfigurationException.VectorArgumentNotSpecifiedLast(command); } } var options = command.Parameters.OfType <CommandOption>(); foreach (var option in options) { // Pair deconstructable? if (option.Property.PropertyType.IsPairDeconstructable()) { if (option.PairDeconstructor != null && option.Converter != null) { throw ConfigurationException.OptionBothHasPairDeconstructorAndTypeParameter(option); } } else if (option.PairDeconstructor != null) { throw ConfigurationException.OptionTypeDoesNotSupportDeconstruction(option); } // Optional options that are not flags? if (option.ParameterKind == ParameterKind.FlagWithValue && !option.IsFlagValue()) { throw ConfigurationException.OptionalOptionValueMustBeFlagWithValue(option); } } // Validate child commands. foreach (var childCommand in command.Children) { Validate(childCommand); } }