Remove deprecated deserialize() mthods from packet classes

Change-Id: I4e52ab368390d30f5f5f24d443a5021916d0c6a3
diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
index 3ec104a..103c9d3 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
@@ -564,7 +564,7 @@
 
             ARP arpPacket = (ARP) packet.getPayload();
 
-            ARP arpReply = (ARP) arpPacket.clone();
+            ARP arpReply = arpPacket.duplicate();
             arpReply.setOpCode(ARP.OP_REPLY);
 
             arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
index 85540c6..d903cd4 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
@@ -479,7 +479,7 @@
     private Ethernet processDhcpPacketFromClient(PacketContext context,
                                                  Ethernet ethernetPacket) {
         // get dhcp header.
-        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        Ethernet etherReply = ethernetPacket.duplicate();
         IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
         UDP udpPacket = (UDP) ipv4Packet.getPayload();
         DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
@@ -666,7 +666,7 @@
      */
     private Ethernet processDhcpPacketFromServer(Ethernet ethernetPacket) {
         // get dhcp header.
-        Ethernet etherReply = (Ethernet) ethernetPacket.clone();
+        Ethernet etherReply = ethernetPacket.duplicate();
         IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
         UDP udpPacket = (UDP) ipv4Packet.getPayload();
         DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
@@ -772,7 +772,7 @@
      * @return Ethernet packet processed
      */
     private Ethernet removeRelayAgentOption(Ethernet ethPacket) {
-        Ethernet ethernet = (Ethernet) ethPacket.clone();
+        Ethernet ethernet = ethPacket.duplicate();
         IPv4 ipv4 = (IPv4) ethernet.getPayload();
         UDP udp = (UDP) ipv4.getPayload();
         DHCP dhcpPayload = (DHCP) udp.getPayload();
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
index d5afdb7..a934ad8 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -785,7 +785,7 @@
 
         boolean directConnFlag = directlyConnected(clientDhcp6);
 
-        Ethernet etherReply = (Ethernet) clientPacket.clone();
+        Ethernet etherReply = clientPacket.duplicate();
         etherReply.setSourceMACAddress(relayAgentMac);
 
         if (directConnFlag && this.dhcpConnectMac == null) {
@@ -924,7 +924,7 @@
             return null;
         }
         // get dhcp6 header.
-        Ethernet etherReply = (Ethernet) receivedPacket.clone();
+        Ethernet etherReply = receivedPacket.duplicate();
         IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
         UDP udpPacket = (UDP) ipv6Packet.getPayload();
         DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
index 30c9c16..2e6ce09 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -583,7 +583,7 @@
          */
         private void processArpPacket(PacketContext context, Ethernet packet, MacAddress replyMac) {
             ARP arpPacket = (ARP) packet.getPayload();
-            ARP arpReply = (ARP) arpPacket.clone();
+            ARP arpReply = arpPacket.duplicate();
             arpReply.setOpCode(ARP.OP_REPLY);
 
             arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index bfb0701..217a981 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -192,7 +192,7 @@
                 TpPort.tpPort(patPort),
                 externalGatewayIp);
 
-        packetOut((Ethernet) eth.clone(),
+        packetOut(eth.duplicate(),
                 packetIn.receivedFrom().deviceId(),
                 patPort,
                 externalGatewayIp);
diff --git a/apps/p4-tutorial/pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java b/apps/p4-tutorial/pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java
index c783236..4c9e5f3 100644
--- a/apps/p4-tutorial/pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java
+++ b/apps/p4-tutorial/pipeconf/src/main/java/org/onosproject/p4tutorial/pipeconf/PipelineInterpreterImpl.java
@@ -19,6 +19,7 @@
 import com.google.common.collect.BiMap;
 import com.google.common.collect.ImmutableBiMap;
 import com.google.common.collect.ImmutableList;
+import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Ethernet;
 import org.onlab.util.ImmutableByteSequence;
 import org.onosproject.net.ConnectPoint;
@@ -179,9 +180,12 @@
     public InboundPacket mapInboundPacket(DeviceId deviceId, PiPacketOperation packetIn)
             throws PiInterpreterException {
         // We assume that the packet is ethernet, which is fine since default.p4 can deparse only ethernet packets.
-        Ethernet ethPkt = new Ethernet();
-
-        ethPkt.deserialize(packetIn.data().asArray(), 0, packetIn.data().size());
+        Ethernet ethPkt;
+        try {
+            ethPkt = Ethernet.deserializer().deserialize(packetIn.data().asArray(), 0, packetIn.data().size());
+        } catch (DeserializationException dex) {
+            throw new PiInterpreterException(dex.getMessage());
+        }
 
         // Returns the ingress port packet metadata.
         Optional<PiPacketMetadata> packetMetadata = packetIn.metadatas().stream()
diff --git a/core/net/src/main/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActions.java b/core/net/src/main/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActions.java
index ed78212..cdbd35c 100644
--- a/core/net/src/main/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActions.java
+++ b/core/net/src/main/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActions.java
@@ -65,7 +65,7 @@
 
     @Override
     public void forward(NeighbourMessageContext context, Interface outIntf) {
-        Ethernet packetOut = (Ethernet) context.packet().clone();
+        Ethernet packetOut = context.packet().duplicate();
         if (outIntf.vlan().equals(VlanId.NONE)) {
             // The egress interface has no VLAN Id. Send out an untagged
             // packet
diff --git a/core/net/src/test/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java b/core/net/src/test/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java
index 52b5227..40e49af 100644
--- a/core/net/src/test/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java
+++ b/core/net/src/test/java/org/onosproject/net/neighbour/impl/DefaultNeighbourMessageActionsTest.java
@@ -113,7 +113,7 @@
     public void forwardToInterface() {
         Ethernet request = NeighbourTestUtils.createArpRequest(IP1);
 
-        Ethernet forwardedRequest = (Ethernet) request.clone();
+        Ethernet forwardedRequest = request.duplicate();
         forwardedRequest.setSourceMACAddress(INTF2.mac());
         forwardedRequest.setVlanID(INTF2.vlan().toShort());
 
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java
index d069e2a..f716a63 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/DefaultP4Interpreter.java
@@ -18,6 +18,7 @@
 
 import com.google.common.collect.ImmutableBiMap;
 import com.google.common.collect.ImmutableList;
+import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Ethernet;
 import org.onlab.util.ImmutableByteSequence;
 import org.onosproject.net.ConnectPoint;
@@ -254,9 +255,12 @@
     public InboundPacket mapInboundPacket(DeviceId deviceId, PiPacketOperation packetIn)
             throws PiInterpreterException {
         // Assuming that the packet is ethernet, which is fine since default.p4 can deparse only ethernet packets.
-        Ethernet ethPkt = new Ethernet();
-
-        ethPkt.deserialize(packetIn.data().asArray(), 0, packetIn.data().size());
+        Ethernet ethPkt;
+        try {
+            ethPkt = Ethernet.deserializer().deserialize(packetIn.data().asArray(), 0, packetIn.data().size());
+        } catch (DeserializationException dex) {
+            throw new PiInterpreterException(dex.getMessage());
+        }
 
         // Returns the ingress port packet metadata.
         Optional<PiPacketMetadata> packetMetadata = packetIn.metadatas()
diff --git a/utils/misc/src/main/java/org/onlab/packet/ARP.java b/utils/misc/src/main/java/org/onlab/packet/ARP.java
index 773169b..b76ff61 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ARP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ARP.java
@@ -248,25 +248,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.hardwareType = bb.getShort();
-        this.protocolType = bb.getShort();
-        this.hardwareAddressLength = bb.get();
-        this.protocolAddressLength = bb.get();
-        this.opCode = bb.getShort();
-        this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
-        bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
-        this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
-        bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
-        this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
-        bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
-        this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
-        bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
-        return this;
-    }
 
     /*
      * (non-Javadoc)
@@ -477,6 +458,21 @@
         };
     }
 
+    /**
+     * Make an exact copy of the ARP packet.
+     *
+     * @return copy of the packet
+     */
+    public ARP duplicate() {
+        try {
+            byte[] data = serialize();
+            return deserializer().deserialize(data, 0, data.length);
+        } catch (DeserializationException dex) {
+            // If we can't make an object out of the serialized data, its a defect
+            throw new IllegalStateException(dex);
+        }
+    }
+
     @Override
     public String toString() {
         return toStringHelper(getClass())
diff --git a/utils/misc/src/main/java/org/onlab/packet/BasePacket.java b/utils/misc/src/main/java/org/onlab/packet/BasePacket.java
index c68b0aa..578086b 100644
--- a/utils/misc/src/main/java/org/onlab/packet/BasePacket.java
+++ b/utils/misc/src/main/java/org/onlab/packet/BasePacket.java
@@ -16,6 +16,9 @@
 
 package org.onlab.packet;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
 /**
  * Base packet class.
  */
@@ -84,18 +87,38 @@
         return true;
     }
 
+    /**
+     * This implementation of clone() is here to preserve backwards compatibility. Applications should not
+     * use clone() and instead use the duplicate() methods on the packet classes.
+     *
+     * @return copy of packet
+     */
     @Override
     public Object clone() {
-        IPacket pkt;
-        try {
-            pkt = this.getClass().newInstance();
-        } catch (final Exception e) {
-            throw new RuntimeException("Could not clone packet");
+
+        Class<? extends BasePacket> packetClass = this.getClass();
+        Method[] allMethods = packetClass.getDeclaredMethods();
+
+        Method deserializerFactory = null;
+        for (Method m : allMethods) {
+            String mname = m.getName();
+            if (mname.equals("deserializer")) {
+                deserializerFactory = m;
+                break;
+            }
         }
 
-        final byte[] data = this.serialize();
-        pkt.deserialize(data, 0, data.length);
-        pkt.setParent(this.parent);
-        return pkt;
+        if (deserializerFactory == null) {
+            throw new IllegalStateException("No Deserializer found for " + packetClass.getName());
+        }
+
+        byte[] data = serialize();
+        try {
+            Deserializer deserializer = (Deserializer) deserializerFactory.invoke(this);
+            return deserializer.deserialize(data, 0, data.length);
+        } catch (IllegalAccessException | InvocationTargetException | DeserializationException ex) {
+            throw new IllegalStateException(ex);
+        }
+
     }
 }
diff --git a/utils/misc/src/main/java/org/onlab/packet/DHCP.java b/utils/misc/src/main/java/org/onlab/packet/DHCP.java
index 791e970..9e6f38f 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP.java
@@ -505,16 +505,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            return null;
-        }
-    }
-
     protected void writeString(final String string, final ByteBuffer bb,
             final int maxLength) {
         if (string == null) {
diff --git a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
index f807000..054552c 100644
--- a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java
@@ -233,14 +233,6 @@
         };
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            return null;
-        }
-    }
 
     /**
      * Gets the message type of this DHCPv6 packet.
diff --git a/utils/misc/src/main/java/org/onlab/packet/Data.java b/utils/misc/src/main/java/org/onlab/packet/Data.java
index 66a8f50..2d405ca 100644
--- a/utils/misc/src/main/java/org/onlab/packet/Data.java
+++ b/utils/misc/src/main/java/org/onlab/packet/Data.java
@@ -65,13 +65,6 @@
         return this.data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        this.data = Arrays.copyOfRange(data, offset, data.length);
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/EAP.java b/utils/misc/src/main/java/org/onlab/packet/EAP.java
index bf53671..9d9dcf6 100644
--- a/utils/misc/src/main/java/org/onlab/packet/EAP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/EAP.java
@@ -232,25 +232,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.code = bb.get();
-        this.identifier = bb.get();
-        this.length = bb.getShort();
-
-        int dataLength;
-        if (this.code == REQUEST || this.code == RESPONSE) {
-            this.type = bb.get();
-            dataLength = this.length - 5;
-        } else {
-            dataLength = this.length - 4;
-        }
-        this.data = new byte[dataLength];
-        bb.get(this.data);
-        return this;
-    }
 
     @Override
     public int hashCode() {
diff --git a/utils/misc/src/main/java/org/onlab/packet/EAPOL.java b/utils/misc/src/main/java/org/onlab/packet/EAPOL.java
index 3a2aa52..741d302 100644
--- a/utils/misc/src/main/java/org/onlab/packet/EAPOL.java
+++ b/utils/misc/src/main/java/org/onlab/packet/EAPOL.java
@@ -198,26 +198,6 @@
         };
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
-        // deserialize the EAPOL header
-        this.version = bb.get();
-        this.eapolType = bb.get();
-        this.packetLength = bb.getShort();
-
-        if (this.packetLength > 0) {
-            // deserialize the EAP Payload
-            this.payload = new EAP();
-
-            this.payload = this.payload.deserialize(data, bb.position(), length - 4);
-            this.payload.setParent(this);
-        }
-
-        return this;
-    }
 
     @Override
     public String toString() {
diff --git a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
index 075066d..006c32e 100644
--- a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
+++ b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
@@ -389,80 +389,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        if (length <= 0) {
-            return null;
-        }
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        if (this.destinationMACAddress == null) {
-            this.destinationMACAddress = MacAddress.valueOf(new byte[6]);
-        }
-        final byte[] dstAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
-        bb.get(dstAddr);
-        this.destinationMACAddress = MacAddress.valueOf(dstAddr);
-
-        if (this.sourceMACAddress == null) {
-            this.sourceMACAddress = MacAddress.valueOf(new byte[6]);
-        }
-        final byte[] srcAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
-        bb.get(srcAddr);
-        this.sourceMACAddress = MacAddress.valueOf(srcAddr);
-
-        short ethType = bb.getShort();
-        if (ethType == TYPE_QINQ) {
-            final short tci = bb.getShort();
-            this.qInQPriorityCode = (byte) (tci >> 13 & 0x07);
-            this.qinqVID = (short) (tci & 0x0fff);
-            this.qinqTPID = TYPE_QINQ;
-            ethType = bb.getShort();
-        }
-
-        if (ethType == TYPE_VLAN) {
-            final short tci = bb.getShort();
-            this.priorityCode = (byte) (tci >> 13 & 0x07);
-            this.vlanID = (short) (tci & 0x0fff);
-            ethType = bb.getShort();
-
-            // there might be one more tag with 1q TPID
-            if (ethType == TYPE_VLAN) {
-                // packet is double tagged with 1q TPIDs
-                // We handle only double tagged packets here and assume that in this case
-                // TYPE_QINQ above was not hit
-                // We put the values retrieved above with TYPE_VLAN in
-                // qInQ fields
-                this.qInQPriorityCode = this.priorityCode;
-                this.qinqVID = this.vlanID;
-                this.qinqTPID = TYPE_VLAN;
-
-                final short innerTci = bb.getShort();
-                this.priorityCode = (byte) (innerTci >> 13 & 0x07);
-                this.vlanID = (short) (innerTci & 0x0fff);
-                ethType = bb.getShort();
-            }
-        } else {
-            this.vlanID = Ethernet.VLAN_UNTAGGED;
-        }
-        this.etherType = ethType;
-
-        IPacket payload;
-        Deserializer<? extends IPacket> deserializer;
-        if (Ethernet.ETHERTYPE_DESERIALIZER_MAP.containsKey(ethType)) {
-            deserializer = Ethernet.ETHERTYPE_DESERIALIZER_MAP.get(ethType);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-        return this;
-    }
-
     /**
      * Checks to see if a string is a valid MAC address.
      *
@@ -862,4 +788,19 @@
             return eth;
         };
     }
+
+    /**
+     * Make an exact copy of the ethernet packet.
+     *
+     * @return copy of the packet
+     */
+    public Ethernet duplicate() {
+        try {
+            byte[] data = serialize();
+            return deserializer().deserialize(data, 0, data.length);
+        } catch (DeserializationException dex) {
+            // If we can't make an object out of the serialized data, its a defect
+            throw new IllegalStateException(dex);
+        }
+    }
 }
diff --git a/utils/misc/src/main/java/org/onlab/packet/ICMP.java b/utils/misc/src/main/java/org/onlab/packet/ICMP.java
index 9513061..d1afcb6 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ICMP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ICMP.java
@@ -134,21 +134,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.icmpType = bb.get();
-        this.icmpCode = bb.get();
-        this.checksum = bb.getShort();
-
-        this.payload = new Data();
-        this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
-                - bb.position());
-        this.payload.setParent(this);
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/ICMP6.java b/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
index e50df26..dcde6b2 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ICMP6.java
@@ -264,31 +264,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.icmpType = bb.get();
-        this.icmpCode = bb.get();
-        this.checksum = bb.getShort();
-
-        Deserializer<? extends IPacket> deserializer;
-        if (ICMP6.TYPE_DESERIALIZER_MAP.containsKey(icmpType)) {
-            deserializer = TYPE_DESERIALIZER_MAP.get(icmpType);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                     bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/IGMP.java b/utils/misc/src/main/java/org/onlab/packet/IGMP.java
index 04308db..3395f66 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IGMP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IGMP.java
@@ -189,32 +189,6 @@
     }
 
     /**
-     * Deserialize an IGMP message.
-     *
-     * @param data bytes to deserialize
-     * @param offset offset to start deserializing from
-     * @param length length of the data to deserialize
-     * @return populated IGMP object
-     */
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-
-        final IGMP igmp;
-        try {
-            igmp = IGMP.deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            log.error("Deserialization exception", e);
-            return this;
-        }
-        this.igmpType = igmp.igmpType;
-        this.resField = igmp.resField;
-        this.checksum = igmp.checksum;
-        this.groups = igmp.groups;
-        return this;
-    }
-
-    /**
      * Deserializer function for IPv4 packets.
      *
      * @return deserializer function
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPacket.java b/utils/misc/src/main/java/org/onlab/packet/IPacket.java
index 11079f7..ed7f287 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IPacket.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IPacket.java
@@ -64,29 +64,5 @@
      */
     byte[] serialize();
 
-    /**
-     * Deserialize this packet layer and all possible payloads.
-     *
-     * NOTE: This method has been deprecated and will be removed in a future
-     * release. It is now recommended to use the Deserializer function provided
-     * by the deserialize() method on each packet to deserialize them. The
-     * Deserializer functions are robust to malformed input.
-     *
-     * @param data bytes to deserialize
-     * @param offset
-     *            offset to start deserializing from
-     * @param length
-     *            length of the data to deserialize
-     * @return the deserialized data
-     * @deprecated in Cardinal Release
-     */
-    @Deprecated
-    IPacket deserialize(byte[] data, int offset, int length);
 
-    /**
-     * Clone this packet and its payload packet but not its parent.
-     *
-     * @return the clone
-     */
-    Object clone();
 }
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPv4.java b/utils/misc/src/main/java/org/onlab/packet/IPv4.java
index 7b0ad17..bdfc5c7 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IPv4.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IPv4.java
@@ -412,55 +412,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        short sscratch;
-
-        this.version = bb.get();
-        this.headerLength = (byte) (this.version & 0xf);
-        this.version = (byte) (this.version >> 4 & 0xf);
-        this.diffServ = bb.get();
-        this.totalLength = bb.getShort();
-        this.identification = bb.getShort();
-        sscratch = bb.getShort();
-        this.flags = (byte) (sscratch >> 13 & 0x7);
-        this.fragmentOffset = (short) (sscratch & 0x1fff);
-        this.ttl = bb.get();
-        this.protocol = bb.get();
-        this.checksum = bb.getShort();
-        this.sourceAddress = bb.getInt();
-        this.destinationAddress = bb.getInt();
-
-        if (this.headerLength > 5) {
-            final int optionsLength = (this.headerLength - 5) * 4;
-            this.options = new byte[optionsLength];
-            bb.get(this.options);
-        }
-
-        if (this.totalLength != length) {
-            this.isTruncated = true;
-        } else {
-            this.isTruncated = false;
-        }
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv4.PROTOCOL_DESERIALIZER_MAP.containsKey(this.protocol)) {
-            deserializer = IPv4.PROTOCOL_DESERIALIZER_MAP.get(this.protocol);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
 
     /**
      * Accepts an IPv4 address of the form xxx.xxx.xxx.xxx, ie 192.168.0.1 and
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPv6.java b/utils/misc/src/main/java/org/onlab/packet/IPv6.java
index c455d59..9483a2b 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IPv6.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IPv6.java
@@ -235,39 +235,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        int iscratch;
-
-        iscratch = bb.getInt();
-        this.version = (byte) (iscratch >> 28 & 0xf);
-        this.trafficClass = (byte) (iscratch >> 20 & 0xff);
-        this.flowLabel = iscratch & 0xfffff;
-        this.payloadLength = bb.getShort();
-        this.nextHeader = bb.get();
-        this.hopLimit = bb.get();
-        bb.get(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
-        bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
-            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/LLC.java b/utils/misc/src/main/java/org/onlab/packet/LLC.java
index 90e09a0..cb54119 100644
--- a/utils/misc/src/main/java/org/onlab/packet/LLC.java
+++ b/utils/misc/src/main/java/org/onlab/packet/LLC.java
@@ -69,15 +69,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.dsap = bb.get();
-        this.ssap = bb.get();
-        this.ctrl = bb.get();
-        return this;
-    }
 
     /**
      * Deserializer function for LLC packets.
diff --git a/utils/misc/src/main/java/org/onlab/packet/LLDP.java b/utils/misc/src/main/java/org/onlab/packet/LLDP.java
index f2d621b..cd46eee 100644
--- a/utils/misc/src/main/java/org/onlab/packet/LLDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/LLDP.java
@@ -143,43 +143,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        LLDPTLV tlv;
-        do {
-            try {
-                tlv = new LLDPOrganizationalTLV().deserialize(bb);
-            } catch (DeserializationException e) {
-                break;
-            }
-
-            // if there was a failure to deserialize stop processing TLVs
-            if (tlv == null) {
-                break;
-            }
-            switch (tlv.getType()) {
-                case 0x0:
-                    // can throw this one away, its just an end delimiter
-                    break;
-                case 0x1:
-                    this.chassisId = tlv;
-                    break;
-                case 0x2:
-                    this.portId = tlv;
-                    break;
-                case 0x3:
-                    this.ttl = tlv;
-                    break;
-
-                default:
-                    this.optionalTLVList.add(tlv);
-                    break;
-            }
-        } while (tlv.getType() != 0 && bb.hasRemaining());
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/MPLS.java b/utils/misc/src/main/java/org/onlab/packet/MPLS.java
index ba592c5..948075b 100644
--- a/utils/misc/src/main/java/org/onlab/packet/MPLS.java
+++ b/utils/misc/src/main/java/org/onlab/packet/MPLS.java
@@ -71,31 +71,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
-        int mplsheader = bb.getInt();
-        this.label = ((mplsheader & 0xfffff000) >> 12);
-        this.bos = (byte) ((mplsheader & 0x00000100) >> 8);
-        this.bos = (byte) (mplsheader & 0x000000ff);
-        this.protocol = (this.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
-
-        Deserializer<? extends IPacket> deserializer;
-        if (protocolDeserializerMap.containsKey(this.protocol)) {
-            deserializer = protocolDeserializerMap.get(this.protocol);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
 
     /**
      * Returns the MPLS label.
diff --git a/utils/misc/src/main/java/org/onlab/packet/PIM.java b/utils/misc/src/main/java/org/onlab/packet/PIM.java
index 68cfe34..f930e3a 100644
--- a/utils/misc/src/main/java/org/onlab/packet/PIM.java
+++ b/utils/misc/src/main/java/org/onlab/packet/PIM.java
@@ -242,28 +242,7 @@
         return data;
     }
 
-    /**
-     * Deserialize the PIM packet.
-     *
-     * @param data bytes to deserialize.
-     * @param offset offset to start deserializing from
-     * @param length length of the data to deserialize
-     *
-     * @return the deserialized PIM packet.
-     */
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-            final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.type = bb.get();
-        this.version = bb.get();
-        this.checksum = bb.getShort();
 
-        //this.payload = new Data();
-        this.payload = this.payload.deserialize(data, bb.position(), bb.limit() - bb.position());
-        this.payload.setParent(this);
-        return this;
-    }
     /**
      * Deserializer function for IPv4 packets.
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/RADIUS.java b/utils/misc/src/main/java/org/onlab/packet/RADIUS.java
index 0a2b220..fff2276 100644
--- a/utils/misc/src/main/java/org/onlab/packet/RADIUS.java
+++ b/utils/misc/src/main/java/org/onlab/packet/RADIUS.java
@@ -275,7 +275,7 @@
             }
         }
         // Assembling EAP object from the concatenated stream
-        message.deserialize(messageStream.toByteArray(), 0, messageStream.size());
+        //message.deserialize(messageStream.toByteArray(), 0, messageStream.size());
         return message;
     }
 
@@ -398,28 +398,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.code = bb.get();
-        this.identifier = bb.get();
-        this.length = bb.getShort();
-        bb.get(this.authenticator, 0, 16);
-
-        int remainingLength = this.length - RADIUS_MIN_LENGTH;
-        while (remainingLength > 0 && bb.hasRemaining()) {
-            RADIUSAttribute attr = new RADIUSAttribute();
-            attr.setType(bb.get());
-            attr.setLength(bb.get());
-            short attrLength = (short) (attr.length & 0xff);
-            attr.value = new byte[attrLength - 2];
-            bb.get(attr.value, 0, attrLength - 2);
-            this.attributes.add(attr);
-            remainingLength -= attr.length;
-        }
-        return this;
-    }
 
     @Override
     public String toString() {
diff --git a/utils/misc/src/main/java/org/onlab/packet/TCP.java b/utils/misc/src/main/java/org/onlab/packet/TCP.java
index 1c84324..735a415 100644
--- a/utils/misc/src/main/java/org/onlab/packet/TCP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/TCP.java
@@ -346,39 +346,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.sourcePort = (bb.getShort() & 0xffff);
-        this.destinationPort = (bb.getShort() & 0xffff);
-        this.sequence = bb.getInt();
-        this.acknowledge = bb.getInt();
-        this.flags = bb.getShort();
-        this.dataOffset = (byte) (this.flags >> 12 & 0xf);
-        this.flags = (short) (this.flags & 0x1ff);
-        this.windowSize = bb.getShort();
-        this.checksum = bb.getShort();
-        this.urgentPointer = bb.getShort();
-        if (this.dataOffset > 5) {
-            int optLength = (this.dataOffset << 2) - 20;
-            if (bb.limit() < bb.position() + optLength) {
-                optLength = bb.limit() - bb.position();
-            }
-            try {
-                this.options = new byte[optLength];
-                bb.get(this.options, 0, optLength);
-            } catch (final IndexOutOfBoundsException e) {
-                this.options = null;
-            }
-        }
-
-        this.payload = new Data();
-        this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
-                - bb.position());
-        this.payload.setParent(this);
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/UDP.java b/utils/misc/src/main/java/org/onlab/packet/UDP.java
index 89638be..9f51713 100644
--- a/utils/misc/src/main/java/org/onlab/packet/UDP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/UDP.java
@@ -195,34 +195,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.sourcePort = (bb.getShort() & 0xffff);
-        this.destinationPort = (bb.getShort() & 0xffff);
-        this.length = bb.getShort();
-        this.checksum = bb.getShort();
-
-        Deserializer<? extends IPacket> deserializer;
-        if (UDP.PORT_DESERIALIZER_MAP.containsKey(this.destinationPort)) {
-            deserializer = UDP.PORT_DESERIALIZER_MAP.get(this.destinationPort);
-        } else if (UDP.PORT_DESERIALIZER_MAP.containsKey(this.sourcePort)) {
-            deserializer = UDP.PORT_DESERIALIZER_MAP.get(this.sourcePort);
-        } else {
-            deserializer = Data.deserializer();
-        }
-
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                   bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/VXLAN.java b/utils/misc/src/main/java/org/onlab/packet/VXLAN.java
index e4325cd..9e451c6 100644
--- a/utils/misc/src/main/java/org/onlab/packet/VXLAN.java
+++ b/utils/misc/src/main/java/org/onlab/packet/VXLAN.java
@@ -62,32 +62,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
-        if (bb.remaining() < VXLAN_HEADER_LENGTH) {
-            return this;
-        }
-
-        this.flags = bb.get();
-        bb.get(this.rsvd1);
-        bb.get(this.vni);
-        this.rsvd2 = bb.get();
-
-        Deserializer<? extends IPacket> deserializer = Data.deserializer();
-
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-        return this;
-    }
-
     /**
      * Returns VNI(VXLAN Network Identifier).
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Duid.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Duid.java
index df5e4d4..c8ca3bd 100644
--- a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Duid.java
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Duid.java
@@ -19,9 +19,7 @@
 
 import com.google.common.base.MoreObjects;
 import org.onlab.packet.BasePacket;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
@@ -146,14 +144,7 @@
         return byteBuffer.array();
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            throw new RuntimeException("Can't deserialize duid due to {}", e);
-        }
-    }
+
 
     public static Deserializer<Dhcp6Duid> deserializer() {
         return (data, offset, length) -> {
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Option.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Option.java
index 597732d..f19f735 100644
--- a/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Option.java
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/Dhcp6Option.java
@@ -21,7 +21,6 @@
 import org.onlab.packet.Data;
 import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 
 import java.nio.ByteBuffer;
 import java.util.Objects;
@@ -147,14 +146,6 @@
         return bb.array();
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            throw new RuntimeException("Can't deserialize data for DHCPv6 option.", e);
-        }
-    }
 
     protected ToStringHelper getToStringHelper() {
         return toStringHelper(Dhcp6Option.class)
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpOption.java
index 76f768f..93e9aac 100644
--- a/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpOption.java
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpOption.java
@@ -17,9 +17,7 @@
 package org.onlab.packet.dhcp;
 
 import org.onlab.packet.BasePacket;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
@@ -55,15 +53,6 @@
         return byteBuffer.array();
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            log.warn("Can't deserialize DhcpOption {}", e);
-            return null;
-        }
-    }
 
     /**
      * Deserializer function for DHCP option.
diff --git a/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpRelayAgentOption.java b/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpRelayAgentOption.java
index adda088..08f488d 100644
--- a/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpRelayAgentOption.java
+++ b/utils/misc/src/main/java/org/onlab/packet/dhcp/DhcpRelayAgentOption.java
@@ -17,9 +17,7 @@
 package org.onlab.packet.dhcp;
 
 import com.google.common.collect.Maps;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
@@ -77,15 +75,7 @@
         return byteBuffer.array();
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        try {
-            return deserializer().deserialize(data, offset, length);
-        } catch (DeserializationException e) {
-            log.warn("can't deserialize DHCP relay agent information option {}", e);
-            return null;
-        }
-    }
+
 
     /**
      * Deserializer function for DHCP relay agent option.
diff --git a/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java b/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java
index a6e277a..1cee5be 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ipv6/Authentication.java
@@ -18,7 +18,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
@@ -180,36 +179,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.nextHeader = bb.get();
-        this.payloadLength = bb.get();
-        bb.getShort();
-        this.securityParamIndex = bb.getInt();
-        this.sequence = bb.getInt();
-        int icvLength = getTotalLength() - FIXED_HEADER_LENGTH;
-        this.integrityCheck = new byte[icvLength];
-        bb.get(this.integrityCheck, 0, icvLength);
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
-            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
-        } else {
-            deserializer = Data.deserializer();
-        }
-
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                              bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java b/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java
index 6a9f188..d6c49e1 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ipv6/BaseOptions.java
@@ -18,7 +18,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
@@ -147,33 +146,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.nextHeader = bb.get();
-        this.headerExtLength = bb.get();
-        int optionLength =
-                FIXED_OPTIONS_LENGTH + LENGTH_UNIT * this.headerExtLength;
-        this.options = new byte[optionLength];
-        bb.get(this.options, 0, optionLength);
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
-            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java b/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java
index d8b50ba..a1e1195 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ipv6/EncapSecurityPayload.java
@@ -19,7 +19,6 @@
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Data;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
 
 import java.nio.ByteBuffer;
@@ -110,20 +109,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.securityParamIndex = bb.getInt();
-        this.sequence = bb.getInt();
-
-        this.payload = new Data();
-        this.payload.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-        this.payload.setParent(this);
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java b/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java
index a03b4e7..112e43e 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ipv6/Fragment.java
@@ -18,7 +18,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
@@ -144,32 +143,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.nextHeader = bb.get();
-        bb.get();
-        short sscratch = bb.getShort();
-        this.fragmentOffset = (short) (sscratch >> 3 & 0x1fff);
-        this.moreFragment = (byte) (sscratch & 0x1);
-        this.identification = bb.getInt();
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
-            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
-        } else {
-            deserializer = Data.deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
 
     /*
     * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java b/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java
index cc658b7..7f8a0d6 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ipv6/Routing.java
@@ -18,7 +18,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Data;
-import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
@@ -169,35 +168,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.nextHeader = bb.get();
-        this.headerExtLength = bb.get();
-        this.routingType = bb.get();
-        this.segmentsLeft = bb.get();
-        int dataLength =
-                FIXED_ROUTING_DATA_LENGTH + LENGTH_UNIT * this.headerExtLength;
-        this.routingData = new byte[dataLength];
-        bb.get(this.routingData, 0, dataLength);
-
-        Deserializer<? extends IPacket> deserializer;
-        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
-            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
-        } else {
-            deserializer = new Data().deserializer();
-        }
-        try {
-            this.payload = deserializer.deserialize(data, bb.position(),
-                                                    bb.limit() - bb.position());
-            this.payload.setParent(this);
-        } catch (DeserializationException e) {
-            return this;
-        }
-
-        return this;
-    }
-
     /*
      * (non-Javadoc)
      *
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java
index 77dd409..77c360a 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborAdvertisement.java
@@ -19,7 +19,6 @@
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.ICMP6;
-import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
 import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
@@ -181,22 +180,7 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        int iscratch;
 
-        iscratch = bb.getInt();
-        this.routerFlag = (byte) (iscratch >> 31 & 0x1);
-        this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
-        this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
-        bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
-        this.options.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java
index ebc378e..d6b1df0 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborDiscoveryOptions.java
@@ -15,12 +15,11 @@
  */
 package org.onlab.packet.ndp;
 
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
 
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -189,40 +188,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
-        options.clear();
-
-        //
-        // Deserialize all options
-        //
-        while (bb.hasRemaining()) {
-            byte type = bb.get();
-            if (!bb.hasRemaining()) {
-                break;
-            }
-            byte lengthField = bb.get();
-            int dataLength = lengthField * 8;   // The data length field is in
-            // unit of 8 octets
-
-            // Exclude the type and length fields
-            if (dataLength < 2) {
-                break;
-            }
-            dataLength -= 2;
-
-            if (bb.remaining() < dataLength) {
-                break;
-            }
-            byte[] optionData = new byte[dataLength];
-            bb.get(optionData, 0, optionData.length);
-            addOption(type, optionData);
-        }
-
-        return this;
-    }
 
     @Override
     public int hashCode() {
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
index 06a5339..51018e4 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/NeighborSolicitation.java
@@ -19,7 +19,6 @@
 import org.onlab.packet.Deserializer;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.ICMP6;
-import org.onlab.packet.IPacket;
 import org.onlab.packet.IPv6;
 import org.onlab.packet.Ip6Address;
 import org.onlab.packet.MacAddress;
@@ -114,18 +113,7 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
 
-        bb.getInt();
-        bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-
-        this.options.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java b/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java
index 15f68a0..ad5e9dc 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/Redirect.java
@@ -17,7 +17,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 import org.onlab.packet.Ip6Address;
 
 import java.nio.ByteBuffer;
@@ -127,19 +126,7 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
 
-        bb.getInt();
-        bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
-        bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);
-
-        this.options.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java b/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java
index 8582dae..bd0f8a0 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/RouterAdvertisement.java
@@ -17,7 +17,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 
 import java.nio.ByteBuffer;
 import java.util.List;
@@ -210,24 +209,7 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        int bscratch;
 
-        this.currentHopLimit = bb.get();
-        bscratch = bb.get();
-        this.mFlag = (byte) ((bscratch >> 7) & 0x1);
-        this.oFlag = (byte) ((bscratch >> 6) & 0x1);
-        this.routerLifetime = bb.getShort();
-        this.reachableTime = bb.getInt();
-        this.retransmitTimer = bb.getInt();
-
-        this.options.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java b/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java
index 116b8cb..902529c 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ndp/RouterSolicitation.java
@@ -17,7 +17,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 
 import java.nio.ByteBuffer;
 import java.util.List;
@@ -78,17 +77,6 @@
         return data;
     }
 
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-
-        bb.getInt();
-
-        this.options.deserialize(data, bb.position(),
-                                 bb.limit() - bb.position());
-
-        return this;
-    }
 
     /*
      * (non-Javadoc)
diff --git a/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java b/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java
index dadddcc..805748d 100644
--- a/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java
+++ b/utils/misc/src/main/java/org/onlab/packet/pim/PIMJoinPrune.java
@@ -17,7 +17,6 @@
 
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.Deserializer;
-import org.onlab.packet.IPacket;
 import org.onlab.packet.IpPrefix;
 
 import java.nio.ByteBuffer;
@@ -180,13 +179,7 @@
         return data2;
     }
 
-    // TODO: I suppose I really need to implement this?
-    @Override
-    public IPacket deserialize(final byte[] data, final int offset,
-                               final int length) {
-        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        return this;
-    }
+
 
     /**
      * Return the J/P deserializer function.
diff --git a/utils/misc/src/test/java/org/onlab/packet/BasePacketTest.java b/utils/misc/src/test/java/org/onlab/packet/BasePacketTest.java
new file mode 100644
index 0000000..61c9fcc
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/packet/BasePacketTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onlab.packet;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+public class BasePacketTest {
+
+    @Test
+    public void testClone() {
+        Ethernet p1 = new Ethernet();
+        p1.sourceMACAddress = MacAddress.ONOS;
+        p1.destinationMACAddress = MacAddress.ZERO;
+        p1.payload = new Data("xyzzy".getBytes());
+        BasePacket copy1 = (BasePacket) p1.clone();
+        assertThat(p1, equalTo(copy1));
+    }
+
+}
\ No newline at end of file