/// <summary>
        /// The delegate used to receive event notifications via a direct function call instead of a .NET Event.
        /// </summary>
        public void OnEventNotification(Opc.Ua.Client.Subscription subscription, EventNotificationList notification, IList<string> stringTable)
        {
            for (int ii = 0; ii < notification.Events.Count; ii++)
            {
                MonitoredItem localItem = null;

                EventFieldList e = null;

                lock (subscription.Session)
                {
                    Opc.Ua.Client.MonitoredItem monitoredItem = subscription.FindItemByClientHandle(notification.Events[ii].ClientHandle);

                    if (monitoredItem != null)
                    {
                        e = notification.Events[ii];

                        for (int jj = 0; jj < e.EventFields.Count; jj++)
                        {
                            e.EventFields[jj] = m_mapper.ToLocalVariant(e.EventFields[jj]);
                        }

                        localItem = (MonitoredItem)monitoredItem.Handle;
                        e.ClientHandle = localItem.ClientHandle;
                    }
                }

                localItem.QueueEvent(e);
            }
        }
        /// <summary>
        /// The delegate used to receive data change notifications via a direct function call instead of a .NET Event.
        /// </summary>
        public void OnDataChangeNotification(Opc.Ua.Client.Subscription subscription, DataChangeNotification notification, IList<string> stringTable)
        {
            for (int ii = 0; ii < notification.MonitoredItems.Count; ii++)
            {
                MonitoredItem localItem = null;
                DataValue value = null;
                ServiceResult error = null;

                lock (subscription.Session)
                {
                    Opc.Ua.Client.MonitoredItem monitoredItem = subscription.FindItemByClientHandle(notification.MonitoredItems[ii].ClientHandle);

                    if (monitoredItem != null)
                    {
                        MonitoredItemNotification value2 = notification.MonitoredItems[ii];

                        if (value2.Value.StatusCode != StatusCodes.Good)
                        {
                            error = new ServiceResult(value2.Value.StatusCode, value2.DiagnosticInfo, stringTable);
                        }

                        value = value2.Value;
                        value.WrappedValue = m_mapper.ToLocalVariant(value2.Value.WrappedValue);
                        value.ServerTimestamp = DateTime.UtcNow;

                        localItem = (MonitoredItem)monitoredItem.Handle;
                    }
                }

                localItem.QueueValue(value, error);
            }
        }