public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg)
        {
            // init basic stuff
            CpContentDirectory CDS = this.GetCDS(arg._Device);

            _Details = new CdsResult_BrowseAll();

            // set up a queue of containers to browse, starting with root container
            Queue C = new Queue();

            _Details.Root    = new MediaContainer();
            _Details.Root.ID = "0";
            _Details.AllObjects.Add(_Details.Root);
            _Details.TotalContainers = 1;
            _Details.TotalItems      = 0;
            C.Enqueue(_Details.Root);

            // if we have containers to browse, do so
            this._TestState = UPnPTestStates.Running;
            UPnPTestStates testResult = UPnPTestStates.Ready;

            arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\"" + this.Name + "\" started.");
            while (C.Count > 0)
            {
                IMediaContainer c = (IMediaContainer)C.Dequeue();

                this._ExpectedTestingTime = _Details.ExpectedTotalBrowseRequests * 30;
                arg.ActiveTests.UpdateTimeAndProgress(_Details.TotalBrowseRequests * 30);

                //
                // get the container's metadata
                //

                IUPnPMedia             metadata;
                CdsBrowseSearchResults results = GetContainerMetadataAndValidate(c.ID, CDS, this, arg, _Details, out metadata);

                testResult = results.WorstError;

                if (testResult > UPnPTestStates.Warn)
                {
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, this.Name + " terminating because container metadata could not be obtained or the metadata was not CDS-compliant.");
                    testResult      = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return(this._TestState);
                }

                if (metadata != null)
                {
                    try
                    {
                        c.UpdateObject(metadata);
                        c.Tag = results.UpdateID;
                    }
                    catch (Exception e)
                    {
                        UpdateObjectError uoe = new UpdateObjectError();
                        uoe.UpdateThis = c;
                        uoe.Metadata   = metadata;
                        throw new TestException("Critical error updating metadata of a container using UpdateObject()", uoe, e);
                    }
                }
                else
                {
                    string reason = "\"" + this.Name + "\" terminating because container metadata could not be cast into object form.";
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason);
                    arg._TestGroup.AddResult("\"" + this.Name + "\" test failed. " + reason);
                    testResult      = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return(this._TestState);
                }

                //
                // Now get the container's children
                //
                ArrayList children = new ArrayList();
                try
                {
                    children = GetContainerChildrenAndValidate(c, CDS, this, arg, _Details, C);

                    if ((_Details.LargestContainer == null) || (children.Count > _Details.LargestContainer.ChildCount))
                    {
                        _Details.LargestContainer = c;
                    }
                }
                catch (TerminateEarly te)
                {
                    string reason = "\"" + this.Name + "\" terminating early. Reason => " + te.Message;
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason);
                    arg._TestGroup.AddResult("\"" + this.Name + "\" test failed. " + reason);
                    testResult      = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return(this._TestState);
                }
            }

            if (testResult >= UPnPTestStates.Failed)
            {
                throw new TestException("Execution should not reach this code if testResult is WARN or worse.", testResult);
            }

            if (testResult == UPnPTestStates.Ready)
            {
                throw new TestException("We should not return Ready state.", testResult);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append("\"" + this._Name + "\" test finished");

            if (testResult == UPnPTestStates.Warn)
            {
                sb.Append(" with warnings");
            }

            sb.AppendFormat(" and found {0}/{1}/{2} TotalObjects/TotalContainers/TotalItems.", _Details.AllObjects.Count, _Details.TotalContainers, _Details.TotalItems);

            arg.TestGroup.AddResult(sb.ToString());
            arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, this.Name + " completed.");

            this._TestState = testResult;

            if (this._TestState <= UPnPTestStates.Warn)
            {
                if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests)
                {
                    throw new TestException("TotalBrowseRequests=" + _Details.TotalBrowseRequests.ToString() + " ExpectedTotal=" + _Details.ExpectedTotalBrowseRequests.ToString(), _Details);
                }
            }
            return(this._TestState);
        }
        public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg)
        {
            // init basic stuff
            CpContentDirectory CDS = this.GetCDS(arg._Device);
            _Details = new CdsResult_BrowseAll();

            // set up a queue of containers to browse, starting with root container
            Queue C = new Queue();
            _Details.Root = new MediaContainer();
            _Details.Root.ID = "0";
            _Details.AllObjects.Add(_Details.Root);
            _Details.TotalContainers = 1;
            _Details.TotalItems = 0;
            C.Enqueue(_Details.Root);

            // if we have containers to browse, do so
            this._TestState = UPnPTestStates.Running;
            UPnPTestStates testResult = UPnPTestStates.Ready;
            arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\""+this.Name + "\" started.");
            while (C.Count > 0)
            {
                IMediaContainer c = (IMediaContainer) C.Dequeue();

                this._ExpectedTestingTime = _Details.ExpectedTotalBrowseRequests * 30;
                arg.ActiveTests.UpdateTimeAndProgress( _Details.TotalBrowseRequests * 30);

                //
                // get the container's metadata
                //

                IUPnPMedia metadata;
                CdsBrowseSearchResults results = GetContainerMetadataAndValidate(c.ID, CDS, this, arg, _Details, out metadata);

                testResult = results.WorstError;

                if (testResult > UPnPTestStates.Warn)
                {
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, this.Name + " terminating because container metadata could not be obtained or the metadata was not CDS-compliant.");
                    testResult = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return this._TestState;
                }

                if (metadata != null)
                {
                    try
                    {
                        c.UpdateObject(metadata);
                        c.Tag = results.UpdateID;
                    }
                    catch (Exception e)
                    {
                        UpdateObjectError uoe = new UpdateObjectError();
                        uoe.UpdateThis = c;
                        uoe.Metadata = metadata;
                        throw new TestException("Critical error updating metadata of a container using UpdateObject()", uoe, e);
                    }
                }
                else
                {
                    string reason = "\"" +this.Name + "\" terminating because container metadata could not be cast into object form.";
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason);
                    arg._TestGroup.AddResult("\""+this.Name + "\" test failed. " + reason);
                    testResult = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return this._TestState;
                }

                //
                // Now get the container's children
                //
                ArrayList children = new ArrayList();
                try
                {
                    children = GetContainerChildrenAndValidate(c, CDS, this, arg, _Details, C);

                    if ((_Details.LargestContainer == null) || (children.Count > _Details.LargestContainer.ChildCount))
                    {
                        _Details.LargestContainer = c;
                    }
                }
                catch (TerminateEarly te)
                {
                    string reason = "\"" +this.Name + "\" terminating early. Reason => " + te.Message;
                    arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason);
                    arg._TestGroup.AddResult("\""+this.Name + "\" test failed. " + reason);
                    testResult = UPnPTestStates.Failed;
                    this._TestState = testResult;
                    return this._TestState;
                }
            }

            if (testResult >= UPnPTestStates.Failed)
            {
                throw new TestException("Execution should not reach this code if testResult is WARN or worse.", testResult);
            }

            if (testResult == UPnPTestStates.Ready)
            {
                throw new TestException("We should not return Ready state.", testResult);
            }

            StringBuilder sb = new StringBuilder();
            sb.Append("\""+this._Name + "\" test finished");

            if (testResult == UPnPTestStates.Warn)
            {
                sb.Append(" with warnings");
            }

            sb.AppendFormat(" and found {0}/{1}/{2} TotalObjects/TotalContainers/TotalItems.", _Details.AllObjects.Count, _Details.TotalContainers, _Details.TotalItems);

            arg.TestGroup.AddResult(sb.ToString());
            arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, this.Name + " completed.");

            this._TestState = testResult;

            if (this._TestState <= UPnPTestStates.Warn)
            {
                if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests)
                {
                    throw new TestException("TotalBrowseRequests="+_Details.TotalBrowseRequests.ToString()+" ExpectedTotal="+_Details.ExpectedTotalBrowseRequests.ToString(), _Details);
                }
            }
            return this._TestState;
        }