private void BuildCertToolFiles_Service(UPnPService s, DirectoryInfo outputDir)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<scpd>");

            sb.Append("<serviceStateTable>");
            foreach(UPnPStateVariable v in s.GetStateVariables())
            {
                sb.Append("<stateVariable>");
                sb.Append("<name>"+v.Name+"</name>");
                sb.Append("<sendEventsAttribute>");
                if (v.SendEvent)
                {
                    sb.Append("yes");
                }
                else
                {
                    sb.Append("no");
                }
                sb.Append("</sendEventsAttribute>");
                sb.Append("<dataType>"+v.ValueType+"</dataType>");
                if (v.AllowedStringValues!=null && v.AllowedStringValues.Length>0)
                {
                    sb.Append("<allowedValueList>");
                    foreach(string av in v.AllowedStringValues)
                    {
                        sb.Append("<allowedValue>"+av+"</allowedValue>");
                    }
                    sb.Append("</allowedValueList>");
                }
                sb.Append("</stateVariable>");
            }
            sb.Append("</serviceStateTable>");

            if (s.Actions.Count>0)
            {
                sb.Append("<actionList>");
                foreach(UPnPAction a in s.Actions)
                {
                    sb.Append("<action>");
                    sb.Append("<name>"+a.Name+"</name>");
                    if (a.ArgumentList.Length>0)
                    {
                        sb.Append("<argumentList>");
                        foreach(UPnPArgument ag in a.ArgumentList)
                        {
                            sb.Append("<argument>");
                            sb.Append("<name>"+ag.Name+"</name>");
                            sb.Append("<direction>"+ag.Direction+"</direction>");
                            sb.Append("<relatedStateVariable>"+ag.RelatedStateVar.Name+"</relatedStateVariable>");
                            sb.Append("</argument>");
                        }
                        sb.Append("</argumentList>");
                    }
                    sb.Append("</action>");
                }
                sb.Append("</actionList>");
            }

            sb.Append("</scpd>");

            StreamWriter W;
            DText d = new DText();
            d.ATTRMARK = ":";
            d[0] = s.ServiceURN;

            W = File.CreateText(outputDir.FullName + "\\" + d[4] + s.Version.ToString() + ".xml");
            W.Write(sb.ToString());
            W.Close();
        }
        protected static string GetCPlusPlusAbstraction_H_Service(string WC, UPnPService s)
        {
            string WC2 = SourceCodeRepository.GetTextBetweenTags(WC,"//{{{Service_Begin}}}","//{{{Service_End}}}");
            string WC3;

            foreach(UPnPStateVariable V in s.GetStateVariables())
            {
                if (V.SendEvent)
                {
                    WC3 = SourceCodeRepository.GetTextBetweenTags(WC2,"//{{{Service_Events_BEGIN}}}","//{{{Service_Events_END}}}");
                    WC3 = WC3.Replace("{{{VARNAME}}}",V.Name);
                    WC3 = WC3.Replace("{{{PARAMDEF}}}",EmbeddedCGenerator.ToCTypeFromStateVar(V));
                    WC2 = SourceCodeRepository.InsertTextBeforeTag(WC2,"//{{{Service_Events_BEGIN}}}",WC3);
                }
            }
            WC2 = SourceCodeRepository.RemoveAndClearTag("//{{{Service_Events_BEGIN}}}","//{{{Service_Events_END}}}",WC2);

            WC2 = WC2.Replace("{{{SERVICE}}}","UPnP_Service_"+((ServiceGenerator.ServiceConfiguration)s.User).Name);
            WC2 = WC2.Replace("{{{DEVICE}}}","UPnP_Device_"+s.ParentDevice.User2.ToString());
            StringBuilder sb = new StringBuilder();
            foreach(UPnPAction a in s.Actions)
            {
                sb.Append("virtual void "+a.Name+"(void *session");
                foreach(UPnPArgument arg in a.Arguments)
                {
                    if (arg.Direction=="in")
                    {
                        sb.Append(", "+EmbeddedCGenerator.ToCTypeFromArg(arg));
                    }
                }
                sb.Append(");\r\n");
            }
            WC2 = WC2.Replace("//{{{Service_VirtualMethods}}}",sb.ToString());

            sb = new StringBuilder();
            foreach(UPnPAction a in s.Actions)
            {
                sb.Append("void Response_"+a.Name+"(void *session");
                foreach(UPnPArgument arg in a.Arguments)
                {
                    if (arg.Direction=="out")
                    {
                        sb.Append(", "+EmbeddedCGenerator.ToCTypeFromArg(arg));
                    }
                }
                sb.Append(");\r\n");
                if (((ServiceGenerator.ServiceConfiguration)s.User).Actions_Fragmented.Contains(a))
                {
                    sb.Append("	void Response_Async_"+a.Name+"(void *session, char* ArgName, char *ArgValue, int ArgValueLength, int ArgStart, int ArgDone, int ResponseDone);\r\n");
                }
            }
            WC2 = WC2.Replace("//{{{Service_VirtualMethods_Response}}}",sb.ToString());
            return(WC2);
        }
        protected static void GenerateStateVariableLookupTable_Service(UPnPService s, Hashtable t)
        {
            Hashtable lookupTable = new Hashtable();
            t[s] = lookupTable;

            int i=0;

            foreach(UPnPStateVariable v in s.GetStateVariables())
            {
                StringBuilder sb = new StringBuilder();
                StringWriter SW = new StringWriter(sb);
                XmlTextWriter X = new XmlTextWriter(SW);

                UPnPDebugObject dobj = new UPnPDebugObject(v);
                dobj.InvokeNonStaticMethod("GetStateVariableXML",new object[1]{X});

                lookupTable[v] = new object[3]{i,sb.Length,sb.ToString()};
                i+=sb.Length;
            }
        }
        private void BuildEventParser(CodeProcessor cs, UPnPService s, string urn, string name)
        {
            bool eventedservice = false;
            foreach(UPnPStateVariable V in s.GetStateVariables())
            {
                if (V.SendEvent) eventedservice = true;
            }

            if (urn.StartsWith("urn:schemas-upnp-org:"))
            {
                // Standard Service
                urn = urn.Substring(urn.LastIndexOf(":")+1);
            }
            else
            {
                // Proprietary Service
                urn = urn.Replace(":","_");
                urn = urn.Replace("-","_");
                urn = urn.Replace(".","_");
            }

            cs.Append("void "+this.pc_methodPrefix+urn+"_EventSink(char* buffer, int bufferlength, struct UPnPService *service)"+cl);
            cs.Append("{"+cl);
            cs.Append("	struct "+this.pc_methodLibPrefix+"XMLNode *xml,*rootXML;"+cl);
            if (eventedservice == true)
            {
                cs.Append("	char *tempString;"+cl);
                cs.Append("	int tempStringLength;"+cl);
            }
            cs.Append("	int flg,flg2;"+cl);
            cs.Append(cl);

            bool placeLong = false;
            bool placeULong = false;
            foreach(UPnPStateVariable V in s.GetStateVariables())
            {
                if (V.SendEvent)
                {
                    cs.Append("	"+ToCType(V.GetNetType().FullName)+" "+V.Name+" = 0;"+cl);
                    if (V.GetNetType()==typeof(byte[]))
                    {
                        cs.Append("	int " + V.Name+"Length;"+cl);
                    }
                    switch(V.GetNetType().FullName)
                    {
                        case "System.SByte":
                        case "System.Int16":
                        case "System.Int32":
                            placeLong = true;
                            break;
                        case "System.Byte":
                        case "System.UInt16":
                        case "System.UInt32":
                            placeULong = true;
                            break;
                    }
                }
            }
            if (placeLong == true) cs.Append(" long TempLong;"+cl);
            if (placeULong == true) cs.Append(" unsigned long TempULong;"+cl);

            cs.Append(cl);
            cs.Comment("Parse SOAP");
            cs.Append("	rootXML = xml = "+this.pc_methodLibPrefix+"ParseXML(buffer, 0, bufferlength);"+cl);
            cs.Append("	"+this.pc_methodLibPrefix+"ProcessXMLNodeList(xml);"+cl);
            cs.Append(cl);

            cs.Append("while(xml != NULL)"+cl);
            cs.Append("{"+cl);
            cs.Append("	if (xml->NameLength == 11 && memcmp(xml->Name, \"propertyset\", 11)==0)"+cl);
            cs.Append("	{"+cl);
            cs.Append("		if (xml->Next->StartTag != 0)"+cl);
            cs.Append("		{"+cl);
            cs.Append("			flg = 0;"+cl);
            cs.Append("			xml = xml->Next;"+cl);
            cs.Append("			while(flg==0)"+cl);
            cs.Append("			{"+cl);
            cs.Append("				if (xml->NameLength == 8 && memcmp(xml->Name, \"property\", 8)==0)"+cl);
            cs.Append("				{"+cl);
            cs.Append("					xml = xml->Next;"+cl);
            cs.Append("					flg2 = 0;"+cl);
            cs.Append("					while(flg2==0)"+cl);
            cs.Append("					{"+cl);

            foreach(UPnPStateVariable V in s.GetStateVariables())
            {
                if (V.SendEvent)
                {
                    cs.Append("					if (xml->NameLength == "+V.Name.Length.ToString()+" && memcmp(xml->Name, \""+V.Name+"\", "+V.Name.Length.ToString()+") == 0)"+cl);
                    cs.Append("					{"+cl);
                    cs.Append("						tempStringLength = "+this.pc_methodLibPrefix+"ReadInnerXML(xml,&tempString);"+cl);

                    if (ToCType(V.GetNetType().FullName)=="char*")
                    {
                        cs.Append("							tempString[tempStringLength] = '\\0';"+cl);
                        cs.Append("							"+V.Name+" = tempString;"+cl);
                    }
                    else
                    {
                        switch(V.GetNetType().FullName)
                        {
                            case "System.Boolean":
                                cs.Append("							if (tempStringLength >= 5 && strncasecmp(tempString, \"false\", 5)==0)"+cl);
                                cs.Append("							{"+cl);
                                cs.Append("								"+V.Name+" = 0;"+cl);
                                cs.Append("							}"+cl);
                                cs.Append("							else if (tempStringLength >= 1 && strncmp(tempString, \"0\", 1)==0)"+cl);
                                cs.Append("							{"+cl);
                                cs.Append("								"+V.Name+" = 0;"+cl);
                                cs.Append("							}"+cl);
                                cs.Append("							else"+cl);
                                cs.Append("							{"+cl);
                                cs.Append("								"+V.Name+" = 1;"+cl);
                                cs.Append("							}"+cl);
                                break;
                            case "System.DateTime":
                                cs.Append("							tempString[tempStringLength] = '\\0';"+cl);
                                cs.Append("							"+V.Name+" = "+this.pc_methodLibPrefix+"Time_Parse(tempString);"+cl);
                                break;
                            case "System.SByte":
                            case "System.Int16":
                            case "System.Int32":
                                cs.Append("							if ("+this.pc_methodLibPrefix+"GetLong(tempString, tempStringLength, &TempLong)==0)"+cl);
                                cs.Append("							{"+cl);
                                cs.Append("								"+V.Name+" = ("+ToCType(V.GetNetType().FullName)+") TempLong;"+cl);
                                cs.Append("							}"+cl);
                                break;
                            case "System.Byte":
                            case "System.UInt16":
                            case "System.UInt32":
                                cs.Append("							if ("+this.pc_methodLibPrefix+"GetULong(tempString, tempStringLength, &TempULong)==0)"+cl);
                                cs.Append("							{"+cl);
                                cs.Append("								"+V.Name+" = ("+ToCType(V.GetNetType().FullName)+") TempULong;"+cl);
                                cs.Append("							}"+cl);
                                break;
                            case "System.Byte[]":
                                cs.Append("							"+V.Name+"Length="+this.pc_methodLibPrefix+"Base64Decode(tempString, tempStringLength, &"+V.Name+");"+cl);
                                break;
                        }
                    }

                    //Trigger Event
                    cs.Append("							if ("+this.pc_methodPrefix+"EventCallback_"+name+"_"+V.Name+" != NULL)"+cl);
                    cs.Append("							{"+cl);
                    cs.Append("								"+this.pc_methodPrefix+"EventCallback_"+name+"_"+V.Name+"(service,"+V.Name);
                    if (V.GetNetType()==typeof(byte[]))
                    {
                        cs.Append(","+V.Name+"Length");
                    }
                    cs.Append(");"+cl);
                    cs.Append("							}"+cl);
                    if (V.GetNetType()==typeof(byte[]))
                    {
                        cs.Append("							free("+V.Name+");"+cl);
                    }
                    cs.Append("						}"+cl);
                }
            }

            cs.Append("						if (xml->Peer!=NULL)"+cl);
            cs.Append("						{"+cl);
            cs.Append("							xml = xml->Peer;"+cl);
            cs.Append("						}"+cl);
            cs.Append("						else"+cl);
            cs.Append("						{"+cl);
            cs.Append("							flg2 = -1;"+cl);
            cs.Append("							xml = xml->Parent;"+cl);
            cs.Append("						}"+cl);
            cs.Append("					}"+cl);
            cs.Append("				}"+cl);
            cs.Append("				if (xml->Peer!=NULL)"+cl);
            cs.Append("				{"+cl);
            cs.Append("					xml = xml->Peer;"+cl);
            cs.Append("				}"+cl);
            cs.Append("				else"+cl);
            cs.Append("				{"+cl);
            cs.Append("					flg = -1;"+cl);
            cs.Append("					xml = xml->Parent;"+cl);
            cs.Append("				}"+cl);
            cs.Append("			}"+cl);
            cs.Append("		}"+cl);
            cs.Append("	}"+cl);
            cs.Append("	xml = xml->Peer;"+cl);
            cs.Append("}"+cl);
            cs.Append(cl);
            cs.Append(""+this.pc_methodLibPrefix+"DestructXMLNodeList(rootXML);"+cl);
            cs.Append("}"+cl);
        }