/// <summary>
        /// [TD Reference 3.2.5.3.4]
        /// Decode MCS Connect Response PDU with GCC Conference Create Response
        /// </summary>
        /// <param name="data">data to be parsed</param>
        /// <returns>decoded MCS Connect Response PDU with GCC Conference Create Response PDU</returns>
        public StackPacket DecodeMcsConnectResponsePDU(byte[] data)
        {
            // initialize
            int currentIndex = 0;
            Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response pdu =
                new Server_MCS_Connect_Response_Pdu_with_GCC_Conference_Create_Response();

            // McsConnectResponse: TpktHeader
            pdu.tpktHeader = ParseTpktHeader(data, ref currentIndex);

            // McsConnectResponse: X224
            pdu.x224Data = ParseX224Data(data, ref currentIndex);

            // T125 Data: decode McsConnectResponse
            int t125DataLength = data.Length - currentIndex;
            if (t125DataLength <= 0)
            {
                throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE);
            }
            byte[] t125Data = new byte[t125DataLength];
            Array.Copy(data, currentIndex, t125Data, 0, t125Data.Length);
            Connect_Response mcsConnectResponse = new Connect_Response();
            Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(t125Data);
            mcsConnectResponse.BerDecode(decodeBuffer);

            // McsConnectResponse:result
            pdu.mcsCrsp.result = (int)mcsConnectResponse.result.Value;
            byte[] userData = mcsConnectResponse.userData.ByteArrayValue;

            // T125 Data: decode McsConnectResponse's user data
            Asn1DecodingBuffer connectDataBuffer = new Asn1DecodingBuffer(userData);
            ConnectData connectData = new ConnectData();
            connectData.PerDecode(connectDataBuffer);

            // T125 Data: get Gcc data
            int gccDataLength = userData.Length - ConstValue.GCC_DATA_OFFSET;
            if (gccDataLength <= 0)
            {
                throw new FormatException(ConstValue.ERROR_MESSAGE_DATA_INDEX_OUT_OF_RANGE);
            }
            byte[] gccData = new byte[gccDataLength];
            Array.Copy(userData, ConstValue.GCC_DATA_OFFSET, gccData, 0, gccData.Length);

            // T125 Data: decode Gcc user data
            ConnectGCCPDU gccPdu = new ConnectGCCPDU();
            Asn1DecodingBuffer gccPduBuffer = new Asn1DecodingBuffer(gccData);
            gccPdu.PerDecode(gccPduBuffer);

            // McsConnectResponse: H221Key
            ConferenceCreateResponse conferenceResponse = (ConferenceCreateResponse)gccPdu.GetData();
            H221NonStandardIdentifier identifier =
                (H221NonStandardIdentifier)conferenceResponse.userData.Elements[0].key.GetData();
            pdu.mcsCrsp.gccPdu.H221Key = Encoding.ASCII.GetString(identifier.ByteArrayValue);

            // McsConnectResponse: ccrResult
            pdu.mcsCrsp.gccPdu.ccrResult = (int)conferenceResponse.result.Value;

            // McsConnectResponse: nodeID
            pdu.mcsCrsp.gccPdu.nodeID = (int)conferenceResponse.nodeID.Value;

            // McsConnectResponse: tag
            pdu.mcsCrsp.gccPdu.tag = (int)conferenceResponse.tag.Value;

            // T125 Data: get Gcc user data
            byte[] gccUserData = conferenceResponse.userData.Elements[0].value.ByteArrayValue;

            // Reset current index
            currentIndex = 0;
            while (currentIndex < gccUserData.Length)
            {
                // Peek data type
                int tempIndex = currentIndex;
                TS_UD_HEADER_type_Values type =
                    (TS_UD_HEADER_type_Values)ParseUInt16(gccUserData, ref tempIndex, false);

                // Parse data by type
                switch (type)
                {
                    case TS_UD_HEADER_type_Values.SC_CORE:
                        pdu.mcsCrsp.gccPdu.serverCoreData = ParseTsUdScCore(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_NET:
                        pdu.mcsCrsp.gccPdu.serverNetworkData = ParseTsUdScNet(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_SECURITY:
                        pdu.mcsCrsp.gccPdu.serverSecurityData = ParseTsUdScSec1(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_MCS_MSGCHANNEL:
                        pdu.mcsCrsp.gccPdu.serverMessageChannelData = ParseTsUdScMSGChannel(gccUserData, ref currentIndex);
                        break;

                    case TS_UD_HEADER_type_Values.SC_MULTITRANSPORT:
                        pdu.mcsCrsp.gccPdu.serverMultitransportChannelData = ParseTsUdScMultiTransport(gccUserData, ref currentIndex);
                        break;

                    default:
                        throw new FormatException(ConstValue.ERROR_MESSAGE_ENUM_UNRECOGNIZED);
                }
            }

            // Check if data length exceeded expectation
            VerifyDataLength(gccUserData.Length, currentIndex, ConstValue.ERROR_MESSAGE_DATA_LENGTH_EXCEEDED);
            return pdu;
        }
        /// <summary>
        /// Encode this structure into byte array.
        /// </summary>
        /// <returns>The byte array of the structure.</returns>
        public override byte[] ToBytes()
        {
            List<byte> totalBuffer = new List<byte>();
            RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader);
            RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data);

            if (mcsCrsp != null)
            {
                byte[] gccData = EncodeGccRspData(mcsCrsp.gccPdu);

                #region Filling MCS Connect Response PDU
                Connect_Response connectResponse = new Connect_Response();
                connectResponse.result = new Result(mcsCrsp.result);
                connectResponse.calledConnectId = new Asn1Integer(mcsCrsp.calledConnectId);
                connectResponse.domainParameters = new DomainParameters(new Asn1Integer(mcsCrsp.domainParameters.maxChannelIds),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.maxUserIds),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.maxTokenIds),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.numPriorities),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.minThroughput),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.maxHeight),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.maxMcsPduSize),
                                                                       new Asn1Integer(mcsCrsp.domainParameters.protocolVersion));
                connectResponse.userData = new Asn1OctetString(gccData);
                #endregion Filling MCS Connect Response PDU

                #region Encode MCS Connect Initial PDU
                Asn1BerEncodingBuffer berEncodeBuffer = new Asn1BerEncodingBuffer();
                connectResponse.BerEncode(berEncodeBuffer);
                #endregion MCS Connect Initial PDU

                RdpbcgrEncoder.EncodeBytes(totalBuffer, berEncodeBuffer.Data);
            }

            byte[] encodedBytes = RdpbcgrUtility.ToBytes(totalBuffer);

            // ToDo: Ugly dump message code here
            // ETW Provider Dump Code
            RdpbcgrUtility.ETWProviderDump(this.GetType().Name, encodedBytes);

            return encodedBytes;
        }