class IcmpDecoder extends AbstractPacketDecoder<Ipv4PacketReceived, IcmpPacketReceived> implements Ipv4PacketListener {

    @Override
    public IcmpPacketReceived decode(Ipv4PacketReceived ipv4PacketReceived) {
        IcmpPacketReceivedBuilder icmpReceivedBuilder = new IcmpPacketReceivedBuilder();

        // Find the latest packet in the packet-chain, which is an
        // EthernetPacket
        List<PacketChain> packetChainList = ipv4PacketReceived.getPacketChain();
        Ipv4Packet ipv4Packet = (Ipv4Packet) packetChainList.get(packetChainList.size() - 1).getPacket();
        int bitOffset = ipv4Packet.getPayloadOffset() * NetUtils.NUM_BITS_IN_A_BYTE;
        byte[] data = ipv4PacketReceived.getPayload();

        IcmpPacketBuilder builder = new IcmpPacketBuilder();
        try {
            // Decode the ICMP type and ICMP code
            builder.setType(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 0, 8)));
            builder.setCode(BitBufferHelper.getShort(BitBufferHelper.getBits(data, bitOffset + 8, 8)));

            // Decode the checksum
            builder.setCrc(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 16, 16)));

            // Decode the identifier and sequence number
            builder.setIdentifier(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 32, 16)));
            builder.setSequenceNumber(BitBufferHelper.getInt(BitBufferHelper.getBits(data, bitOffset + 48, 16)));

            // Decode the ICMP Payload
            int payloadStartInBits = bitOffset + 64;
            int payloadEndInBits = data.length * NetUtils.NUM_BITS_IN_A_BYTE - payloadStartInBits - 4
                    * NetUtils.NUM_BITS_IN_A_BYTE;
            int start = payloadStartInBits / NetUtils.NUM_BITS_IN_A_BYTE;
            int end = start + payloadEndInBits / NetUtils.NUM_BITS_IN_A_BYTE;
            builder.setPayloadOffset(start);
            builder.setPayloadLength(end - start);
        } catch (BufferException e) {
            LOG.debug("Exception while decoding ICMP packet", e.getMessage());
        }

        // build icmp
        packetChainList.add(new PacketChainBuilder().setPacket(builder.build()).build());
        icmpReceivedBuilder.setPacketChain(packetChainList);

        // carry forward the original payload.
        icmpReceivedBuilder.setPayload(ipv4PacketReceived.getPayload());

        return icmpReceivedBuilder.build();
    }

    public  IcmpDecoder(NotificationProviderService notificationProviderService);

}