/// <summary>
 /// Method executes when a "good" server has done bye bye.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="server"></param>
 private void Sink_OnGoodServerRemoved(_MediaServerDiscovery sender, CpMediaServer server)
 {
     if (this.OnGoodServerRemoved != null)
     {
         this.OnGoodServerRemoved(this, server);
     }
 }
 /// <summary>
 /// Method executes when a server says BEY BYE.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="device"></param>
 private void Sink_OnServerRemoved(_MediaServerDiscovery sender, UPnPDevice device)
 {
     if (this.OnServerGone != null)
     {
         this.OnServerGone(this, device);
     }
 }
 /// <summary>
 /// Method executes when a server is discovered.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="device"></param>
 private void Sink_OnServerAdded(_MediaServerDiscovery sender, UPnPDevice device)
 {
     if (this.OnServerSeen != null)
     {
         this.OnServerSeen(this, device);
     }
 }
        /// <summary>
        /// Constructs a MediaServerDiscovery object.
        /// </summary>
        /// <param name="onServerAddedCallback">null, if not interested in the OnServerSeen event; otherwise adds the callback to the multicasted event</param>
        /// <param name="onServerRemovedCallback">null, if not interested in the OnServerGone event; otherwise adds the callback to the multicasted event</param>
        /// <param name="onGoodServerAddedCallback">null, if not interested in the OnGoodServerAdded event; strongly recommended that this is not null; otherwise adds the callback to the multicasted event</param>
        /// <param name="onGoodServerRemovedCallback">null, if not interested in the OnGoodServerRemoved event; otherwise adds the callback to the multicasted event</param>
        public MediaServerDiscovery(
			Delegate_OnServerDeviceChange onServerAddedCallback,
			Delegate_OnServerDeviceChange onServerRemovedCallback,
			Delegate_OnGoodServersChange onGoodServerAddedCallback,
			Delegate_OnGoodServersChange onGoodServerRemovedCallback
			)
        {
            if (onServerAddedCallback != null)
            {
                this.OnServerSeen += onServerAddedCallback;
            }

            if (onServerRemovedCallback != null)
            {
                this.OnServerGone += onServerRemovedCallback;
            }

            if (onGoodServerAddedCallback != null)
            {
                this.OnGoodServerAdded += onGoodServerAddedCallback;
            }

            if (onGoodServerRemovedCallback != null)
            {
                this.OnGoodServerRemoved += onGoodServerRemovedCallback;
            }

            CpMediaServer[] servers = null;
            CpMediaServer[] goodServers = null;

            TheLock.WaitOne();
            if (TheInstance != null)
            {
                servers = TheInstance.GoodServers;
                goodServers = TheInstance.GoodServers;
            }
            else
            {
                TheInstance = new _MediaServerDiscovery(true);
            }
            TheLock.ReleaseMutex();

            TheInstance.OnCpServerAdded += new _MediaServerDiscovery.Delegate_OnGoodServersChange(this.Sink_OnGoodServerAdded);
            TheInstance.OnCpServerRemoved += new _MediaServerDiscovery.Delegate_OnGoodServersChange(this.Sink_OnGoodServerRemoved);
            TheInstance.OnServerSeen += new _MediaServerDiscovery.Delegate_OnServerDeviceChange(this.Sink_OnServerAdded);
            TheInstance.OnServerGone += new _MediaServerDiscovery.Delegate_OnServerDeviceChange(this.Sink_OnServerRemoved);

            if (servers != null)
            {
                if (this.OnServerSeen != null)
                {
                    foreach (CpMediaServer server in servers)
                    {
                        if (servers.Length > 0)
                        {
                            this.OnServerSeen(this, server.ConnectionManager.GetUPnPService().ParentDevice);
                        }
                    }
                }
            }

            if (goodServers != null)
            {
                if (this.OnGoodServerAdded != null)
                {
                    foreach (CpMediaServer server in goodServers)
                    {
                        if (servers.Length > 0)
                        {
                            this.OnGoodServerAdded(this, server);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Method executes when a server says BEY BYE.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="device"></param>
 private void Sink_OnServerRemoved(_MediaServerDiscovery sender, UPnPDevice device)
 {
     if(this.OnServerGone != null)
     {
         this.OnServerGone(this, device);
     }
 }
 /// <summary>
 /// Method executes when a server is discovered.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="device"></param>
 private void Sink_OnServerAdded(_MediaServerDiscovery sender, UPnPDevice device)
 {
     if(this.OnServerSeen != null)
     {
         this.OnServerSeen(this, device);
     }
 }
 /// <summary>
 /// Method executes when a "good" server has done bye bye.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="server"></param>
 private void Sink_OnGoodServerRemoved(_MediaServerDiscovery sender, CpMediaServer server)
 {
     if(this.OnGoodServerRemoved != null)
     {
         this.OnGoodServerRemoved(this, server);
     }
 }
        /// <summary>
        /// Constructs a MediaServerDiscovery object.
        /// </summary>
        /// <param name="onServerAddedCallback">null, if not interested in the OnServerSeen event; otherwise adds the callback to the multicasted event</param>
        /// <param name="onServerRemovedCallback">null, if not interested in the OnServerGone event; otherwise adds the callback to the multicasted event</param>
        /// <param name="onGoodServerAddedCallback">null, if not interested in the OnGoodServerAdded event; strongly recommended that this is not null; otherwise adds the callback to the multicasted event</param>
        /// <param name="onGoodServerRemovedCallback">null, if not interested in the OnGoodServerRemoved event; otherwise adds the callback to the multicasted event</param>
        public MediaServerDiscovery
        (
            Delegate_OnServerDeviceChange onServerAddedCallback,
            Delegate_OnServerDeviceChange onServerRemovedCallback,
            Delegate_OnGoodServersChange onGoodServerAddedCallback,
            Delegate_OnGoodServersChange onGoodServerRemovedCallback
        )
        {
            if (onServerAddedCallback != null)
            {
                this.OnServerSeen += onServerAddedCallback;
            }

            if (onServerRemovedCallback != null)
            {
                this.OnServerGone += onServerRemovedCallback;
            }

            if (onGoodServerAddedCallback != null)
            {
                this.OnGoodServerAdded += onGoodServerAddedCallback;
            }

            if (onGoodServerRemovedCallback != null)
            {
                this.OnGoodServerRemoved += onGoodServerRemovedCallback;
            }

            CpMediaServer[] servers     = null;
            CpMediaServer[] goodServers = null;

            TheLock.WaitOne();
            if (TheInstance != null)
            {
                servers     = TheInstance.GoodServers;
                goodServers = TheInstance.GoodServers;
            }
            else
            {
                TheInstance = new _MediaServerDiscovery(true);
            }
            TheLock.ReleaseMutex();

            TheInstance.OnCpServerAdded   += new _MediaServerDiscovery.Delegate_OnGoodServersChange(this.Sink_OnGoodServerAdded);
            TheInstance.OnCpServerRemoved += new _MediaServerDiscovery.Delegate_OnGoodServersChange(this.Sink_OnGoodServerRemoved);
            TheInstance.OnServerSeen      += new _MediaServerDiscovery.Delegate_OnServerDeviceChange(this.Sink_OnServerAdded);
            TheInstance.OnServerGone      += new _MediaServerDiscovery.Delegate_OnServerDeviceChange(this.Sink_OnServerRemoved);

            if (servers != null)
            {
                if (this.OnServerSeen != null)
                {
                    foreach (CpMediaServer server in servers)
                    {
                        if (servers.Length > 0)
                        {
                            this.OnServerSeen(this, server.ConnectionManager.GetUPnPService().ParentDevice);
                        }
                    }
                }
            }


            if (goodServers != null)
            {
                if (this.OnGoodServerAdded != null)
                {
                    foreach (CpMediaServer server in goodServers)
                    {
                        if (servers.Length > 0)
                        {
                            this.OnGoodServerAdded(this, server);
                        }
                    }
                }
            }
        }