/// <summary>
        /// Decode the stream from decoder parameter and produce a Dataset
        /// </summary>
        /// <param name="binaryDecoder"></param>
        /// <param name="dataSetReaders"></param>
        /// <returns></returns>
        public void DecodeSubscribedDataSets(BinaryDecoder binaryDecoder, IList <DataSetReaderDataType> dataSetReaders)
        {
            if (dataSetReaders == null || dataSetReaders.Count == 0)
            {
                return;
            }

            try
            {
                List <DataSetReaderDataType> dataSetReadersFiltered = new List <DataSetReaderDataType>();

                // 1. decode network message header (PublisherId & DataSetClassId)
                DecodeNetworkMessageHeader(binaryDecoder);

                //ignore network messages that are not dataSet messages
                if (m_uadpNetworkMessageType != UADPNetworkMessageType.DataSetMessage)
                {
                    return;
                }

                /* 6.2.8.1 PublisherId
                 * The parameter PublisherId defines the Publisher to receive NetworkMessages from.
                 * If the value is null, the parameter shall be ignored and all received NetworkMessages pass the PublisherId filter. */
                foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                {
                    //check Enabled & publisher id
                    if (dataSetReader.PublisherId.Value == null ||
                        (PublisherId != null && PublisherId.Equals(dataSetReader.PublisherId.Value)))
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                }
                if (dataSetReadersFiltered.Count == 0)
                {
                    return;
                }
                dataSetReaders = dataSetReadersFiltered;

                //continue filtering
                dataSetReadersFiltered = new List <DataSetReaderDataType>();

                // 2. decode WriterGroupId
                DecodeGroupMessageHeader(binaryDecoder);

                /* 6.2.8.2 WriterGroupId
                 * The parameter WriterGroupId with DataType UInt16 defines the identifier of the corresponding WriterGroup.
                 * The default value 0 is defined as null value, and means this parameter shall be ignored.*/
                foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                {
                    //check WriterGroupId id
                    if (dataSetReader.WriterGroupId == 0 || dataSetReader.WriterGroupId == WriterGroupId)
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                }
                if (dataSetReadersFiltered.Count == 0)
                {
                    return;
                }
                dataSetReaders = dataSetReadersFiltered;

                // 3. decode payload header
                DecodePayloadHeader(binaryDecoder);
                // 4.
                DecodeExtendedNetworkMessageHeader(binaryDecoder);
                // 5.
                DecodeSecurityHeader(binaryDecoder);

                //6.1
                DecodePayloadSize(binaryDecoder);

                // the list of decode dataset messages for this network message
                List <UaDataSetMessage> dataSetMessages = new List <UaDataSetMessage>();

                /* 6.2.8.3 DataSetWriterId
                 * The parameter DataSetWriterId with DataType UInt16 defines the DataSet selected in the Publisher for the DataSetReader.
                 * If the value is 0 (null), the parameter shall be ignored and all received DataSetMessages pass the DataSetWriterId filter.*/
                foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                {
                    List <UaDataSetMessage> uadpDataSetMessages = new List <UaDataSetMessage>(DataSetMessages);
                    //if there is no information regarding dataSet in network message, add dummy datasetMessage to try decoding
                    if (uadpDataSetMessages.Count == 0)
                    {
                        uadpDataSetMessages.Add(new UadpDataSetMessage());
                    }
                    // 6.2 Decode payload into DataSets
                    // Restore the encoded fields (into dataset for now) for each possible dataset reader
                    foreach (UadpDataSetMessage uadpDataSetMessage in uadpDataSetMessages)
                    {
                        if (uadpDataSetMessage.DataSet != null)
                        {
                            continue; // this dataset message was already decoded
                        }
                        if (dataSetReader.DataSetWriterId == 0 || uadpDataSetMessage.DataSetWriterId == dataSetReader.DataSetWriterId)
                        {
                            //atempt to decode dataset message using the reader
                            uadpDataSetMessage.DecodePossibleDataSetReader(binaryDecoder, dataSetReader);
                            if (uadpDataSetMessage.DataSet != null)
                            {
                                dataSetMessages.Add(uadpDataSetMessage);
                            }
                        }
                    }
                }

                if (m_uaDataSetMessages.Count == 0)
                {
                    // set the list of dataset messages to the network message
                    m_uaDataSetMessages.AddRange(dataSetMessages);
                }
            }
            catch (Exception ex)
            {
                // Unexpected exception in DecodeSubscribedDataSets
                Utils.Trace(ex, "UadpNetworkMessage.DecodeSubscribedDataSets");
            }
        }
        /// <summary>
        /// Decode the stream from decoder parameter and produce a Dataset
        /// </summary>
        /// <param name="jsonDecoder"></param>
        /// <param name="dataSetReaders"></param>
        /// <returns></returns>
        public void DecodeSubscribedDataSets(JsonDecoder jsonDecoder, IEnumerable <DataSetReaderDataType> dataSetReaders)
        {
            try
            {
                List <DataSetReaderDataType> dataSetReadersFiltered = new List <DataSetReaderDataType>();

                // 1. decode network message header (PublisherId & DataSetClassId)
                DecodeNetworkMessageHeader(jsonDecoder);

                // ignore network messages that are not dataSet messages
                if (m_jsonNetworkMessageType != JSONNetworkMessageType.DataSetMessage)
                {
                    return;
                }

                //* 6.2.8.1 PublisherId
                // The parameter PublisherId defines the Publisher to receive NetworkMessages from.
                // If the value is null, the parameter shall be ignored and all received NetworkMessages pass the PublisherId filter. */
                foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                {
                    if (dataSetReader.PublisherId == Variant.Null)
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                    // publisher id
                    else if ((NetworkMessageContentMask & JsonNetworkMessageContentMask.PublisherId) != 0 &&
                             PublisherId != null &&
                             PublisherId.Equals(dataSetReader.PublisherId.Value.ToString()))
                    {
                        dataSetReadersFiltered.Add(dataSetReader);
                    }
                }
                if (dataSetReadersFiltered.Count == 0)
                {
                    return;
                }
                dataSetReaders = dataSetReadersFiltered;

                object        messagesToken    = null;
                List <object> messagesList     = null;
                string        messagesListName = string.Empty;
                if (jsonDecoder.ReadField(kFieldMessages, out messagesToken))
                {
                    messagesList = messagesToken as List <object>;
                    if (messagesList == null)
                    {
                        // this is a SingleDataSetMessage encoded as the conteten of Messages
                        jsonDecoder.PushStructure(kFieldMessages);
                        messagesList = new List <object>();
                    }
                    else
                    {
                        messagesListName = kFieldMessages;
                    }
                }
                else if (jsonDecoder.ReadField(JsonDecoder.RootArrayName, out messagesToken))
                {
                    messagesList     = messagesToken as List <object>;
                    messagesListName = JsonDecoder.RootArrayName;
                }
                else
                {
                    // this is a SingleDataSetMessage encoded as the conteten of json
                    messagesList = new List <object>();
                }
                if (messagesList != null)
                {
                    // atempt decoding for each data set reader
                    foreach (DataSetReaderDataType dataSetReader in dataSetReaders)
                    {
                        JsonDataSetReaderMessageDataType jsonMessageSettings = ExtensionObject.ToEncodeable(dataSetReader.MessageSettings)
                                                                               as JsonDataSetReaderMessageDataType;
                        if (jsonMessageSettings == null)
                        {
                            // The reader MessageSettings is not set up corectly
                            continue;
                        }
                        JsonNetworkMessageContentMask networkMessageContentMask =
                            (JsonNetworkMessageContentMask)jsonMessageSettings.NetworkMessageContentMask;
                        if ((networkMessageContentMask & NetworkMessageContentMask) != NetworkMessageContentMask)
                        {
                            // The reader MessageSettings.NetworkMessageContentMask is not set up corectly
                            continue;
                        }

                        // initialize the dataset message
                        JsonDataSetMessage jsonDataSetMessage = new JsonDataSetMessage();
                        jsonDataSetMessage.DataSetMessageContentMask = (JsonDataSetMessageContentMask)jsonMessageSettings.DataSetMessageContentMask;
                        jsonDataSetMessage.SetFieldContentMask((DataSetFieldContentMask)dataSetReader.DataSetFieldContentMask);
                        // set the flag that indicates if dataset message shall have a header
                        jsonDataSetMessage.HasDataSetMessageHeader = (networkMessageContentMask & JsonNetworkMessageContentMask.DataSetMessageHeader) != 0;

                        jsonDataSetMessage.DecodePossibleDataSetReader(jsonDecoder, messagesList.Count, messagesListName, dataSetReader);
                        if (jsonDataSetMessage.DataSet != null)
                        {
                            m_uaDataSetMessages.Add(jsonDataSetMessage);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Unexpected exception in DecodeSubscribedDataSets
                Utils.Trace(ex, "JsonNetworkMessage.DecodeSubscribedDataSets");
            }
        }