/// <summary>
        /// Dump message-pack binary to JSON string.
        /// </summary>
        public static string ToJson(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return("");
            }

            int readSize;

            if (MessagePackBinary.GetMessagePackType(bytes, 0) == MessagePackType.Extension)
            {
                var header = MessagePackBinary.ReadExtensionFormatHeader(bytes, 0, out readSize);
                if (header.TypeCode == ExtensionTypeCode)
                {
                    // decode lz4
                    var offset = readSize;
                    var length = MessagePackBinary.ReadInt32(bytes, offset, out readSize);
                    offset += readSize;

                    var buffer = LZ4MemoryPool.GetBuffer();
                    if (buffer.Length < length)
                    {
                        buffer = new byte[length];
                    }

                    // LZ4 Decode
                    LZ4Codec.Decode(bytes, offset, bytes.Length - offset, buffer, 0, length);

                    bytes = buffer; // use LZ4 bytes
                }
            }

            var sb = new StringBuilder();

            ToJsonCore(bytes, 0, sb);
            return(sb.ToString());
        }
        static T DeserializeCore <T>(ArraySegment <byte> bytes, IFormatterResolver resolver)
        {
            if (resolver == null)
            {
                resolver = MessagePackSerializer.DefaultResolver;
            }
            var formatter = resolver.GetFormatterWithVerify <T>();

            int readSize;

            if (MessagePackBinary.GetMessagePackType(bytes.Array, bytes.Offset) == MessagePackType.Extension)
            {
                var header = MessagePackBinary.ReadExtensionFormatHeader(bytes.Array, bytes.Offset, out readSize);
                if (header.TypeCode == ExtensionTypeCode)
                {
                    // decode lz4
                    var offset = bytes.Offset + readSize;
                    var length = MessagePackBinary.ReadInt32(bytes.Array, offset, out readSize);
                    offset += readSize;

                    var buffer = LZ4MemoryPool.GetBuffer(); // use LZ4 Pool
                    if (buffer.Length < length)
                    {
                        buffer = new byte[length];
                    }

                    // LZ4 Decode
                    var len = bytes.Count + bytes.Offset - offset;
                    LZ4Codec.Decode(bytes.Array, offset, len, buffer, 0, length);

                    return(formatter.Deserialize(buffer, 0, resolver, out readSize));
                }
            }

            return(formatter.Deserialize(bytes.Array, bytes.Offset, resolver, out readSize));
        }