void ExternalAuthorizationTest(
            Func <AccessPointInfo, bool> accessPointCapabilitiesTest,
            TopicInfo accessRequestTopic,
            Action <XmlElement, TopicInfo> validateAccessRequestTopic,
            ValidateMessageFunction validateRequestMessageFunction,
            TopicInfo resultTopic,
            Action <XmlElement, TopicInfo> validateResultTopic,
            ValidateMessageFunction validateResultMessageFunction,
            Action <string, string> reactToRequest)
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                //3.	Get complete list of access points from the DUT (see Annex A.1).
                List <AccessPointInfo> fullAccessPointsList = GetAccessPointInfoList();

                //4.	Check that there is at least one Access Point with required Capabilities

                List <AccessPointInfo> accessPointsList = null;
                if (accessPointCapabilitiesTest != null)
                {
                    accessPointsList = fullAccessPointsList.Where(A => accessPointCapabilitiesTest(A)).ToList();

                    if (accessPointsList.Count == 0)
                    {
                        LogTestEvent("No AccessPoints with required Capabilities found, exit the test." + Environment.NewLine);
                        return;
                    }
                }
                else
                {
                    accessPointsList = fullAccessPointsList;
                }

                // Get topic description from the DUT and check topics support

                ValidateTopicsSupport(accessRequestTopic, validateAccessRequestTopic,
                                      resultTopic, validateResultTopic);

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(new TopicInfo[] { accessRequestTopic, resultTopic });

                // create notification listener and subscription
                Utils.NotifyServer server = new NotifyServer(_nic);
                SetupNotifyServer(server);
                string notificationsUri = server.GetNotificationUri();
                subscriptionReference   = CreateSubscription(filter, timeout, notificationsUri, out subscribeStarted);

                string credentialsToken      = string.Empty;
                string credentialsHolderName = string.Empty;
                string accessPointToken      = GetAccessRequestMessage(server,
                                                                       timeout,
                                                                       accessRequestTopic,
                                                                       validateRequestMessageFunction,
                                                                       fullAccessPointsList,
                                                                       accessPointsList,
                                                                       ref credentialsToken,
                                                                       ref credentialsHolderName);

                // receive events - after calling ExternalAuthorization
                {
                    BeginStep("Start listening");
                    Notify notify = server.WaitForNotify(() => { StepPassed(); reactToRequest(accessPointToken, credentialsToken); },
                                                         timeout * 1000,
                                                         _semaphore.StopEvent);

                    RemoveHandlers(server);

                    ValidateNotificationsPacket(server.RawData);

                    ValidateNotifyNotEmpty(notify);

                    if (notify.NotificationMessage.Length > 1)
                    {
                        LogTestEvent("DUT sent more than one notification. Test will be performed for token from the first notification");
                    }
                    NotificationMessageHolderType theMessage = notify.NotificationMessage[0];

                    ValidateResultMessage(notify, theMessage, server.RawData, resultTopic, validateResultMessageFunction, accessPointToken, credentialsToken, credentialsHolderName);
                }
            },
                () =>
            {
                _operator.HideMessage();
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }
        void ExternalAuthorizationTimeoutTest(
            Func <AccessPointInfo, bool> accessPointCapabilitiesTest,
            TopicInfo accessRequestTopic,
            Action <XmlElement, TopicInfo> validateAccessRequestTopic,
            ValidateMessageFunction validateRequestMessageFunction,
            TopicInfo resultTopic,
            Action <XmlElement, TopicInfo> validateResultTopic,
            ValidateMessageFunction validateResultMessageFunction)
        {
            EndpointReferenceType subscriptionReference = null;

            System.DateTime subscribeStarted = System.DateTime.MaxValue;

            int timeout = 60;

            RunTest(
                () =>
            {
                //3.	Get complete list of access points from the DUT (see Annex A.1).
                List <AccessPointInfo> fullAccessPointsList = GetAccessPointInfoList();

                //4.	Check that there is at least one Access Point with required Capabilities

                List <AccessPointInfo> accessPointsList = null;
                if (accessPointCapabilitiesTest != null)
                {
                    accessPointsList = fullAccessPointsList.Where(A => accessPointCapabilitiesTest(A)).ToList();

                    if (accessPointsList.Count == 0)
                    {
                        LogTestEvent("No AccessPoints with required Capabilities found, exit the test." + Environment.NewLine);
                        return;
                    }
                }
                else
                {
                    accessPointsList = fullAccessPointsList;
                }

                // Get topic description from the DUT and check topics support

                ValidateTopicsSupport(accessRequestTopic, validateAccessRequestTopic,
                                      resultTopic, validateResultTopic);

                // filter for current test
                TestTool.Proxies.Event.FilterType filter = CreateSubscriptionFilter(new TopicInfo[] { accessRequestTopic, resultTopic });

                // create notification listener and subscription
                Utils.NotifyServer server = new NotifyServer(_nic);
                SetupNotifyServer(server);
                string notificationsUri = server.GetNotificationUri();
                subscriptionReference   = CreateSubscription(filter, timeout, notificationsUri, out subscribeStarted);

                // get access request message
                string credentialsToken      = string.Empty;
                string credentialsHolderName = string.Empty;
                string accessPointToken      = GetAccessRequestMessage(server,
                                                                       timeout,
                                                                       accessRequestTopic,
                                                                       validateRequestMessageFunction,
                                                                       fullAccessPointsList,
                                                                       accessPointsList,
                                                                       ref credentialsToken,
                                                                       ref credentialsHolderName);
                RemoveHandlers(server);

                // receive events
                {
                    EnsureNotificationProducerClientCreated();

                    LogTestEvent(string.Format("Wait for {0} event{1}", resultTopic.GetDescription(), Environment.NewLine));

                    Utils.NotifyAsyncServer asyncServer = new NotifyAsyncServer(_nic);
                    SetupNotifyServer2(asyncServer);
                    asyncServer.StartCollecting(_semaphore.StopEvent);

                    AutoResetEvent received           = new AutoResetEvent(false);
                    asyncServer.NotificationReceived +=
                        new Action <byte[]>((data) => { received.Set(); });

                    Renew request           = new Renew();
                    request.TerminationTime = "PT60S";

                    // use 50 second instead of 60
                    int subscriptionGuaranteedTimeLeft = (int)(subscribeStarted.AddSeconds(50) - System.DateTime.Now).TotalMilliseconds;
                    if (subscriptionGuaranteedTimeLeft < 0)
                    {
                        subscriptionGuaranteedTimeLeft = 0;
                    }
                    System.DateTime exitTime = System.DateTime.Now.AddMilliseconds(_messageTimeout);

                    try
                    {
                        while (true)
                        {
                            // check if we are still waiting the message
                            int waitTimeLeft = (int)(exitTime - System.DateTime.Now).TotalMilliseconds;
                            if (waitTimeLeft <= 0)
                            {
                                break;
                            }

                            // compute time for next wait
                            int waitTime = Math.Min(subscriptionGuaranteedTimeLeft, waitTimeLeft);
                            int res      = WaitHandle.WaitAny(new WaitHandle[] { received, _semaphore.StopEvent }, waitTime);

                            if (res == WaitHandle.WaitTimeout)
                            {
                                // no notification received
                                if (System.DateTime.Now < exitTime)
                                {
                                    Renew(request);
                                    subscriptionGuaranteedTimeLeft = 50000;
                                    subscribeStarted = System.DateTime.Now;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else if (res == 1)
                            {
                                asyncServer.StopCollecting();
                                // Stop event received
                                throw new StopEventException();
                            }
                            else
                            {
                                // Notification received
                                break;
                            }
                        }
                    }
                    catch (Exception exc)
                    {
                        throw;
                    }
                    finally
                    {
                        asyncServer.StopCollecting();
                        RemoveHandlers2(asyncServer);
                    }

                    Dictionary <Notify, byte[]> messages = asyncServer.Get();

                    Assert(messages.Count > 0, "No notifications received", "Check if the DUT sent notifications");

                    Notify notify  = messages.Keys.First();
                    byte[] rawData = messages[notify];

                    ValidateNotificationsPacket(rawData);

                    ValidateNotifyNotEmpty(notify);

                    NotificationMessageHolderType theMessage = notify.NotificationMessage[0];

                    ValidateResultMessage(notify,
                                          theMessage,
                                          rawData,
                                          resultTopic,
                                          validateResultMessageFunction,
                                          accessPointToken,
                                          credentialsToken,
                                          credentialsHolderName);
                }
            },
                () =>
            {
                _operator.HideMessage();
                ReleaseSubscription(subscribeStarted, subscriptionReference, timeout);
            });
        }