@Override
    public void encode(final ChannelHandlerContext context, final DatabasePacket message, final ByteBuf out) {
        MySQLPacketPayload payload = new MySQLPacketPayload(prepareMessageHeader(out).markWriterIndex(), context.channel().attr(CommonConstants.CHARSET_ATTRIBUTE_KEY).get());
        try {
            message.write(payload);
            // CHECKSTYLE:OFF
        } catch (final RuntimeException ex) {
            // CHECKSTYLE:ON
            out.resetWriterIndex();
            new MySQLErrPacket(new UnknownSQLException(ex).toSQLException()).write(payload);
        } finally {
            if (out.readableBytes() - PAYLOAD_LENGTH - SEQUENCE_LENGTH < MAX_PACKET_LENGTH) {
                updateMessageHeader(out, context.channel().attr(MySQLConstants.SEQUENCE_ID_ATTRIBUTE_KEY).get().getAndIncrement());
            } else {
                writeMultiPackets(context, out);
            }
        }
    }
@Test
    void assertEncodePacketMoreThan16MB() {
        CompositeByteBuf expected = new CompositeByteBuf(UnpooledByteBufAllocator.DEFAULT, false, 6);
        when(context.alloc().compositeBuffer(6)).thenReturn(expected);
        when(context.alloc().ioBuffer(4, 4)).thenReturn(Unpooled.buffer(4, 4), Unpooled.buffer(4, 4), Unpooled.buffer(4, 4));
        MySQLPacketCodecEngine engine = new MySQLPacketCodecEngine();
        engine.encode(context, mock(MySQLPacket.class), prepareByteBufAlmost32MB());
        verify(context).write(expected);
        assertThat(expected.numComponents(), is(5));
        assertThat(expected.component(0).getUnsignedByte(3), is((short) 0));
        assertThat(expected.component(1).readableBytes(), is(0xFFFFFF));
        assertThat(expected.component(2).getUnsignedByte(3), is((short) 1));
        assertThat(expected.component(3).readableBytes(), is(0xFFFFFF));
        assertThat(expected.component(4).getUnsignedByte(3), is((short) 2));
    }