private bool Test_AVTransport_LastChange()
        {
            bool RetVal = true;

            AVT.OnStateVariable_LastChange += new CpAVTransport.StateVariableModifiedHandler_LastChange(AVT_LastChangeSink);
            Ev.Reset();

            AVT._subscribe(150);
            Ev.WaitOne(30000, false);

            string LC = AVT.LastChange;

            if (LC.Substring(0, 1) != "<")
            {
                LC = UPnPStringFormatter.UnEscapeString(LC);
            }

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

            try
            {
                XMLDoc.Read();
                XMLDoc.MoveToContent();

                if (XMLDoc.NamespaceURI != "urn:schemas-upnp-org:metadata-1-0/AVT/")
                {
                    //Invalid Namespace
                    RetVal = false;
                    AddEvent(LogImportance.Critical, "Event Formatting", "LastChange event was not in the proper namespace");
                }
                else
                {
                    // OK
                    AddEvent(LogImportance.Remark, "Event Formatting", "LastChange event appears OK");
                }
            }
            catch (System.Xml.XmlException)
            {
                // Not a well-formed XML
                RetVal = false;
                AddEvent(LogImportance.Critical, "Event Formatting", "LastChange event was not a well formed XML");
            }

            AVT.GetUPnPService().UnSubscribe(null);
            return(RetVal);
        }
        public AVTransportLastChange(CpAVTransport cpAV, string Ident, int ID, AVTransportLastChange.ReadyHandler ReadyCallback)
        {
            OpenSource.Utilities.InstanceTracker.Add(this);
            this.OnReady += ReadyCallback;
            InstanceID    = ID.ToString();
            Identifier    = Ident;
            _cp           = cpAV;
            _cp.OnStateVariable_LastChange += new CpAVTransport.StateVariableModifiedHandler_LastChange(LastChangeSink);

            _cp._subscribe(500);


            lock (this)
            {
                if (_cp.HasAction_GetPositionInfo)
                {
                    ++StateCounter;
                    //PollerTimeoutHandler = new LifeTimeMonitor.LifeTimeHandler(PollerTimeoutSink);
                    //PollerTimeout.AddWeakEvent_OnExpired(PollerTimeoutHandler);

                    _cp.GetPositionInfo((UInt32)ID, null, new CpAVTransport.Delegate_OnResult_GetPositionInfo(PositionInfoSink));
                }

                if (_cp.HasAction_GetMediaInfo)
                {
                    ++StateCounter;
                    _cp.GetMediaInfo((UInt32)ID, null, new CpAVTransport.Delegate_OnResult_GetMediaInfo(MediaInfoSink));
                }

                if (_cp.HasAction_GetTransportInfo)
                {
                    ++StateCounter;
                    _cp.GetTransportInfo((UInt32)ID, null, new CpAVTransport.Delegate_OnResult_GetTransportInfo(GetTransportInfoSink));
                }

                if (_cp.HasAction_GetTransportSettings)
                {
                    ++StateCounter;
                    _cp.GetTransportSettings((UInt32)ID, null, new CpAVTransport.Delegate_OnResult_GetTransportSettings(GetTransportSettingsSink));
                }
            }
        }
        /// <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);
        }