internal override void ParseEntityInternal(IFreeformEntity entity, ref List <byte> buffer)
        {
            IFreeformEntity_MsgTgt tgt  = entity as IFreeformEntity_MsgTgt;
            IFreeformEntity_MsgTgt tgt2 = tgt;

            if (tgt2 != null)
            {
                // has raw data inside the target
                if (tgt2 is IFFTgt_Override)
                {
                    buffer.AddRange(tgt2.ToRawData());
                    return;
                }

                int       gmuParserId   = this.GetTargetId(tgt, out tgt2);
                int       gmuTargetId   = gmuParserId.ExtractCombinedId();
                bool      isSecured     = tgt2.IsSecured;
                bool      hasSubTargets = this.HasSubTargets;
                byte[]    buffer2       = null;
                IFFParser parser        = this;
                IFFParser parserSecured = null;

                FFParserItem parserItem = this.GetParserItem(null, gmuParserId);
                if (parserItem == null)
                {
                    if (tgt2.Parent != null &&
                        tgt2.Parent is IFreeformEntity_Msg)
                    {
                        int id = FreeformHelper.CreateCombinedId(tgt2.Parent.UniqueEntityId.GetGmuIdInt8(), gmuParserId);
                        parserItem = this.GetParserItem(null, id);
                    }
                }

                // found?
                if (parserItem != null)
                {
                    // parser
                    IFFParser parser2 = parserItem.GetParser(this.FlowInitiation);
                    if (parser2 != null)
                    {
                        if (tgt2.Targets != null &&
                            tgt2.Targets.Count > 0)
                        {
                            buffer2 = parser2.ParseTarget(tgt2);
                        }
                        else
                        {
                            parser = parser2;
                        }
                    }

                    // secured parser
                    if (isSecured)
                    {
                        int          securityId  = FreeformHelper.CreateCombinedId(entity.Parent as IFreeformEntity_Msg, SECURITY_ID, false);
                        FFParserItem parserItem2 = this.GetParserItem(null, securityId);
                        if (parserItem2 != null)
                        {
                            parserSecured = parserItem2.GetParser(this.FlowInitiation);
                        }
                    }
                }

                bool skipTargetInfo = parser.SkipTargetInfo;
                if (buffer2 == null)
                {
                    List <byte> data = new List <byte>();
                    parser.GetTargetData(tgt2, ref data);
                    buffer2 = data.ToArray();
                }

                // encrypt the target
                if (isSecured &&
                    parserSecured != null)
                {
                    List <byte> bufferToEncrypt = new List <byte>();
                    this.AddTargetToBuffer(ref bufferToEncrypt, (byte)gmuTargetId, buffer2, true, false);

                    parserSecured.GetTargetData(tgt2, ref bufferToEncrypt);
                    buffer2        = bufferToEncrypt.ToArray();
                    gmuTargetId    = SECURITY_ID;
                    hasSubTargets  = true;
                    skipTargetInfo = false;
                }

                this.AddTargetToBuffer(ref buffer, (byte)gmuTargetId, buffer2, hasSubTargets, skipTargetInfo);
            }
        }
        protected override IFreeformEntity ParseBufferInternal(IFreeformEntity parent, IFreeformEntity rootEntity, ref IFreeformEntity entity, byte[] buffer, int offset, int length)
        {
            if (length == 0)
            {
                return(null);
            }
            int sessionId = -1;

            if (buffer != null)
            {
                if (length < 0)
                {
                    length = buffer.Length;
                }
                bool hasSubTargets = this.HasSubTargets;

                while (offset < length)
                {
                    int    id         = buffer[offset];
                    int    combinedId = id;
                    byte   length2    = 0;
                    byte[] buffer2    = null;

                    if (rootEntity != null &&
                        rootEntity is IFreeformEntity_Msg)
                    {
                        combinedId = rootEntity.CreateCombinedId(id, false);
                    }

                    if (HasSubTargets)
                    {
                        length2 = buffer[++offset]; // we may get zero length buffer
                        if (length2 > 0)
                        {
                            buffer2 = new byte[length2];
                            Buffer.BlockCopy(buffer, ++offset, buffer2, 0, buffer2.Length);
                        }
                        else
                        {
                            offset += 1;
                            continue;
                        }
                    }
                    else
                    {
                        buffer2 = new byte[buffer.Length - 1];
                        Buffer.BlockCopy(buffer, ++offset, buffer2, 0, buffer2.Length);
                    }

                    if (buffer2 != null)
                    {
                        IFreeformEntity_MsgTgt target    = null;
                        bool         isSecured           = false;
                        bool         isResponseRequired  = false;
                        bool         isResponseRequired2 = false;
                        FFParserItem parserItem          = this.GetParserItem(rootEntity, id);
                        int          appId = id;

                        // not found, then try it with combined id
                        if (parserItem == null)
                        {
                            parserItem = this.GetParserItem(rootEntity, combinedId);
                        }

                        // found
                        if (parserItem != null)
                        {
                            // check if response required
                            id = id.GetRequestResponseId(out isResponseRequired);

                            // check if the packet is secured
                            appId = parserItem.AppId.GetRequestResponseId(out isResponseRequired2);

                            FFTgtParseBufferHandler action = parserItem[this.FlowInitiation].Action;
                            if (action != null)
                            {
                                target = action(parent as IFreeformEntity_MsgTgt, id, length2, buffer2);
                            }
                            else
                            {
                                IFFParser parser = parserItem.GetParser(this.FlowInitiation);
                                if (parser != null)
                                {
                                    target = parser.ParseBuffer(rootEntity, appId, buffer2) as IFreeformEntity_MsgTgt;
                                }
                            }
                        }

                        // secured target
                        if (target is FFTgt_B2B_Encrypted)
                        {
                            rootEntity.EncryptedTarget = target;
                            isSecured = true;
                        }

                        entity = target;
                        if (target != null)
                        {
                            target.TargetID           = appId;
                            target.TargetLength       = length2;
                            target.EntityData         = buffer2;
                            target.IsSecured          = isSecured;
                            target.IsResponseRequired = isResponseRequired;
                            if (parent != null)
                            {
                                parent.Targets.Add(target);
                            }
                            if (target is IFreeformEntity_MsgTgt_Primary &&
                                rootEntity != null)
                            {
                                rootEntity.EntityPrimaryTarget = target;
                            }
                        }
                    }

                    if (hasSubTargets)
                    {
                        offset += length2;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(entity);
        }