@Override
 public void channelRead(final ChannelHandlerContext ctx, final Object inputObj) throws Exception {
   try {
     final ByteBuf input = (ByteBuf) inputObj;
     if (!input.isReadable()) {
       return;
     }
     final Channel channel = ctx.channel();
     receivedData.writeBytes(input);
     ProtocolVersion handshakeversion = ProtocolVersion.NOT_SET;
     receivedData.readerIndex(0);
     int firstbyte = receivedData.readUnsignedByte();
     switch (firstbyte) {
       case 0xFE:
         { // old ping
           try {
             if (receivedData.readableBytes() == 0) { // really old protocol probably
               scheduleTask(ctx, new Ping11ResponseTask(channel), 1000, TimeUnit.MILLISECONDS);
             } else if (receivedData.readUnsignedByte() == 1) {
               if (receivedData.readableBytes() == 0) {
                 // 1.5.2 probably
                 scheduleTask(
                     ctx, new Ping152ResponseTask(this, channel), 500, TimeUnit.MILLISECONDS);
               } else if ((receivedData.readUnsignedByte() == 0xFA)
                   && "MC|PingHost"
                       .equals(
                           new String(
                               Utils.toArray(
                                   receivedData.readBytes(receivedData.readUnsignedShort() * 2)),
                               StandardCharsets.UTF_16BE))) { // 1.6.*
                 receivedData.readUnsignedShort();
                 handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte());
               }
             }
           } catch (IndexOutOfBoundsException ex) {
           }
           break;
         }
       case 0x02:
         { // 1.6 or 1.5.2 handshake
           try {
             handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte());
           } catch (IndexOutOfBoundsException ex) {
           }
           break;
         }
       default:
         { // 1.7 or 1.8 handshake
           receivedData.readerIndex(0);
           ByteBuf data = getVarIntPrefixedData(receivedData);
           if (data != null) {
             handshakeversion = readNPHandshake(data);
           }
           break;
         }
     }
     // if we detected the protocol than we save it and process data
     if (handshakeversion != ProtocolVersion.NOT_SET) {
       setProtocol(channel, receivedData, handshakeversion);
     }
   } catch (Throwable t) {
     ctx.channel().close();
   } finally {
     ReferenceCountUtil.release(inputObj);
   }
 }
 private ProtocolVersion readNPHandshake(ByteBuf data) {
   if (readVarInt(data) == 0x00) {
     return ProtocolVersion.fromId(readVarInt(data));
   }
   return ProtocolVersion.UNKNOWN;
 }