void Dispose()
        {
            iSCP.OnAddedDevice   -= new UPnPInternalSmartControlPoint.DeviceHandler(HandleAddedDevice);
            iSCP.OnDeviceExpired -= new UPnPInternalSmartControlPoint.DeviceHandler(HandleExpiredDevice);
            iSCP.OnRemovedDevice -= new UPnPInternalSmartControlPoint.DeviceHandler(HandleRemovedDevice);
            iSCP.OnUpdatedDevice -= new UPnPInternalSmartControlPoint.DeviceHandler(HandleUpdatedDevice);

            iSCP = null;
        }
        /// <summary>
        /// Keep track of all UPnP devices on the network. The user can expect the OnAddedDeviceSink or OnAddedServiceSink
        /// delegate to immidiatly be called for each device that is already known.
        /// <para>
        /// if multiple filters are supplied, the results will be that of the parent device which satisfies all the search criteria.
        /// </para>
        /// </summary>
        /// <param name="OnAddedDeviceSink"></param>
        /// <param name="OnAddedServiceSink"></param>
        /// <param name="Filters">Array of strings, which represent the search criteria</param>
        public UPnPSmartControlPoint(DeviceHandler OnAddedDeviceSink, ServiceHandler OnAddedServiceSink, string[] Filters)
        {
            //MultiFilter = true;
            PartialMatchFilters = new String[Filters.Length];
            MinimumVersion      = new double[Filters.Length];
            for (int i = 0; i < PartialMatchFilters.Length; ++i)
            {
                if (Filters[i].Length > 15 && Filters[i].Length > UPnPStringFormatter.GetURNPrefix(Filters[i]).Length)
                {
                    PartialMatchFilters[i] = UPnPStringFormatter.GetURNPrefix(Filters[i]);
                    try
                    {
                        MinimumVersion[i] = double.Parse(Filters[i].Substring(PartialMatchFilters[i].Length), new CultureInfo("en-US").NumberFormat);
                    }
                    catch
                    {
                        MinimumVersion[i] = 1.0;
                    }
                }
                else
                {
                    PartialMatchFilters[i] = Filters[i];
                    MinimumVersion[i]      = 1.0;
                }
            }

            if (OnAddedDeviceSink != null)
            {
                this.OnAddedDevice += OnAddedDeviceSink;
            }
            if (OnAddedServiceSink != null)
            {
                this.OnAddedService += OnAddedServiceSink;
            }

            iSCP = new UPnPInternalSmartControlPoint(1 == Filters.Length ? Filters[0] : "upnp:rootdevice");

            iSCP.OnAddedDevice   += new UPnPInternalSmartControlPoint.DeviceHandler(HandleAddedDevice);
            iSCP.OnDeviceExpired += new UPnPInternalSmartControlPoint.DeviceHandler(HandleExpiredDevice);
            iSCP.OnRemovedDevice += new UPnPInternalSmartControlPoint.DeviceHandler(HandleRemovedDevice);
            iSCP.OnUpdatedDevice += new UPnPInternalSmartControlPoint.DeviceHandler(HandleUpdatedDevice);

            IEnumerator cdEN = iSCP.GetCurrentDevices().GetEnumerator();

            if ((OnAddedDeviceSink != null || OnAddedServiceSink != null) && cdEN != null)
            {
                while (cdEN.MoveNext())
                {
                    HandleAddedDevice(null, (UPnPDevice)cdEN.Current);
                }
            }
        }
 /// <summary>
 /// Forward the HandleExpiredDevice event to the user as an OnRemovedDevice event.
 /// </summary>
 /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
 /// <param name="device">The UPnPDevice object that was removed from the network</param>
 private void HandleExpiredDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
 {
     HandleRemovedDevice(sender, device);
 }
        /// <summary>
        /// Forward the OnRemovedDevice event to the user.
        /// </summary>
        /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
        /// <param name="device">The UPnPDevice object that was removed from the network</param>
        private void HandleRemovedDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
        {
            if ((OnRemovedDevice != null) || (OnRemovedService != null))
            {
                object[] r;
                ArrayList dList = new ArrayList();
                ArrayList sList = new ArrayList();
                Hashtable h = new Hashtable();

                bool MatchAll = true;
                for (int filterIndex = 0; filterIndex < PartialMatchFilters.Length; ++filterIndex)
                {
                    string filter = PartialMatchFilters[filterIndex];
                    double Version = MinimumVersion[filterIndex];

                    if (CheckDeviceAgainstFilter(filter, Version, device, out r) == false)
                    {
                        MatchAll = false;
                        break;
                    }
                    else
                    {
                        foreach (object x in r)
                        {
                            if (x.GetType().FullName == "OpenSource.UPnP.UPnPDevice")
                            {
                                dList.Add((UPnPDevice)x);
                                if (PartialMatchFilters.Length == 1)
                                {
                                    if (OnRemovedDevice != null)
                                    {
                                        OnRemovedDevice(this, (UPnPDevice)x);
                                    }
                                }
                            }
                            else
                            {
                                sList.Add((UPnPService)x);
                                if (PartialMatchFilters.Length == 1)
                                {
                                    if (OnRemovedDevice != null)
                                    {
                                        OnRemovedDevice(this, (UPnPDevice)x);
                                    }
                                }
                            }
                        }
                    }
                }
                if (MatchAll == true)
                {
                    if (PartialMatchFilters.Length == 1)
                    {
                        if (OnRemovedService != null)
                        {
                            foreach (UPnPService S in sList)
                            {
                                OnRemovedService(this, S);
                            }
                        }
                        return;
                    }
                    else
                    {
                        foreach (UPnPDevice dev in dList)
                        {
                            bool _OK_ = true;
                            foreach (string filter in PartialMatchFilters)
                            {
                                if (dev.GetDevices(filter).Length == 0)
                                {
                                    if (dev.GetServices(filter).Length == 0)
                                    {
                                        _OK_ = false;
                                        break;
                                    }
                                }
                            }
                            if (_OK_ == true)
                            {
                                h[dev] = dev;
                            }
                        }
                        foreach (UPnPService serv in sList)
                        {
                            bool _OK_ = true;
                            foreach (string filter in PartialMatchFilters)
                            {
                                if (serv.ParentDevice.GetServices(filter).Length == 0)
                                {
                                    _OK_ = false;
                                    break;
                                }
                            }
                            if (_OK_ == true)
                            {
                                if (h.ContainsKey(serv.ParentDevice) == false)
                                {
                                    h[serv.ParentDevice] = serv.ParentDevice;
                                }
                            }
                        }
                    }
                }

                IDictionaryEnumerator ide = h.GetEnumerator();
                while (ide.MoveNext())
                {
                    if (OnRemovedDevice != null)
                    {
                        OnRemovedDevice(this, (UPnPDevice)ide.Value);
                    }
                }
            }
        }
        /// <summary>
        /// Forward the OnUpdatedDevice event to the user.
        /// </summary>
        /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
        /// <param name="device">The UPnPDevice object that was updated</param>
        private void HandleUpdatedDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
        {

        }
 /// <summary>
 /// Forward the HandleExpiredDevice event to the user as an OnRemovedDevice event.
 /// </summary>
 /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
 /// <param name="device">The UPnPDevice object that was removed from the network</param>
 private void HandleExpiredDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
 {
     HandleRemovedDevice(sender, device);
 }
        /// <summary>
        /// Forward the OnRemovedDevice event to the user.
        /// </summary>
        /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
        /// <param name="device">The UPnPDevice object that was removed from the network</param>
        private void HandleRemovedDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
        {
            if ((OnRemovedDevice != null) || (OnRemovedService != null))
            {
                object[]  r;
                ArrayList dList = new ArrayList();
                ArrayList sList = new ArrayList();
                Hashtable h     = new Hashtable();

                bool MatchAll = true;
                for (int filterIndex = 0; filterIndex < PartialMatchFilters.Length; ++filterIndex)
                {
                    string filter  = PartialMatchFilters[filterIndex];
                    double Version = MinimumVersion[filterIndex];

                    if (CheckDeviceAgainstFilter(filter, Version, device, out r) == false)
                    {
                        MatchAll = false;
                        break;
                    }
                    else
                    {
                        foreach (object x in r)
                        {
                            if (x.GetType().FullName == "OpenSource.UPnP.UPnPDevice")
                            {
                                dList.Add((UPnPDevice)x);
                                if (PartialMatchFilters.Length == 1)
                                {
                                    if (OnRemovedDevice != null)
                                    {
                                        OnRemovedDevice(this, (UPnPDevice)x);
                                    }
                                }
                            }
                            else
                            {
                                sList.Add((UPnPService)x);
                                if (PartialMatchFilters.Length == 1)
                                {
                                    if (OnRemovedDevice != null)
                                    {
                                        OnRemovedDevice(this, (UPnPDevice)x);
                                    }
                                }
                            }
                        }
                    }
                }
                if (MatchAll == true)
                {
                    if (PartialMatchFilters.Length == 1)
                    {
                        if (OnRemovedService != null)
                        {
                            foreach (UPnPService S in sList)
                            {
                                OnRemovedService(this, S);
                            }
                        }
                        return;
                    }
                    else
                    {
                        foreach (UPnPDevice dev in dList)
                        {
                            bool _OK_ = true;
                            foreach (string filter in PartialMatchFilters)
                            {
                                if (dev.GetDevices(filter).Length == 0)
                                {
                                    if (dev.GetServices(filter).Length == 0)
                                    {
                                        _OK_ = false;
                                        break;
                                    }
                                }
                            }
                            if (_OK_ == true)
                            {
                                h[dev] = dev;
                            }
                        }
                        foreach (UPnPService serv in sList)
                        {
                            bool _OK_ = true;
                            foreach (string filter in PartialMatchFilters)
                            {
                                if (serv.ParentDevice.GetServices(filter).Length == 0)
                                {
                                    _OK_ = false;
                                    break;
                                }
                            }
                            if (_OK_ == true)
                            {
                                if (h.ContainsKey(serv.ParentDevice) == false)
                                {
                                    h[serv.ParentDevice] = serv.ParentDevice;
                                }
                            }
                        }
                    }
                }

                IDictionaryEnumerator ide = h.GetEnumerator();
                while (ide.MoveNext())
                {
                    if (OnRemovedDevice != null)
                    {
                        OnRemovedDevice(this, (UPnPDevice)ide.Value);
                    }
                }
            }
        }
 /// <summary>
 /// Forward the OnUpdatedDevice event to the user.
 /// </summary>
 /// <param name="sender">UPnPInternalSmartControlPoint that sent the event</param>
 /// <param name="device">The UPnPDevice object that was updated</param>
 private void HandleUpdatedDevice(UPnPInternalSmartControlPoint sender, UPnPDevice device)
 {
 }