/// <summary>
        /// Handles change events raised by the node.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="state">The node that raised the event.</param>
        /// <param name="masks">What caused the event to be raised</param>
        public void OnNodeChange(ISystemContext context, NodeState state, NodeStateChangeMasks masks)
        {
            if (m_monitoredItems != null)
            {
                for (int ii = 0; ii < m_monitoredItems.Count; ii++)
                {
                    DataChangeMonitoredItem monitoredItem = m_monitoredItems[ii];

                    // check if the node has been deleted.
                    if ((masks & NodeStateChangeMasks.Deleted) != 0)
                    {
                        monitoredItem.QueueValue(null, StatusCodes.BadNodeIdUnknown);
                        continue;
                    }

                    if (monitoredItem.AttributeId == Attributes.Value)
                    {
                        if ((masks & NodeStateChangeMasks.Value) != 0)
                        {
                            monitoredItem.ValueChanged(context);
                        }
                    }
                    else
                    {
                        if ((masks & NodeStateChangeMasks.NonValue) != 0)
                        {
                            monitoredItem.ValueChanged(context);
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Whether the node has any active monitored items for the specified attribute.
 /// </summary>
 /// <param name="attributeId">The attribute id.</param>
 /// <returns>
 ///     <c>true</c> if there is enebled monitored item with AttributeId equal <paramref name="attributeId"/>; otherwise, <c>false</c>.
 /// </returns>
 public bool IsMonitoringRequired(uint attributeId)
 {
     if (m_monitoredItems != null)
     {
         for (int ii = 0; ii < m_monitoredItems.Count; ii++)
         {
             DataChangeMonitoredItem monitoredItem = m_monitoredItems[ii];
             if (monitoredItem.AttributeId == attributeId && monitoredItem.MonitoringMode != MonitoringMode.Disabled)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        /// <summary>
        /// Creates a new data change monitored item.
        /// </summary>
        /// <param name="context">The system context.</param>
        /// <param name="monitoredItemId">The unique identifier for the monitiored item.</param>
        /// <param name="attributeId">The attribute to monitor.</param>
        /// <param name="indexRange">The index range to use for array values.</param>
        /// <param name="dataEncoding">The data encoding to return for structured values.</param>
        /// <param name="diagnosticsMasks">The diagnostics masks to use.</param>
        /// <param name="timestampsToReturn">The timestamps to return.</param>
        /// <param name="monitoringMode">The initial monitoring mode.</param>
        /// <param name="clientHandle">The handle assigned by the client.</param>
        /// <param name="samplingInterval">The sampling interval.</param>
        /// <param name="queueSize">The queue size.</param>
        /// <param name="discardOldest">Whether to discard the oldest values when the queue overflows.</param>
        /// <param name="filter">The data change filter to use.</param>
        /// <param name="range">The range to use when evaluating a percentage deadband filter.</param>
        /// <param name="alwaysReportUpdates">Whether the monitored item should skip the check for a change in value.</param>
        /// <returns>The new monitored item.</returns>
        public DataChangeMonitoredItem CreateDataChangeItem(
            ISystemContext context,
            uint monitoredItemId,
            uint attributeId,
            NumericRange indexRange,
            QualifiedName dataEncoding,
            DiagnosticsMasks diagnosticsMasks,
            TimestampsToReturn timestampsToReturn,
            MonitoringMode monitoringMode,
            uint clientHandle,
            double samplingInterval,
            uint queueSize,
            bool discardOldest,
            DataChangeFilter filter,
            Range range,
            bool alwaysReportUpdates)
        {
            DataChangeMonitoredItem monitoredItem = new DataChangeMonitoredItem(
                this,
                monitoredItemId,
                attributeId,
                indexRange,
                dataEncoding,
                diagnosticsMasks,
                timestampsToReturn,
                monitoringMode,
                clientHandle,
                samplingInterval,
                queueSize,
                discardOldest,
                filter,
                range,
                alwaysReportUpdates);

            if (m_monitoredItems == null)
            {
                m_monitoredItems      = new List <DataChangeMonitoredItem>();
                m_node.OnStateChanged = OnNodeChange;
            }
            m_monitoredItems.Add(monitoredItem);
            return(monitoredItem);
        }