public RenderingControlLastChange(CpRenderingControl cpRC, string Ident, int ID, RenderingControlLastChange.OnReadyHandler ReadyCallback)
        {
            OpenSource.Utilities.InstanceTracker.Add(this);
            this.OnReady += ReadyCallback;
            InstanceID    = ID;
            Identifier    = Ident;
            _cp           = cpRC;
            _cp.OnStateVariable_LastChange += new CpRenderingControl.StateVariableModifiedHandler_LastChange(LastChangeSink);
            _cp._subscribe(500);

            lock (this)
            {
                if (_cp.HasAction_GetVolume)
                {
                    CpRenderingControl.Delegate_OnResult_GetVolume TD = new CpRenderingControl.Delegate_OnResult_GetVolume(VolumeSink);

                    StateCounter += _cp.Values_A_ARG_TYPE_Channel.Length;

                    foreach (string voltype in _cp.Values_A_ARG_TYPE_Channel)
                    {
                        _cp.SetUnspecifiedValue("Enum_A_ARG_TYPE_Channel", voltype);
                        _cp.GetVolume((UInt32)ID, CpRenderingControl.Enum_A_ARG_TYPE_Channel._UNSPECIFIED_, null, TD);
                    }
                }
                if (_cp.HasAction_GetMute)
                {
                    CpRenderingControl.Delegate_OnResult_GetMute RGM = new CpRenderingControl.Delegate_OnResult_GetMute(MuteSink);
                    StateCounter += _cp.Values_A_ARG_TYPE_Channel.Length;

                    foreach (string voltype in _cp.Values_A_ARG_TYPE_Channel)
                    {
                        _cp.SetUnspecifiedValue("Enum_A_ARG_TYPE_Channel", voltype);
                        _cp.GetMute((UInt32)ID, CpRenderingControl.Enum_A_ARG_TYPE_Channel._UNSPECIFIED_, null, RGM);
                    }
                }

                if (StateCounter == 0)
                {
                    if (OnReady != null)
                    {
                        OnReady(this);
                    }
                }
            }
        }
 private void MuteSink(CpRenderingControl sender, System.UInt32 InstanceID, CpRenderingControl.Enum_A_ARG_TYPE_Channel Channel, System.Boolean CurrentMute, UPnPInvokeException e, object _Tag)
 {
     if (e == null)
     {
         MuteByChannel[_cp.Enum_A_ARG_TYPE_Channel_ToString(Channel)] = CurrentMute;
     }
     lock (this)
     {
         --StateCounter;
         if (StateCounter == 0)
         {
             if (OnReady != null)
             {
                 OnReady(this);
             }
         }
     }
 }
 private void VolumeSink(CpRenderingControl sender, UInt32 id, CpRenderingControl.Enum_A_ARG_TYPE_Channel Channel, UInt16 VolumeLevel, UPnPInvokeException e, object Handle)
 {
     if (e == null)
     {
         VolumeByChannel[_cp.Enum_A_ARG_TYPE_Channel_ToString(Channel)] = VolumeLevel;
     }
     lock (this)
     {
         --StateCounter;
         if (StateCounter == 0)
         {
             if (OnReady != null)
             {
                 OnReady(this);
             }
         }
     }
 }
        protected void LastChangeSink(CpRenderingControl sender, string LC)
        {
            if (LC == "")
            {
                return;
            }
            if (LC.Substring(0, 1) != "<")
            {
                LC = UPnPStringFormatter.UnEscapeString(LC);
            }
            if (LC.Substring(0, 1) != "<")
            {
                LC = UPnPStringFormatter.UnEscapeString(LC);
            }


            /*
             * if(LC.StartsWith("<?")==true)
             * {
             *      int dx = LC.IndexOf(">");
             *      LC = LC.Substring(0,dx+1) + "<MYROOT>" + LC.Substring(dx+1) + "</MYROOT>";
             * }
             * else
             * {
             *      LC = "<MYROOT>" + LC + "</MYROOT>";
             * }*/

            StringReader  MyString = new StringReader(LC);
            XmlTextReader XMLDoc   = new XmlTextReader(MyString);

            Hashtable T = new Hashtable();

            int    ID        = -1;
            string VarName   = "";
            string VarValue  = "";
            string AttrName  = "";
            string AttrValue = "";

            XMLDoc.Read();
            XMLDoc.MoveToContent();

            XMLDoc.Read();
            XMLDoc.MoveToContent();

            while ((XMLDoc.LocalName != "Event") && (XMLDoc.EOF == false))
            {
                // At Start, should be InstanceID
                if (XMLDoc.LocalName == "InstanceID")
                {
                    XMLDoc.MoveToAttribute("val");
                    ID = int.Parse(XMLDoc.GetAttribute("val"));
                    if (T.ContainsKey(ID) == false)
                    {
                        T[ID] = new Hashtable();
                    }
                    XMLDoc.MoveToContent();

                    XMLDoc.Read();
                    XMLDoc.MoveToContent();

                    while (XMLDoc.LocalName != "InstanceID")
                    {
                        VarName   = XMLDoc.LocalName;
                        VarValue  = "";
                        AttrName  = "";
                        AttrValue = "";

                        for (int a_idx = 0; a_idx < XMLDoc.AttributeCount; ++a_idx)
                        {
                            XMLDoc.MoveToAttribute(a_idx);
                            if (XMLDoc.LocalName == "val")
                            {
                                VarValue = XMLDoc.GetAttribute(a_idx);
                            }
                            else
                            {
                                AttrName  = XMLDoc.LocalName;
                                AttrValue = XMLDoc.GetAttribute(a_idx);
                            }
                        }

                        XMLDoc.MoveToContent();

                        if (AttrName == "")
                        {
                            ((Hashtable)T[ID])[VarName] = VarValue;
                        }
                        else
                        {
                            if (((Hashtable)T[ID]).ContainsKey(VarName) == false)
                            {
                                ((Hashtable)T[ID])[VarName] = new Hashtable();
                            }
                            if (((Hashtable)((Hashtable)T[ID])[VarName]).ContainsKey(AttrName) == false)
                            {
                                ((Hashtable)((Hashtable)T[ID])[VarName])[AttrName] = new Hashtable();
                            }
                            ((Hashtable)((Hashtable)((Hashtable)T[ID])[VarName])[AttrName])[AttrValue] = VarValue;
                        }
                        XMLDoc.Read();
                        XMLDoc.MoveToContent();
                    }
                }
                else
                {
                    XMLDoc.Skip();
                }
                XMLDoc.Read();
                XMLDoc.MoveToContent();
            }

            XMLDoc.Close();


            IDictionaryEnumerator inEn = T.GetEnumerator();
            IDictionaryEnumerator EvEn;
            Hashtable             TT;

            while (inEn.MoveNext())
            {
                if ((int)inEn.Key == InstanceID)
                {
                    TT   = (Hashtable)inEn.Value;
                    EvEn = TT.GetEnumerator();
                    while (EvEn.MoveNext())
                    {
                        switch ((string)EvEn.Key)
                        {
                        case "Mute":
                            if (EvEn.Value.GetType().FullName == "System.String")
                            {
                                MuteByChannel["MASTER"] = (bool)UPnPService.CreateObjectInstance(typeof(bool), (string)EvEn.Value);
                            }
                            else
                            {
                                IDictionaryEnumerator E2 = ((Hashtable)EvEn.Value).GetEnumerator();
                                while (E2.MoveNext())
                                {
                                    IDictionaryEnumerator E3 = ((Hashtable)((Hashtable)E2.Value)).GetEnumerator();
                                    while (E3.MoveNext())
                                    {
                                        MuteByChannel[E3.Key.ToString()] = (bool)UPnPService.CreateObjectInstance(typeof(bool), E3.Value.ToString());
                                    }
                                }
                            }

                            if (OnMuteChanged != null)
                            {
                                OnMuteChanged(this);
                            }
                            break;

                        case "Volume":
                            if (EvEn.Value.GetType().FullName == "System.String")
                            {
                                VolumeByChannel["MASTER"] = UInt16.Parse((string)EvEn.Value);
                            }
                            else
                            {
                                IDictionaryEnumerator E2 = ((Hashtable)EvEn.Value).GetEnumerator();
                                while (E2.MoveNext())
                                {
                                    IDictionaryEnumerator E3 = ((Hashtable)((Hashtable)E2.Value)).GetEnumerator();
                                    while (E3.MoveNext())
                                    {
                                        VolumeByChannel[E3.Key.ToString()] = UInt16.Parse(E3.Value.ToString());
                                    }
                                }
                            }
                            //_Volume = UInt16.Parse((string)EvEn.Value);
                            if (OnVolumeChanged != null)
                            {
                                OnVolumeChanged(this);
                            }
                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// This construct is only called by the AVRenderer object.
        /// </summary>
        /// <param name="device"></param>
        /// <param name="AVTransportID"></param>
        /// <param name="RenderingControlID"></param>
        /// <param name="ConnectionID"></param>
        /// <param name="ReadyCallback"></param>
        /// <param name="StateObject"></param>
        internal AVConnection(UPnPDevice device, int AVTransportID, int RenderingControlID, Int32 ConnectionID, AVConnection.OnReadyHandler ReadyCallback, object StateObject)
        {
            OpenSource.Utilities.InstanceTracker.Add(this);
            this.Tag      = StateObject;
            this.OnReady += ReadyCallback;

            FriendlyName = device.FriendlyName;
            Identifier   = device.UniqueDeviceName + ":" + ConnectionID.ToString();
            AVTid        = AVTransportID;
            RCid         = RenderingControlID;
            CMid         = ConnectionID;

            AVTransport       = new CpAVTransport(device.GetServices(CpAVTransport.SERVICE_NAME)[0]);
            RenderingControl  = new CpRenderingControl(device.GetServices(CpRenderingControl.SERVICE_NAME)[0]);
            ConnectionManager = new CpConnectionManager(device.GetServices(CpConnectionManager.SERVICE_NAME)[0]);

            if (RenderingControl.HasStateVariable_Volume)
            {
                // If the renderer has defined ranges, use those
                if (RenderingControl.HasMaximum_Volume)
                {
                    MaxVolume = (UInt16)RenderingControl.Maximum_Volume;
                }
                else
                {
                    MaxVolume = UInt16.MaxValue;
                }

                if (RenderingControl.HasMinimum_Volume)
                {
                    MinVolume = (UInt16)RenderingControl.Minimum_Volume;
                }
                else
                {
                    MinVolume = UInt16.MinValue;
                }
            }

            lock (this)
            {
                if (AVTransport.HasStateVariable_LastChange)
                {
                    // Hook up to the LastChange event of AVTransport
                    ++this.StateCounter;
                    AV_LastChange = new AVTransportLastChange(AVTransport, device.UniqueDeviceName, AVTid, new AVTransportLastChange.ReadyHandler(AVTLC));
                    AV_LastChange.OnCurrentPositionChanged    += new AVTransportLastChange.VariableChangeHandler(PositionSink);
                    AV_LastChange.OnPlayStateChanged          += new AVTransportLastChange.VariableChangeHandler(PlayStateSink);
                    AV_LastChange.OnAVTransportURIChanged     += new AVTransportLastChange.VariableChangeHandler(AVTransportURISink);
                    AV_LastChange.OnCurrentTrackChanged       += new AVTransportLastChange.VariableChangeHandler(TrackChangedSink);
                    AV_LastChange.OnNumberOfTracksChanged     += new AVTransportLastChange.VariableChangeHandler(NumberOfTracksChangedSink);
                    AV_LastChange.OnTrackURIChanged           += new AVTransportLastChange.VariableChangeHandler(TrackURIChangedSink);
                    AV_LastChange.OnCurrentURIMetaDataChanged += new AVTransportLastChange.VariableChangeHandler(URIMetaDataChangedSink);
                    AV_LastChange.OnCurrentPlayModeChanged    += new AVTransportLastChange.VariableChangeHandler(CurrentPlayModeChangedSink);
                    AV_LastChange.OnTransportStatusChanged    += new AVTransportLastChange.VariableChangeHandler(TransportStatusChangedSink);
                }

                if (RenderingControl.HasStateVariable_LastChange)
                {
                    // Hook up to the LastChange event of RenderingControl
                    ++this.StateCounter;
                    RC_LastChange = new RenderingControlLastChange(RenderingControl, device.UniqueDeviceName, RCid, new RenderingControlLastChange.OnReadyHandler(RCLC));
                    RC_LastChange.OnMuteChanged   += new RenderingControlLastChange.VariableChangeHandler(MuteSink);
                    RC_LastChange.OnVolumeChanged += new RenderingControlLastChange.VariableChangeHandler(VolumeSink);
                }

                /* Get ProtocolInfo Value of current connection */
                ++this.StateCounter;
                ConnectionManager.GetCurrentConnectionInfo(ConnectionID, this.GetHashCode(), new CpConnectionManager.Delegate_OnResult_GetCurrentConnectionInfo(InitialState_GetCurrentConnectionInfoSink));
            }
            RenderingControl._subscribe(500);
            AVTransport._subscribe(500);
        }