/// <summary>
        /// Adds an input or output value to the data grids.
        /// </summary>
        /// <param name="argDesc">The argument description for the argument.</param>
        /// <param name="svDesc">The state variable description for the linked state variable to the argument.</param>
        /// <param name="inputIndex">The current input index.</param>
        /// <param name="outputIndex">The current output index.</param>
        protected void AddIOValue(ArgumentDescription argDesc, StateVariableDescription svDesc, ref int inputIndex, ref int outputIndex)
        {
            StateVariableDataType ldtType;

            // Get the data type for the state variable description
            if (svDesc == null)
                ldtType = StateVariableDataType.tunknown;
            else
                ldtType = svDesc.DataTypeValue;

            switch (argDesc.DirectionValue)
            {
                case ArgumentDirection.In:
                    // If its an input then add it
                    int liIndex = dgInputs.Rows.Add(
                        argDesc.Name,
                        ldtType.Description(),
                        ldtType.StringFromValue(ldtType.Default()));

                    // Set its row info
                    dgInputs.Rows[liIndex].Tag = new RowInfo(argDesc, svDesc, inputIndex);

                    // Increment the input index
                    inputIndex++;

                    break;

                case ArgumentDirection.Out:
                    // If its an output then add it
                    liIndex = dgOutputs.Rows.Add(
                        argDesc.Name,
                        ldtType.Description(),
                        String.Empty);

                    // Set its row info
                    dgOutputs.Rows[liIndex].Tag = new RowInfo(argDesc, svDesc, outputIndex);

                    // Increment the output index
                    outputIndex++;

                    break;
            }
        }
 /// <summary>
 /// Creates a new state variable tree item.
 /// </summary>
 /// <param name="service">The service for which this state variable belongs.</param>
 /// <param name="desc">The state variable description.</param>
 public UPnPStateVarTreeItem(Service service, StateVariableDescription desc)
     : base(service)
 {
     mdDesc = desc;
 }
        /// <summary>
        /// Determines whether a state variable is queryable and therefore 
        /// should have its property accessor created.
        /// </summary>
        /// <param name="service">The service the state variable belongs to.</param>
        /// <param name="testStateVars">True to test for query ability, false to allow.</param>
        /// <param name="stateVarDesc">The state variaible description for which needs to be tested.</param>
        /// <returns>True if the state variable should have its accessor property created.</returns>
        private bool IsStateVarQueryable(Service service, bool testStateVars, StateVariableDescription stateVarDesc)
        {
            // Do we want to test for queryable ability
            if (testStateVars)
            {
                bool lbAddProp = false;

                try
                {
                    // Attempt to query the state variable
                    service.QueryStateVariable(stateVarDesc.Name);

                    // If succeeded then allow the property
                    lbAddProp = true;
                }
                catch (UPnPException loE)
                {
                    // If its variable value unknown then its probably a valid state variable
                    if (loE.Code == UPnPException.UPnPErrorCode.UPNP_E_VARIABLE_VALUE_UNKNOWN)
                        lbAddProp = true;
                }
                catch (Exception)
                {
                }

                // Return whether the property should be added
                return lbAddProp;
            }
            else
                // We want to add it irrespective
                return true;
        }
        /// <summary>
        /// Generates the descriptive details for a state variable, eg. AllowedRange, Defulat, AllowedValues.
        /// </summary>
        /// <param name="stateVarDesc">The state variable description describing the state variable.</param>
        /// <returns>A string containing a single line comment.</returns>
        private string GenerateStateVariableDescriptionComment(StateVariableDescription stateVarDesc)
        {
            if (stateVarDesc != null)
            {
                StringBuilder lsbComment = new StringBuilder();

                // Allowed range
                if (stateVarDesc.AllowedRange != null)
                {
                    // Allowed range - min and max
                    if (
                        !string.IsNullOrEmpty(stateVarDesc.AllowedRange.Minimum) ||
                        !string.IsNullOrEmpty(stateVarDesc.AllowedRange.Maximum)
                       )
                        lsbComment.Append(
                            string.Format(
                                CodeGenProvider.StateVarAllowedRangeComment,
                                (string.IsNullOrEmpty(stateVarDesc.AllowedRange.Minimum) ? CodeGenProvider.ArgMinimum : stateVarDesc.AllowedRange.Minimum),
                                (string.IsNullOrEmpty(stateVarDesc.AllowedRange.Minimum) ? CodeGenProvider.ArgMaximum : stateVarDesc.AllowedRange.Maximum)
                            )
                        );

                    // Allowed range - step
                    if (!string.IsNullOrEmpty(stateVarDesc.AllowedRange.Step)
                       )
                        lsbComment.Append(
                            string.Format(
                                CodeGenProvider.StateVarStepComment,
                                stateVarDesc.AllowedRange.Step
                            )
                        );
                }

                // Allowed values - ecvluding Enum types
                if (stateVarDesc.AllowedValues != null &&
                    stateVarDesc.AllowedValues.Count > 0 &&
                    stateVarDesc.DataTypeValue != StateVariableDataType.tstring)
                {
                    StringBuilder lsbAllowedValues = new StringBuilder();

                    foreach (string lsAllowedValue in stateVarDesc.AllowedValues)
                        lsbAllowedValues.Append(
                            string.Format(
                                CodeGenProvider.AllowedValue,
                                (lsbAllowedValues.Length == 0 ? string.Empty : CodeGenProvider.Comma),
                                lsAllowedValue
                            )
                        );

                    if (lsbAllowedValues.Length > 0)
                        lsbComment.Append(
                            string.Format(
                                CodeGenProvider.StateVarAllowedValues,
                                lsbAllowedValues.ToString()
                            )
                        );
                }

                // Default value
                if (!string.IsNullOrEmpty(stateVarDesc.DefaultValue))
                    lsbComment.Append(
                        string.Format(
                            CodeGenProvider.StateVarDefaultValueComment,
                            stateVarDesc.DefaultValue
                        )
                    );

                return lsbComment.ToString();
            }
            else
                return string.Empty;
        }
        private void GenerateStateVarEventCode(
            string type, string stateVarFriendlyName, string conversionCode, StringConstants consts, StringBuilder eventHandlers,
            StringBuilder eventCallers, StringBuilder stateVarEventIntercept,
            StateVariableDescription stateVarDesc)
        {
            string lsConstName =
                consts[
                    CodeGenProvider.StateVarNameGroup, stateVarDesc.Name,
                    string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name)
                ];

            eventHandlers.Append(
                string.Format(
                    CodeGenProvider.StateVariableEventHandler,
                    type,
                    stateVarFriendlyName));

            eventCallers.Append(
                string.Format(
                    CodeGenProvider.StateVariableEventCaller,
                    type,
                    stateVarFriendlyName));

            stateVarEventIntercept.Append(
                string.Format(
                    CodeGenProvider.StateVarChangedEventHandlerCaseStatement,
                    lsConstName,
                    stateVarFriendlyName,
                    type,
                    conversionCode));
        }
 /// <summary>
 /// Generates the comments for a state variable including its name.
 /// </summary>
 /// <param name="stateVarDesc">The state variable description describing the state variable.</param>
 /// <returns>A string containing a single line comment.</returns>
 private string GenerateStateVarComment(StateVariableDescription stateVarDesc)
 {
     return string.Format(
         CodeGenProvider.StateVarComment,
         stateVarDesc.Name,
         GenerateStateVariableDescriptionComment(stateVarDesc));
 }
        /// <summary>
        /// Generates the code for a NON enumerated state variable.
        /// </summary>
        /// <param name="consts">The string constants created.</param>
        /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param>
        /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param>
        /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param>
        /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param>
        /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param>
        /// <param name="stateVarDesc">The state variable description.</param>
        /// <param name="friendlyName">The code friendly name of the state variaible.</param>
        /// <param name="addProp">True to add the actual property accessor.</param>
        private void GenerateStateVarCode(
            StringConstants consts, StringBuilder stateVarProps,
            StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept,
            Dictionary<string, string> stateVarTypes, StateVariableDescription stateVarDesc,
            string friendlyName, bool addProp)
        {
            // Get the data type
            string lsType = stateVarDesc.DataTypeValue.BaseType().Name;

            // Append the accessor for the state variaible
            if (addProp)
                stateVarProps.Append(
                    string.Format(
                        CodeGenProvider.NonEnumStateVar,
                        lsType, friendlyName,
                        consts[
                            CodeGenProvider.StateVarNameGroup, stateVarDesc.Name,
                            string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name)
                        ],
                        GenerateStateVarComment(stateVarDesc)));

            // Add the type to the list for the actions
            stateVarTypes[stateVarDesc.Name] = lsType;

            // If the state variable is evented
            if (stateVarDesc.SendEvents)
                GenerateStateVarEventCode(
                    lsType,
                    friendlyName,
                    String.Format(CodeGenProvider.NonEnumStateVarEventConversion, lsType),
                    consts,
                    eventHandlers,
                    eventCallers,
                    stateVarEventIntercept,
                    stateVarDesc);
        }
        /// <summary>
        /// Generates the code for an enumerated state variable.
        /// </summary>
        /// <param name="consts">The string constants created.</param>
        /// <param name="stateVarProps">A StringBuilder to contain property definitions.</param>
        /// <param name="stateVarConversion">A StringBuilder to contain the conversion method definitions.</param>
        /// <param name="stateVarEnums">A StringBuilder to contain the enumerations for the state variables.</param>
        /// <param name="eventHandlers">A StringBuilder to contain event handler declarations for the state variable changes.</param>
        /// <param name="eventCallers">A StringBuilder to contain event caller methods for the state variable changes.</param>
        /// <param name="stateVarEventIntercept">A StringBUilder to contain the case statements for the state variable changed event.</param>
        /// <param name="enumStateVars">A HashSet containing the names of all enumerated state variables.</param>
        /// <param name="stateVarTypes">A Dictionary to contain each state variaible name and its code data type.</param>
        /// <param name="stateVarDesc">The state variable description.</param>
        /// <param name="friendlyName">The code friendly name of the state variaible.</param>
        /// <param name="addProp">True to add the actual property accessor.</param>
        private void GenerateEnumStateVarCode(
            StringConstants consts, StringBuilder stateVarProps, StringBuilder stateVarConversion, StringBuilder stateVarEnums,
            StringBuilder eventHandlers, StringBuilder eventCallers, StringBuilder stateVarEventIntercept,
            HashSet<string> enumStateVars, Dictionary<string, string> stateVarTypes,
            StateVariableDescription stateVarDesc, string friendlyName, bool addProp)
        {
            StringBuilder lsbStateVarEnumValues = new StringBuilder();
            StringBuilder lsbEnumStateVarParse = new StringBuilder();
            StringBuilder lsbEnumStateVarToString = new StringBuilder();

            // Add the state var to the enum list
            enumStateVars.Add(stateVarDesc.Name);

            // Generate allowed values code
            GenerateEnumAllowedValuesCode(
                consts, stateVarDesc, friendlyName, lsbStateVarEnumValues,
                lsbEnumStateVarParse, lsbEnumStateVarToString);

            // Generate enumeration
            stateVarEnums.Append(string.Format(CodeGenProvider.StateVarEnum, friendlyName, lsbStateVarEnumValues));

            // Generate conversion functions
            stateVarConversion.Append(string.Format(CodeGenProvider.EnumStateVarConversion, friendlyName, lsbEnumStateVarParse, lsbEnumStateVarToString));

            // Generate property accessor if required
            if (addProp)
                stateVarProps.Append(
                    string.Format(
                        CodeGenProvider.EnumStateVar, friendlyName,
                        consts[
                            CodeGenProvider.StateVarNameGroup, stateVarDesc.Name,
                            string.Format(CodeGenProvider.StateVarNameComment, stateVarDesc.Name)
                        ],
                        GenerateStateVarComment(stateVarDesc)));

            string lsEnumTypeName = string.Format(CodeGenProvider.EnumStateVarName, friendlyName);

            // Add the type to the list for the actions
            stateVarTypes[stateVarDesc.Name] = lsEnumTypeName;

            // If the state variable is evented
            if (stateVarDesc.SendEvents)
                GenerateStateVarEventCode(
                    lsEnumTypeName,
                    friendlyName,
                    String.Format(CodeGenProvider.EnumStateVarEventConversion, friendlyName),
                    consts,
                    eventHandlers,
                    eventCallers,
                    stateVarEventIntercept,
                    stateVarDesc);
        }
        /// <summary>
        /// Generates the case statements for the conversion functions 
        /// for an enumerated state variaible.
        /// </summary>
        /// <param name="consts">The string constants created.</param>
        /// <param name="stateVarDesc">The state variable description.</param>
        /// <param name="friendlyName">The code friendly name of the state variaible.</param>
        /// <param name="stateVarEnumValues">A StringBuilder to contain the list of enumeration values.</param>
        /// <param name="enumStateVarParse">A StringBuilder to contain the list of state variable parse case statements.</param>
        /// <param name="enumStateVarToString">A StringBuilder to contain the list of state variable to string case statements.</param>
        private void GenerateEnumAllowedValuesCode(
            StringConstants consts, StateVariableDescription stateVarDesc, string friendlyName,
            StringBuilder stateVarEnumValues, StringBuilder enumStateVarParse, StringBuilder enumStateVarToString)
        {
            // For each allowed value
            foreach (string lsAllowedValue in stateVarDesc.AllowedValues)
            {
                // Get the code friendly name
                string lsFriendlyValue = CodeGenProvider.CodeFriendlyIdentifier(lsAllowedValue, false);

                // Create the constant for the allowed value
                string lsAllowedValueConst = consts[
                    string.Format(CodeGenProvider.AllowedValueGroup, CodeGenProvider.CodeFriendlyIdentifier(stateVarDesc.Name, false)),
                    lsAllowedValue,
                    string.Format(CodeGenProvider.AllowedValueComment, lsAllowedValue, stateVarDesc.Name)
                ];

                // Generate the enumeration values
                stateVarEnumValues.Append(string.Format(CodeGenProvider.EnumStateVarValue, lsFriendlyValue, friendlyName));

                // Generate the parse case statement
                enumStateVarParse.Append(string.Format(CodeGenProvider.EnumParseCaseStatement, lsAllowedValueConst, friendlyName, lsFriendlyValue));

                // Generate the to string case statment
                enumStateVarToString.Append(string.Format(CodeGenProvider.EnumToStringCaseStatement, friendlyName, lsFriendlyValue, lsAllowedValueConst));
            }
        }
 /// <summary>
 /// Creates a new row info structure.
 /// </summary>
 /// <param name="argDesc">The argument description for the input or output.</param>
 /// <param name="stateVarDesc">The state variable description for the input or output.</param>
 /// <param name="index">The index of the input or output.</param>
 public RowInfo(ArgumentDescription argDesc, StateVariableDescription stateVarDesc, int index)
 {
     madArgDesc = argDesc;
     msvStateVarDesc = stateVarDesc;
     miIndex = index;
 }