@Override
    public OFMatchV3 readFrom(ChannelBuffer bb) throws OFParseError {
      int start = bb.readerIndex();
      // fixed value property type == 0x1
      short type = bb.readShort();
      if (type != (short) 0x1) throw new OFParseError("Wrong type: Expected=0x1(0x1), got=" + type);
      int length = U16.f(bb.readShort());
      if (length < MINIMUM_LENGTH)
        throw new OFParseError(
            "Wrong length: Expected to be >= " + MINIMUM_LENGTH + ", was: " + length);
      if (bb.readableBytes() + (bb.readerIndex() - start) < length) {
        // Buffer does not have all data yet
        bb.readerIndex(start);
        return null;
      }
      if (logger.isTraceEnabled()) logger.trace("readFrom - length={}", length);
      OFOxmList oxmList =
          OFOxmList.readFrom(bb, length - (bb.readerIndex() - start), OFOxmVer14.READER);
      // align message to 8 bytes (length does not contain alignment)
      bb.skipBytes(((length + 7) / 8 * 8) - length);

      OFMatchV3Ver14 matchV3Ver14 = new OFMatchV3Ver14(oxmList);
      if (logger.isTraceEnabled()) logger.trace("readFrom - read={}", matchV3Ver14);
      return matchV3Ver14;
    }