/// <summary>
        /// Processes incoming Messages
        /// If a Batch comes in, only the first message must have a valid NPA Path
        /// </summary>
        internal static void ProcessClientDeviceMessage(TheQueuedSender MyQSender, TheRequestData pRequestData, List <TheDeviceMessage> tDevList)
        {
            var toRemove = new List <TheDeviceMessage>();

            foreach (TheDeviceMessage tDev in tDevList)
            {
                if (string.IsNullOrEmpty(tDev.NPA))
                {
                    return; // CODE REVIEW: Really stop processing all subsequent TDMs here (malformed TDM -> security)?
                }
                string NPA = tDev.NPA.Substring(4);
                if (NPA.EndsWith(".ashx", StringComparison.OrdinalIgnoreCase))
                {
                    NPA = NPA.Substring(0, NPA.Length - 5);
                }
                if (TheBaseAssets.MyScopeManager.ParseISBPath(NPA, out Guid? ttSessionID, out cdeSenderType tSenderType, out long tFID, out string tVersion))
                {
                    Guid tSessionID = TheCommonUtils.CGuid(ttSessionID);
                    Guid tDeviceID  = TheCommonUtils.CGuid(tDev.DID);
                    lock (TheBaseAssets.MySession.GetLock())    //CODE-REVIEW: VERY expensive lock! Really necessary?
                    {
                        var myTargetNodeChannel = MyQSender.MyTargetNodeChannel;
                        if (MyQSender.IsConnected && myTargetNodeChannel.MySessionState != null) //!=null new in 3.2
                        {
                            if (!tSessionID.Equals(myTargetNodeChannel.MySessionState.cdeMID))
                            {
                                Guid tOldID = myTargetNodeChannel.MySessionState.cdeMID;
                                myTargetNodeChannel.MySessionState = TheBaseAssets.MySession.ValidateSEID(tSessionID);    //Measure Frequency
                                if (myTargetNodeChannel.MySessionState == null)
                                {
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", $"No exiting session for remote node found. Using new session (possible reason: fast cloud reconnect) ...new: {tSessionID} old: {tOldID}", eMsgLevel.l2_Warning), true);
                                    myTargetNodeChannel.MySessionState = pRequestData.SessionState;
                                }
                                else
                                {
                                    TheBaseAssets.MySession.RemoveSessionByID(tOldID);
                                }
                            }
                        }
                        if (tDeviceID != Guid.Empty && tDeviceID != myTargetNodeChannel.cdeMID)
                        {
                            if (myTargetNodeChannel.SenderType == cdeSenderType.CDE_CUSTOMISB)
                            {
                                if (myTargetNodeChannel.TruDID != tDeviceID)
                                {
                                    myTargetNodeChannel.TruDID = tDeviceID;
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"Custom ISB sets TruDID to: {TheCommonUtils.GetDeviceIDML(tDeviceID)} for MTNC: {myTargetNodeChannel.ToMLString()}", eMsgLevel.l4_Message), true);
                                }
                            }
                            else
                            {
                                TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("CoreComm", $"Different DeviceIDs received ...new: {TheCommonUtils.GetDeviceIDML(tDeviceID)} old: {TheCommonUtils.GetDeviceIDML(myTargetNodeChannel.cdeMID)} {(myTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE ? "For CloudRoute and Service normal" : "")}", eMsgLevel.l2_Warning), true);
                                TheBaseAssets.MySession.RemoveSessionsByDeviceID(myTargetNodeChannel.cdeMID, Guid.Empty);
                                TheQueuedSenderRegistry.UpdateQSenderID(myTargetNodeChannel.cdeMID, tDeviceID);
                                myTargetNodeChannel.cdeMID = tDeviceID;
                                if (pRequestData.DeviceID != tDeviceID)
                                {
                                    TheBaseAssets.MySYSLOG.WriteToLog(243, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("CoreComm", $"Different DeviceIDs in DID and Request ...DID: {TheCommonUtils.GetDeviceIDML(tDeviceID)} Request: {TheCommonUtils.GetDeviceIDML(myTargetNodeChannel.cdeMID)}", eMsgLevel.l2_Warning), true);
                                    pRequestData.DeviceID = tDeviceID;
                                }
                                switch (pRequestData.ResponseMimeType)
                                {
                                case "cde/mini":
                                    myTargetNodeChannel.SenderType = cdeSenderType.CDE_MINI;
                                    break;
                                }
                            }
                        }
                        if (myTargetNodeChannel.MySessionState == null)
                        {
                            myTargetNodeChannel.MySessionState = TheBaseAssets.MySession.GetOrCreateSessionState(tSessionID, pRequestData);
                        }
                        myTargetNodeChannel.MySessionState.SiteVersion = tVersion;
                        myTargetNodeChannel.MySessionState.cdeMID      = tSessionID;
                        myTargetNodeChannel.MySessionState.CurrentURL  = myTargetNodeChannel.TargetUrl;
                        // Keep the RSA public key of the other party, so we can use it to encrypt data when sending to that party in the future
                        if (!String.IsNullOrEmpty(tDev.RSA))
                        {
                            myTargetNodeChannel.MySessionState.RSAPublicSend = tDev.RSA;
                        }
                        if (MyQSender.IsConnecting && !MyQSender.IsConnected)
                        {
                            MyQSender.IsConnected = true;
                            if (myTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE)
                            {
                                if (TheBaseAssets.MyServiceHostInfo.IsIsolated && TheBaseAssets.MyServiceHostInfo.MasterNode == Guid.Empty)
                                {
                                    TheBaseAssets.MyServiceHostInfo.MasterNode = myTargetNodeChannel.cdeMID;
                                    TheQueuedSenderRegistry.SendMasterNodeQueue();
                                }
                                MyQSender.StartHeartBeat();
                                TheBaseAssets.MySYSLOG.WriteToLog(23055, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("CoreComm", $"Cloud Route is back up to {myTargetNodeChannel.ToMLString()}", eMsgLevel.l4_Message));
                                if (TheQueuedSenderRegistry.eventCloudIsBackUp != null)
                                {
                                    TheCommonUtils.cdeRunAsync("QS-StartEngineNU", true, o =>
                                    {
                                        TheQueuedSenderRegistry.eventCloudIsBackUp(TheCDEngines.MyContentEngine, myTargetNodeChannel);
                                    });
                                }
                            }
                            if (MyQSender.eventConnected != null)
                            {
                                TheCommonUtils.cdeRunAsync("QueueConnected", true, (p) => { MyQSender.eventConnected(MyQSender, myTargetNodeChannel); });
                            }
                            MyQSender.MyISBlock?.FireEvent("Connected");
                        }
                        pRequestData.SessionState = myTargetNodeChannel.MySessionState;
                        MyQSender?.SetLastHeartbeat(myTargetNodeChannel.MySessionState);
                    }
                    if (!string.IsNullOrEmpty(tDev.TOP) && tDev.TOP.StartsWith("CDE_CONNECT"))
                    {
                        string[] tP = TheCommonUtils.cdeSplit(tDev.TOP, ";:;", true, true);
                        if (tP.Length > 1)
                        {
                            string tEngs = tP[1];
                            TheCommonUtils.cdeRunAsync("QS-StartEngineNU", false, o =>
                            {
                                TheCDEngines.StartEngineWithNewUrl(MyQSender?.MyTargetNodeChannel, tEngs);
                            });
                        }
                        if (tDevList.Count > 1)
                        {
                            if (toRemove == null)
                            {
                                toRemove = new List <TheDeviceMessage>();
                            }
                            toRemove.Add(tDev);
                            continue;
                        }
                        else
                        {
                            return;
                        }
                    }
                    if (string.IsNullOrEmpty(tDev.TOP) || tDev.TOP.StartsWith("CDE_PICKUP") || tDev.TOP.StartsWith("CDE_WSINIT"))
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(23056, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Heartbeat received {MyQSender?.MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l4_Message));
                        if (tDevList.Count > 1)
                        {
                            if (toRemove == null)
                            {
                                toRemove = new List <TheDeviceMessage>();
                            }
                            toRemove.Add(tDev);
                            continue;
                        }
                        else
                        {
                            return;
                        }
                    }
                    break; //Found valid path and can go out
                }
            }
            if (toRemove != null)
            {
                foreach (var tDev in toRemove)
                {
                    tDevList.Remove(tDev);
                }
            }
            TheCommonUtils.cdeRunAsync("QS-UpCo2Exec", false, o =>
            {
                pRequestData.ResponseBuffer = null;
                DoExecuteCommand(null, MyQSender, false, pRequestData, tDevList);
            }, tDevList);
        }