using Microsoft.VisualStudio.TestTools.UnitTesting;
using Quectel_BC35_G_NBIOT;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Quectel_BC35_G_NBIOT_Test
{
    [TestClass]
    public class RegexMessageCutterTest
    {
        public static bool ValueEquals(IEnumerable<byte> array1, IEnumerable<byte> array2)
        {
            if (array1 == null && array2 == null)
            {
                return true;
            }

            if ((array1 == null) || (array2 == null))
            {
                return false;
            }

            if (array1.Count() != array2.Count())
            {
                return false;
            }
            if (array1.Equals(array2))
            {
                return true;
            }
            else
            {
                for (int Index = 0; Index < array1.Count(); Index++)
                {
                    if (!Equals(array1.ElementAt(Index), array2.ElementAt(Index)))
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        #region Regex test

        [TestMethod]
        public void MsgCutterRegexTestMethod1()
        {
            var rawStr = RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);

            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length, match.Value);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_1()
        {
            var rawStr = RegexMessageCutter.CR + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(false, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == 0);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_2()
        {
            var rawStr = RegexMessageCutter.LF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(false, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == 0);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_3()
        {
            var rawStr = RegexMessageCutter.CRLF + "OK " + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            //Assert.AreEqual(true, match.Index == 0);
            //Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_4()
        {
            var rawStr = RegexMessageCutter.CRLF + " OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            //Assert.AreEqual(true, match.Index == 0);
            //Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_7()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CMD1:param0" + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_8()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_9()
        {
            var rawStr = RegexMessageCutter.CRLF + "    +CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_10()
        {
            /* this is like two Unsolicited messages */
            var rawStr = RegexMessageCutter.CRLF + "+CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK1" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            //Assert.AreEqual(true, match.Index == 0);
            //Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_11()
        {
            /* this is like two Unsolicited messages */
            var rawStr = RegexMessageCutter.CRLF + "+CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "??" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            //Assert.AreEqual(true, match.Index == 0);
            //Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_12()
        {
            /* this is like 4 Unsolicited messages */
            var rawStr = RegexMessageCutter.CRLF + "+CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "+CMD2:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "+CMD3:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod1_13()
        {
            var unexpectedHeader = "123";
            var rawStr = "123" + RegexMessageCutter.CRLF + "+CMD1:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "+CMD2:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "+CMD3:param0   " + RegexMessageCutter.CRLF +
                RegexMessageCutter.CRLF + "OK" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == unexpectedHeader.Length);
            Assert.AreEqual(true, match.Length == rawStr.Length - unexpectedHeader.Length);
        }


        [TestMethod]
        public void MsgCutterRegexTestMethod1_15()
        {
            /* in AT+QMTPUB Publish Messages: 
             * Write Command AT+QMTPUB=<tcpconnectID>,<msgID>,<qos>,<retain>,"<topic>"
             * After “>” is responded, input the data to be sent. Tap “CTRL+Z” to send, and tap
             * “ESC” to cancel the operation 
             */
            var rawStr = RegexMessageCutter.CRLF + ">";
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod2()
        {
            var rawStr = RegexMessageCutter.CRLF + "ERROR" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod3()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CME ERROR:3" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod4()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CME ERROR:0" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod5()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CME ERROR:13" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod6()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CME ERROR:013" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        [TestMethod]
        public void MsgCutterRegexTestMethod7()
        {
            var rawStr = RegexMessageCutter.CRLF + "+CME ERROR:013433" + RegexMessageCutter.CRLF;
            var match = Regex.Match(rawStr, RegexMessageCutter.RegexStr);
            Assert.AreEqual(true, match.Success);
            Assert.AreEqual(true, match.Index == 0);
            Assert.AreEqual(true, match.Length == rawStr.Length);
        }

        #endregion

        #region PureOkStateResponse

        [TestMethod]
        //[DeploymentItem(@"LiteFccCoreMain\nlog.config")]
        public void PureOkStateResponseTestMethod1()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;

            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(raw, cutter.Message));
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod2()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod3()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod4()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33, RegexMessageCutter.LF, };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod5()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33, RegexMessageCutter.LF, };
            var invalidRaw = new byte[] { RegexMessageCutter.CR, }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(invalidRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 0);
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod6()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33, RegexMessageCutter.LF, };
            var invalidRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF, 0x66, 0x77, 0x88, 0x99 });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(invalidRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
        }


        [TestMethod]
        public void PureOkStateResponseTestMethod10()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
                //put some un-readable chars
                .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
                //.Concat(new byte[] { 0x30 })
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
                .Concat("OK".ToUtf8Bytes())
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod11()
        {
            //\CR\LF+CGPADDR:0,100.89.148.14\CR\LFOK\CR\LF
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
                .Concat("+CGPADDR:0,100.89.148.14".ToUtf8Bytes())
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
                .Concat("OK".ToUtf8Bytes())
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
        }


        [TestMethod]
        public void RegexMessageCutter_IndexOf_Test0()
        {
            var r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 3 });
            Assert.AreEqual(true, r == 2, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 4 });
            Assert.AreEqual(true, r == 3, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1, 2 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 3 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 3, 4 });
            Assert.AreEqual(true, r == 2, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1, 2, 3 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 3, 4 });
            Assert.AreEqual(true, r == 1, "actual: " + r);



            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 6 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 7 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 8 });
            Assert.AreEqual(true, r == -1, "actual: " + r);



            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1, 3 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 4 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);


            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1, 2, 4 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 3, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 3, 4, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);


            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 1, 2, 3, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4 }, new List<byte> { 2, 3, 4, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

        }

        [TestMethod]
        public void RegexMessageCutter_IndexOf_Test1()
        {
            var r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 3 });
            Assert.AreEqual(true, r == 2, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 4 });
            Assert.AreEqual(true, r == 3, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 2 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 3, 4 });
            Assert.AreEqual(true, r == 2, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 2, 3 });
            Assert.AreEqual(true, r == 0, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3, 4 });
            Assert.AreEqual(true, r == 1, "actual: " + r);



            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 0 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 9 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 10 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 11 });
            Assert.AreEqual(true, r == -1, "actual: " + r);



            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 3 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 4 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);


            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 2, 4 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 3, 4, 5 });
            Assert.AreEqual(true, r == 2, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 4, 5 });
            Assert.AreEqual(true, r == 3, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 5, 6, 7, 8 });
            Assert.AreEqual(true, r == 4, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 7, 8 });
            Assert.AreEqual(true, r == 6, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 2, 3, 5 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3, 4, 5 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3, 4, 5, 6 });
            Assert.AreEqual(true, r == 1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 2, 3, 4, 5, 6, 8 });
            Assert.AreEqual(true, r == -1, "actual: " + r);

            r = RegexMessageCutter.IndexOf(new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 }, new List<byte> { 1, 2, 3, 4, 5, 6, 7, 8 });
            Assert.AreEqual(true, r == 0, "actual: " + r);
        }

        [TestMethod]
        public void PureOkStateResponseTestMethod20()
        {
            int onInvalidMsgReadTimes = 0;
            List<List<byte>> onMsgCut = new List<List<byte>>();
            //
            //OK
            //
            //
            //4600
            //
            //
            //OK
            //
            //
            //OK
            //
            var validRaw = new byte[] {
                0x0D, 0x0A, 0x4F, 0x4B, 0x0D, 0x0A,

                0x0D, 0x0A, 0x34, 0x36, 0x30, 0x30, 0x0D, 0x0A,
                0x0D, 0x0A, 0x4F, 0x4B, 0x0D, 0x0A,

                0x0D, 0x0A, 0x4F, 0x4B, 0x0D, 0x0A};
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = validRaw;
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCut.Add(new List<byte>(cutter.Message)); };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCut.Count == 1);
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
        }

        #endregion

        #region PureErrorStateResponse

        [TestMethod]
        public void PureErrorStateResponseTestMethod1()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;

            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("ERROR".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(raw, cutter.Message));
        }

        [TestMethod]
        public void PureErrorStateResponseTestMethod2()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("ERROR".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => onInvalidMsgReadTimes++;
            cutter.OnMessageCut += (a, b) => onMsgCutTimes++;
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureErrorStateResponseTestMethod3()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("ERROR".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        #endregion

        #region PureCmeErrorStateResponse

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod1()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;

            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("+CME ERROR:1".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(raw, cutter.Message));
        }

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod2()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
                .Concat("+CME ERROR:1".ToUtf8Bytes())
                .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => onInvalidMsgReadTimes++;
            cutter.OnMessageCut += (a, b) => onMsgCutTimes++;
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod3()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("+CME ERROR:1".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod4()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;

            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("+CME ERROR:123456".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(raw, cutter.Message));
        }

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod5()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("+CME ERROR:123456".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => onInvalidMsgReadTimes++;
            cutter.OnMessageCut += (a, b) => onMsgCutTimes++;
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        [TestMethod]
        public void PureCmeErrorStateResponseTestMethod6()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var invalidPrefixRaw = new byte[] { 0x00, 0x11, 0x22, RegexMessageCutter.CR, 0x33 };
            var validRaw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("+CME ERROR:123456".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            var raw = invalidPrefixRaw.Concat(validRaw);
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 1);
            Assert.AreEqual(true, onMsgCutTimes == 1);
            Assert.AreEqual(true, ValueEquals(validRaw, cutter.Message));
        }

        #endregion

        #region WithContentResponse, multiple CRLF

        [TestMethod]
        public void WithContentResponseTestMethod1()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("msgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod2()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod3()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod4()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContent中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod5()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContent中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod6()
        {
            int onInvalidMsgReadTimes = 0;
            int onMsgCutTimes = 0;
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContent中文一个ContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("msgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContentmsgContent".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个中文一个".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCutTimes++; };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCutTimes == 1, "actual onMsgCutTimes is " + onMsgCutTimes);
        }

        [TestMethod]
        public void WithContentResponseTestMethod7()
        {
            int onInvalidMsgReadTimes = 0;
            List<byte[]> onMsgCuts = new List<byte[]>();
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCuts.Add(cutter.Message); };
            cutter.Feed(raw.ToArray());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCuts.Count == 1, "actual onMsgCutTimes is " + onMsgCuts.Count);
            Assert.AreEqual(true, ValueEquals(onMsgCuts[0], raw));
        }

        [TestMethod]
        public void WithContentResponseTestMethod8()
        {
            int onInvalidMsgReadTimes = 0;
            List<byte[]> onMsgCuts = new List<byte[]>();
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("OK".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCuts.Add(cutter.Message); };
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            cutter.Feed(raw.ToArray());
            //Debug.WriteLine("stopwatch: " + stopwatch.ElapsedMilliseconds);
            Assert.AreEqual(true, stopwatch.ElapsedMilliseconds < 50, "MsgCutter is too slow to cut, it used(ms) " + stopwatch.ElapsedMilliseconds.ToString());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCuts.Count == 1, "actual onMsgCutTimes is " + onMsgCuts.Count);
            Assert.AreEqual(true, ValueEquals(onMsgCuts[0], raw));
        }

        [TestMethod]
        public void WithContentResponseTestMethod9()
        {
            int onInvalidMsgReadTimes = 0;
            List<byte[]> onMsgCuts = new List<byte[]>();
            var raw = new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF }
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("Quectel".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("BC35-G".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("333333333".ToUtf8Bytes())
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })
            .Concat(new byte[] { 0x11, 0x15, 0x16, 0x17, 0x1B, 0x80, 0x87, 0x8B, 0x8E, 0x8F, 0x99, 0x9C, 0x9F, 0xAD, 0xbf, 0xC0, 0xDD, 0xDE, 0xF0, 0xF7, 0xFF })

            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF })
            .Concat("+CME ERROR:3432423".ToUtf8Bytes())
            .Concat(new byte[] { RegexMessageCutter.CR, RegexMessageCutter.LF });
            RegexMessageCutter cutter = new RegexMessageCutter();
            cutter.OnInvalidMessageRead += (a, b) => { onInvalidMsgReadTimes++; };
            cutter.OnMessageCut += (a, b) => { onMsgCuts.Add(cutter.Message); };
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            cutter.Feed(raw.ToArray());
            //Debug.WriteLine("stopwatch: " + stopwatch.ElapsedMilliseconds);
            Assert.AreEqual(true, stopwatch.ElapsedMilliseconds < 50, "MsgCutter is too slow to cut, it used(ms) " + stopwatch.ElapsedMilliseconds.ToString());
            Assert.AreEqual(true, onInvalidMsgReadTimes == 0, "actual onInvalidMsgReadTimes is " + onInvalidMsgReadTimes);
            Assert.AreEqual(true, onMsgCuts.Count == 1, "actual onMsgCutTimes is " + onMsgCuts.Count);
            Assert.AreEqual(true, ValueEquals(onMsgCuts[0], raw));
        }

        #endregion
    }
}