/// <summary>
        /// Creates and adds one or more MonitoredItems to a Subscription.
        /// </summary>
        /// <param name="client">A instance of <see cref="ISessionClient"/>.</param>
        /// <param name="request">A <see cref="CreateMonitoredItemsRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="CreateMonitoredItemsResponse"/>.</returns>
        public static async Task<CreateMonitoredItemsResponse> CreateMonitoredItemsAsync(this ISessionClient client, CreateMonitoredItemsRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            return (CreateMonitoredItemsResponse)await client.RequestAsync(request).ConfigureAwait(false);
        }
        /// <summary>
        /// Creates new subscriptions on the server.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token. </param>
        /// <returns>A task.</returns>
        private async Task CreateNewSubscriptionsAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            var subscriptionsChanged = new AsyncAutoResetEvent();
            var handler = new NotifyCollectionChangedEventHandler((s, e) => subscriptionsChanged.Set());
            this.Subscriptions.CollectionChanged += handler;

            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    foreach (var subscription in this.Subscriptions)
                    {
                        if (subscription.Id == 0)
                        {
                            try
                            {
                                // create the subscription.
                                var subscriptionRequest = new CreateSubscriptionRequest
                                {
                                    RequestedPublishingInterval = subscription.PublishingInterval,
                                    RequestedMaxKeepAliveCount = subscription.KeepAliveCount,
                                    RequestedLifetimeCount = subscription.LifetimeCount > 0 ? subscription.LifetimeCount : (uint)(this.SessionTimeout / subscription.PublishingInterval),
                                    PublishingEnabled = false, // initially
                                    Priority = subscription.Priority
                                };
                                var subscriptionResponse = await this.CreateSubscriptionAsync(subscriptionRequest);
                                var id = subscription.Id = subscriptionResponse.SubscriptionId;

                                // add the items.
                                if (subscription.MonitoredItems.Count > 0)
                                {
                                    var items = subscription.MonitoredItems.ToList();
                                    var requests = items.Select(m => new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = m.NodeId, AttributeId = m.AttributeId, IndexRange = m.IndexRange }, MonitoringMode = m.MonitoringMode, RequestedParameters = new MonitoringParameters { ClientHandle = m.ClientId, DiscardOldest = m.DiscardOldest, QueueSize = m.QueueSize, SamplingInterval = m.SamplingInterval, Filter = m.Filter } }).ToArray();
                                    var itemsRequest = new CreateMonitoredItemsRequest
                                    {
                                        SubscriptionId = id,
                                        ItemsToCreate = requests,
                                    };
                                    var itemsResponse = await this.CreateMonitoredItemsAsync(itemsRequest);
                                    for (int i = 0; i < itemsResponse.Results.Length; i++)
                                    {
                                        var item = items[i];
                                        var result = itemsResponse.Results[i];
                                        item.ServerId = result.MonitoredItemId;
                                        if (StatusCode.IsBad(result.StatusCode))
                                        {
                                            Log.Warn($"Error response from MonitoredItemCreateRequest for {item.NodeId}. {result.StatusCode}");
                                        }
                                    }
                                }

                                // start publishing.
                                if (subscription.PublishingEnabled)
                                {
                                    var modeRequest = new SetPublishingModeRequest
                                    {
                                        SubscriptionIds = new[] { id },
                                        PublishingEnabled = true,
                                    };
                                    var modeResponse = await this.SetPublishingModeAsync(modeRequest);
                                }
                            }
                            catch (ServiceResultException ex)
                            {
                                Log.Warn($"Error creating subscription '{subscription.GetType().Name}'. {ex.Message}");
                            }
                        }
                    }

                    await subscriptionsChanged.WaitAsync().WithCancellation(cancellationToken);
                }
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                this.Subscriptions.CollectionChanged -= handler;
            }
        }