/// <summary>
        /// Derived classes call this method to add subtests associated
        /// with this test group. The implementation will add the
        /// <see cref="ISubTest"/> objects to the <see cref="AdvancedTestGroup.AllTests"/>
        /// field.
        /// </summary>
        /// <param name="subTest"></param>
        protected void AddSubTest(ISubTest subTest)
        {
            foreach (ISubTest sub in AllTests.Values)
            {
                bool found = false;
                if (sub.Name == subTest.Name)
                {
                    found = true;
                }

                if (found)
                {
                    throw new ApplicationException("Cannot have two subtests with the same name.");
                }
            }

            AllTests.Add(subTest, subTest);

            this.AddTest(subTest.Name, subTest.Description);
        }
        private void AddTest(ISubTest sub)
        {
            bool found = false;

            foreach (ISubTest st in Q.Values)
            {
                if (st.Name == sub.Name)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                foreach (ISubTest pre in sub.Prerequisites)
                {
                    AddTest(pre);
                }

                Q.Add(sub, sub);
            }
        }
        /// <summary>
        /// Derived classes call this method to add subtests associated
        /// with this test group. The implementation will add the
        /// <see cref="ISubTest"/> objects to the <see cref="AdvancedTestGroup.AllTests"/>
        /// field.
        /// </summary>
        /// <param name="subTest"></param>
        protected void AddSubTest(ISubTest subTest)
        {
            foreach (ISubTest sub in AllTests.Values)
            {
                bool found = false;
                if (sub.Name == subTest.Name)
                {
                    found = true;
                }

                if (found)
                {
                    throw new ApplicationException("Cannot have two subtests with the same name.");
                }
            }

            AllTests.Add(subTest, subTest);

            this.AddTest(subTest.Name, subTest.Description);
        }
        private void AddTest(ISubTest sub)
        {
            bool found = false;
            foreach (ISubTest st in Q.Values)
            {
                if (st.Name == sub.Name)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                foreach (ISubTest pre in sub.Prerequisites)
                {
                    AddTest(pre);
                }

                Q.Add(sub, sub);
            }
        }
        public void RunQueue()
        {
            Arg.TestGroup.state = UPnPTestStates.Running;

            UPnPService[]        services = Arg.Device.Services;
            UPnPServiceWatcher[] watchers = new UPnPServiceWatcher[services.Length];
            for (int i = 0; i < services.Length; i++)
            {
                //watchers[i] = new UPnPServiceWatcher(services[i], null, new UPnPServiceWatcher.SniffPacketHandler(this.SniffPacketSink));
            }

            foreach (ISubTest sub in Q.Values)
            {
                Arg.TestGroup.SetState(sub.Name, UPnPTestStates.Running);

                bool cont = true;
                foreach (SubTest pre1 in sub.Prerequisites)
                {
                    pre1.CalculateExpectedTestingTime(Q.Values, Arg);

                    ISubTest pre = null;
                    foreach (ISubTest pre2 in Q.Values)
                    {
                        if (pre2.Name == pre1.Name)
                        {
                            pre = pre2;
                        }
                    }

                    if (
                        (!
                         (pre.TestState == UPnPTestStates.Pass) ||
                         (pre.TestState == UPnPTestStates.Warn)
                        )
                        )
                    {
                        cont = false;
                    }
                }

                this.UpdateTimeAndProgress(0);
                if (cont)
                {
                    UPnPTestStates result = sub.Run(Q.Values, Arg);
                    Arg.TestGroup.SetState(sub.Name, result);

                    if (sub.TestState != result)
                    {
                        throw new ApplicationException("Test state does not match the set value.");
                    }
                }
                this.UpdateTimeAndProgress(0);
            }

            UPnPTestStates MasterResult = UPnPTestStates.Pass;

            foreach (ISubTest done in Q.Values)
            {
                if (done.TestState > MasterResult)
                {
                    MasterResult = done.TestState;
                    break;
                }
            }

            for (int i = 0; i < services.Length; i++)
            {
                //watchers[i].OnSniffPacket -= new UPnPServiceWatcher.SniffPacketHandler(this.SniffPacketSink);
            }


            Arg.TestGroup.state = MasterResult;
        }