class CommandEncoder extends MessageToByteEncoder<Object> {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(CommandEncoder.class);

    private final boolean traceEnabled = logger.isTraceEnabled();

    private final boolean debugEnabled = logger.isDebugEnabled();

    public CommandEncoder() {
        this(PlatformDependent.directBufferPreferred());
    }

    public CommandEncoder(boolean preferDirect) {
        super(preferDirect);
    }

    @Override
    protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, Object msg, boolean preferDirect) throws Exception {

        if (msg instanceof Collection) {

            if (preferDirect) {
                return ctx.alloc().ioBuffer(((Collection) msg).size() * 16);
            } else {
                return ctx.alloc().heapBuffer(((Collection) msg).size() * 16);
            }
        }

        if (preferDirect) {
            return ctx.alloc().ioBuffer();
        } else {
            return ctx.alloc().heapBuffer();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {

        out.touch("CommandEncoder.encode(…)");
        if (msg instanceof RedisCommand) {
            RedisCommand<?, ?, ?> command = (RedisCommand<?, ?, ?>) msg;
            encode(ctx, out, command);
        }

        if (msg instanceof Collection) {
            Collection<RedisCommand<?, ?, ?>> commands = (Collection<RedisCommand<?, ?, ?>>) msg;
            for (RedisCommand<?, ?, ?> command : commands) {
                encode(ctx, out, command);
            }
        }
    }

    private void encode(ChannelHandlerContext ctx, ByteBuf out, RedisCommand<?, ?, ?> command) {<FILL_FUNCTION_BODY>}

    private String logPrefix(Channel channel) {
        StringBuilder buffer = new StringBuilder(64);
        buffer.append('[').append(ChannelLogDescriptor.logDescriptor(channel)).append(']');
        return buffer.toString();
    }

}


        try {
            out.markWriterIndex();
            command.encode(out);
        } catch (RuntimeException e) {
            out.resetWriterIndex();
            command.completeExceptionally(new EncoderException(
                    "Cannot encode command. Please close the connection as the connection state may be out of sync.", e));
        }

        if (debugEnabled) {
            logger.debug("{} writing command {}", logPrefix(ctx.channel()), command);
            if (traceEnabled) {
                logger.trace("{} Sent: {}", logPrefix(ctx.channel()), out.toString(Charset.defaultCharset()).trim());
            }
        }
    
<no_super_class>