/// <summary>
        /// Decode one PDU
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static RdpegfxPdu DecodeSinglePdu(byte[] data)
        {
            RdpegfxPdu pdu     = new RdpegfxPdu();
            bool       fResult = PduMarshaler.Unmarshal(data, pdu);

            if (fResult)
            {
                RdpegfxServerPdu receivedPdu = null;
                if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_1)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_1();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_WIRETOSURFACE_2)
                {
                    receivedPdu = new RDPGFX_WIRE_TO_SURFACE_PDU_2();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETEENCODINGCONTEXT)
                {
                    receivedPdu = new RDPGFX_DELETE_ENCODING_CONTEXT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SOLIDFILL)
                {
                    receivedPdu = new RDPGFX_SOLIDFILL();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOSURFACE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_SURFACETOCACHE)
                {
                    receivedPdu = new RDPGFX_SURFACE_TO_CACHE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHETOSURFACE)
                {
                    receivedPdu = new RDPGFX_CACHE_TO_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_EVICTCACHEENTRY)
                {
                    receivedPdu = new RDPGFX_EVICT_CACHE_ENTRY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CREATESURFACE)
                {
                    receivedPdu = new RDPGFX_CREATE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_DELETESURFACE)
                {
                    receivedPdu = new RDPGFX_DELETE_SURFACE();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_STARTFRAME)
                {
                    receivedPdu = new RDPGFX_START_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_ENDFRAME)
                {
                    receivedPdu = new RDPGFX_END_FRAME();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_RESETGRAPHICS)
                {
                    receivedPdu = new RDPGFX_RESET_GRAPHICS();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAPSURFACE_TO_OUTPUT();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CACHEIMPORTREPLY)
                {
                    receivedPdu = new RDPGFX_CACHE_IMPORT_REPLY();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_CAPSCONFIRM)
                {
                    receivedPdu = new RDPGFX_CAPS_CONFIRM();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_WINDOW();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_QOEFRAMEACKNOWLEDGE)
                {
                    receivedPdu = new RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDOUTPUT)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU();
                }
                else if (pdu.Header.cmdId == PacketTypeValues.RDPGFX_CMDID_MAPSURFACETOSCALEDWINDOW)
                {
                    receivedPdu = new RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU();
                }

                if (receivedPdu != null && PduMarshaler.Unmarshal(data, receivedPdu))
                {
                    return(receivedPdu);
                }
            }
            RdpegfxUnkownPdu unkown = new RdpegfxUnkownPdu();

            PduMarshaler.Unmarshal(data, unkown);
            return(unkown);
        }
        /// <summary>
        /// Method to make a map Surface to output Pdu.
        /// </summary>
        /// <param name="sid">This is used to indicate surface id.</param>
        /// <param name="x">This is used to indicate x-coordinate of the upper-left corner of the surface.</param>
        /// <param name="y">This is used to indicate y-coordinate of the upper-left corner of the surface.</param>
        public RDPGFX_MAPSURFACE_TO_OUTPUT CreateMapSurfaceToOutputPdu(ushort sid, uint x, uint y)
        {
            RDPGFX_MAPSURFACE_TO_OUTPUT surf2Output = new RDPGFX_MAPSURFACE_TO_OUTPUT(sid, x, y);

            return(surf2Output);
        }