protected override void ProcessConversation()
        {
            foreach (var snooperExportBase in this.SourceExports)
            {
                foreach (SnooperMQTTExportedObject exportedObject in snooperExportBase.ExportObjects)
                {
                    this.OnBeforeProtocolParsing();

                    MessengerEventBase messengerEvent = null;

                    // Process MQTT publish messages
                    var mqttMessage = exportedObject as MQTTMsg;
                    var mqttCommand = mqttMessage?.Command;
                    if (mqttCommand is MQTTCommandPublish)
                    {
                        var mqttPublishCommand = mqttCommand as MQTTCommandPublish;
                        switch (mqttPublishCommand.Topic)
                        {
                        case "/foreground_state":
                            messengerEvent = this.HandleEvent <MessengerEventForegroundState>(this.SnooperExport, exportedObject.ExportSource, mqttPublishCommand.Payload);
                            break;

                        case "/typing":
                            messengerEvent = this.HandleEvent <MessengerEventTyping>(this.SnooperExport, exportedObject.ExportSource, mqttPublishCommand.Payload);
                            break;

                        case "/t_sm":
                            messengerEvent = this.HandleEvent <MessengerEventSendMessage>(this.SnooperExport, exportedObject.ExportSource, mqttPublishCommand.Payload);
                            break;

                        case "/t_ms":
                            var syncClientPayload = new MNMessagesSyncClientPayload();
                            syncClientPayload.Read(MessengerEventBase.CompactProtocolForPayload(MessengerEventBase.DecompressPayload(mqttPublishCommand.Payload)));
                            this.HandleSyncMessage(this.SnooperExport, exportedObject.ExportSource, syncClientPayload, mqttMessage.TimeStamp, mqttMessage.Frames);
                            break;

                        default:
                            continue;
                        }
                    }
                    else if (mqttCommand is MQTTCommandConnect)
                    {
                        var mqttConnectCommand = mqttCommand as MQTTCommandConnect;
                        messengerEvent = this.HandleEvent <MessengerEventConnect>(this.SnooperExport, exportedObject.ExportSource, mqttConnectCommand.Payload);
                    }
                    else
                    {
                        continue;
                    }

                    if (messengerEvent == null)
                    {
                        continue;
                    }

                    messengerEvent.TimeStamp = mqttMessage.TimeStamp;
                    messengerEvent.Frames.AddRange(mqttMessage.Frames);
                }
            }
        }
        protected void HandleSyncMessage(SnooperExportBase exportObject, IExportSource exportSource, MNMessagesSyncClientPayload syncClientPayload, DateTime timestamp, IEnumerable <PmFrameBase> frames)
        {
            foreach (var syncDeltaWrapper in syncClientPayload.Deltas)
            {
                MessengerEventBase deltaEvent = null;
                if (syncDeltaWrapper.DeltaNewMessage != null)
                {
                    deltaEvent = new MessengerEventReceiveMessage(exportObject, syncDeltaWrapper.DeltaNewMessage);
                }
                else
                {
                    continue;
                }

                this.OnAfterProtocolParsing();

                deltaEvent.TimeStamp = timestamp;
                deltaEvent.Frames.AddRange(frames);

                this.OnBeforeDataExporting();
                deltaEvent.ExportSources.Add(exportSource);
                this.SnooperExport.AddExportObject(deltaEvent);
                this.OnAfterDataExporting();
            }
        }