class NettyEncoder extends OneToOneEncoder {
    private Codec codec;
    private com.weibo.api.motan.transport.Channel client;

    public NettyEncoder(Codec codec, com.weibo.api.motan.transport.Channel client) {
        this.codec = codec;
        this.client = client;
    }

    @Override
    protected Object encode(ChannelHandlerContext ctx, Channel nettyChannel, Object message) throws Exception {
        byte[] data = encodeMessage(message);
        ChannelBuffer channelBuffer;
        short type = ByteUtil.bytes2short(data, 0);
        if (type == DefaultRpcCodec.MAGIC) {
            channelBuffer = encodeV1(message, data);
        } else if (type == MotanV2Header.MAGIC) {
            channelBuffer = encodeV2(data);
        } else {
            throw new MotanFrameworkException("can not encode message, unknown magic:" + type);
        }
        if (message instanceof Request) {
            Request request = (Request) message;
            MotanFrameworkUtil.logEvent(request, MotanConstants.TRACE_CENCODE);
            request.setAttachment(MotanConstants.CONTENT_LENGTH, String.valueOf(channelBuffer.readableBytes()));
        } else if (message instanceof Response) {
            Response response = (Response) message;
            MotanFrameworkUtil.logEvent(response, MotanConstants.TRACE_SENCODE);
            response.setAttachment(MotanConstants.CONTENT_LENGTH, String.valueOf(channelBuffer.readableBytes()));
        }
        return channelBuffer;
    }


    private ChannelBuffer encodeV2(byte[] data) throws Exception {
        return ChannelBuffers.wrappedBuffer(data);
    }

    private ChannelBuffer encodeV1(Object message, byte[] data) throws Exception {
        long requestId = getRequestId(message);
        byte[] transportHeader = new byte[MotanConstants.NETTY_HEADER];
        ByteUtil.short2bytes(MotanConstants.NETTY_MAGIC_TYPE, transportHeader, 0);
        transportHeader[3] = getType(message);
        ByteUtil.long2bytes(requestId, transportHeader, 4);
        ByteUtil.int2bytes(data.length, transportHeader, 12);
        return ChannelBuffers.wrappedBuffer(transportHeader, data);
    }

    private byte[] encodeMessage(Object message) throws IOException {
        byte[] data = null;
        if (message instanceof Response) {
            try {
                data = codec.encode(client, message);
            } catch (Exception e) {
                LoggerUtil.error("NettyEncoder encode error, identity=" + client.getUrl().getIdentity(), e);
                long requestId = getRequestId(message);
                Response response = MotanFrameworkUtil.buildErrorResponse(requestId, ((Response) message).getRpcProtocolVersion(), e);
                data = codec.encode(client, response);
            }
        } else {
            data = codec.encode(client, message);
        }
        return data;
    }

    private long getRequestId(Object message) {
        if (message instanceof Request) {
            return ((Request) message).getRequestId();
        } else if (message instanceof Response) {
            return ((Response) message).getRequestId();
        } else {
            return 0;
        }
    }

    private byte getType(Object message) {<FILL_FUNCTION_BODY>}
}

        if (message instanceof Request) {
            return MotanConstants.FLAG_REQUEST;
        } else if (message instanceof Response) {
            return MotanConstants.FLAG_RESPONSE;
        } else {
            return MotanConstants.FLAG_OTHER;
        }
    
<no_super_class>