class MySQLNegotiateHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
        if (msg instanceof HandshakeInitializationPacket) {
            HandshakeInitializationPacket handshake = (HandshakeInitializationPacket) msg;
            ClientAuthenticationPacket clientAuth = new ClientAuthenticationPacket();
            clientAuth.setSequenceNumber((byte) (handshake.getSequenceNumber() + 1));
            clientAuth.setCharsetNumber((byte) 33);
            clientAuth.setUsername(username);
            clientAuth.setPassword(password);
            clientAuth.setServerCapabilities(handshake.getServerCapabilities());
            // use default database
            clientAuth.setDatabaseName("mysql");
            clientAuth.setAuthPluginData(joinAndCreateAuthPluginData(handshake));
            clientAuth.setAuthPluginName(handshake.getAuthPluginName());
            ctx.channel().writeAndFlush(clientAuth);
            serverInfo = new ServerInfo();
            serverInfo.setServerVersion(new ServerVersion(handshake.getServerVersion()));
            return;
        }
        if (msg instanceof OkPacket) {
            ctx.channel().pipeline().remove(this);
            authResultCallback.setSuccess(serverInfo);
            return;
        }
        ErrorPacket error = (ErrorPacket) msg;
        ctx.channel().close();
        throw new RuntimeException(error.getMessage());
    }

}