public UPnPRelayDevice(UPnPDevice device, CpGateKeeper _CP)
        {
            OpenSource.Utilities.InstanceTracker.Add(this);
            ILCB = new InvokeResponseHandler(InvokeResponseSink);
            CP = _CP;
            ProxyDevice = UPnPDevice.CreateRootDevice(750, double.Parse(device.Version), "");
            ProxyDevice.UniqueDeviceName = Guid.NewGuid().ToString();

            ProxyDevice.HasPresentation = false;
            ProxyDevice.FriendlyName = "*" + device.FriendlyName;
            ProxyDevice.Manufacturer = device.Manufacturer;
            ProxyDevice.ManufacturerURL = device.ManufacturerURL;
            ProxyDevice.ModelName = device.ModelName;
            ProxyDevice.DeviceURN = device.DeviceURN;

            foreach (UPnPService S in device.Services)
            {
                UPnPService S2 = (UPnPService)S.Clone();
                foreach (UPnPAction A in S2.Actions)
                {
                    A.ParentService = S2;
                    A.SpecialCase += new UPnPAction.SpecialInvokeCase(InvokeSink);
                }

                UPnPDebugObject dbg = new UPnPDebugObject(S2);

                dbg.SetField("SCPDURL", "_" + S2.ServiceID + "_scpd.xml");
                dbg.SetProperty("ControlURL", "_" + S2.ServiceID + "_control");
                dbg.SetProperty("EventURL", "_" + S2.ServiceID + "_event");
                ProxyDevice.AddService(S2);
            }

            UDNTable[device.UniqueDeviceName] = ProxyDevice;
            ReverseUDNTable[ProxyDevice.UniqueDeviceName] = device.UniqueDeviceName;
            foreach (UPnPDevice _ed in device.EmbeddedDevices)
            {
                ProcessDevice(_ed);
            }
        }
        private void Fix(UPnPDevice device, int number, Hashtable serviceNameTable)
        {
            device.User3 = new object[9]{
                                            device.SerialNumber,
                                            device.FriendlyName,
                                            device.Manufacturer,
                                            device.ManufacturerURL,
                                            device.ModelDescription,
                                            device.ModelName,
                                            device.ModelNumber,
                                            device.ModelURL,
                                            device.ProductCode};
            if (device.FriendlyName != "%s")
            {
                FriendlyNameTable[device] = device.FriendlyName;
            }
            if (device.Root)
            {
                device.UniqueDeviceName = "%s";
            }
            else
            {
                device.UniqueDeviceName = "%s_" + number.ToString();
            }
            device.SerialNumber = "%s";
            device.FriendlyName = "%s";
            if (Configuration.DynamicObjectModel)
            {
                device.Manufacturer = "%s";
                device.ManufacturerURL = "%s";
                device.ModelDescription = "%s";
                device.ModelName = "%s";
                device.ModelNumber = "%s";
                device.ModelURL = new Uri("http://255.255.255.255:255/");
                device.ProductCode = "%s";
            }
            foreach (UPnPService service in device.Services)
            {
                UPnPDebugObject obj = new UPnPDebugObject(service);
                obj.SetField("SCPDURL", (string)serviceNameTable[service] + "/scpd.xml");
                obj.SetField("__controlurl", (string)serviceNameTable[service] + "/control");
                bool eventOK = false;
                foreach (UPnPStateVariable sv in service.GetStateVariables())
                {
                    if (sv.SendEvent)
                    {
                        eventOK = true;
                        break;
                    }
                }
                if (eventOK)
                {
                    obj.SetField("__eventurl", (string)serviceNameTable[service] + "/event");
                }
                else
                {
                    obj.SetField("__eventurl", "");
                }
            }

            foreach (UPnPDevice d in device.EmbeddedDevices)
            {
                Fix(d, ++number, serviceNameTable);
            }
        }
        private void Fix(UPnPDevice device, int number, Hashtable serviceNameTable)
        {
            if (device.Root)
            {
                device.UniqueDeviceName = "%s";
            }
            else
            {
                device.UniqueDeviceName = "%s_" + number.ToString();
            }
            device.SerialNumber = "%s";
            foreach(UPnPService service in device.Services)
            {
                UPnPDebugObject obj = new UPnPDebugObject(service);
                obj.SetField("SCPDURL",(string)serviceNameTable[service] + "/scpd.xml");
                obj.SetField("__controlurl",(string)serviceNameTable[service] + "/control");
                obj.SetField("__eventurl",(string)serviceNameTable[service] + "/event");
            }

            foreach(UPnPDevice d in device.EmbeddedDevices)
            {
                Fix(d, ++number, serviceNameTable);
            }
        }
        private void ProcessDevice(UPnPDevice device)
        {
            UPnPDevice d = UPnPDevice.CreateEmbeddedDevice(double.Parse(device.Version), Guid.NewGuid().ToString());
            d.FriendlyName = "*" + device.FriendlyName;
            d.Manufacturer = device.Manufacturer;
            d.ManufacturerURL = device.ManufacturerURL;
            d.ModelDescription = device.ModelDescription;
            d.ModelURL = device.ModelURL;
            d.DeviceURN = device.DeviceURN;
            UDNTable[device.UniqueDeviceName] = d;
            ReverseUDNTable[d.UniqueDeviceName] = device.UniqueDeviceName;

            foreach (UPnPService S in device.Services)
            {
                UPnPService S2 = (UPnPService)S.Clone();
                foreach (UPnPAction A in S2.Actions)
                {
                    A.ParentService = S2;
                    A.SpecialCase += new UPnPAction.SpecialInvokeCase(InvokeSink);
                }

                UPnPDebugObject dbg = new UPnPDebugObject(S2);

                dbg.SetField("SCPDURL", "_" + S2.ServiceID + "_scpd.xml");
                dbg.SetProperty("ControlURL", "_" + S2.ServiceID + "_control");
                dbg.SetProperty("EventURL", "_" + S2.ServiceID + "_event");
                d.AddService(S2);
            }
            ((UPnPDevice)UDNTable[device.ParentDevice.UniqueDeviceName]).AddDevice(d);

            foreach (UPnPDevice _ed in device.EmbeddedDevices)
            {
                ProcessDevice(_ed);
            }
        }