Cleanup the implementation of class TopologyEvent and associated classes.

The major addition is the new method TopologyEvent.getEventType() that
returns the type of the event: SWITCH, PORT, LINK, HOST, MASTERSHIP

* Refactor and move around the implementation of methods like
  hashCode() equals() and toString()

* Remove method getID() from classes MastershipEvent, SwitchEvent, PortEvent
  LinkEvent, HostEvent, and keep it only in TopologyEvent where it is
  actually needed.

* Changed class TopologyElement to abstract, and added two abstract
  methods: getOriginDpid() and getIDasByteBuffer() which are already
  implemented by all FooEvent derived classes.

No functional changes.

Change-Id: I62f4723cb3f4b519f365c04e7b736abda9b1973b
diff --git a/src/main/java/net/onrc/onos/core/topology/HostEvent.java b/src/main/java/net/onrc/onos/core/topology/HostEvent.java
index 33f8db8..86d1751 100644
--- a/src/main/java/net/onrc/onos/core/topology/HostEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/HostEvent.java
@@ -109,11 +109,13 @@
         this.lastSeenTime = lastSeenTime;
     }
 
-    /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
+    // Assuming mac is unique cluster-wide
+    public static ByteBuffer getHostID(final byte[] mac) {
+        return (ByteBuffer) ByteBuffer.allocate(2 + mac.length)
+                .putChar('H').put(mac).flip();
+    }
+
+    @Override
     public Dpid getOriginDpid() {
         // TODO: Eventually, we should return a collection of Dpid values
         for (SwitchPort sp : attachmentPoints) {
@@ -123,56 +125,38 @@
     }
 
     @Override
-    public String toString() {
-        return "[HostEvent " + mac + " attachmentPoints:" + attachmentPoints + "]";
+    public ByteBuffer getIDasByteBuffer() {
+        return getHostID(mac.toBytes());
     }
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = super.hashCode();
-        result = prime * result
-                + ((attachmentPoints == null) ? 0 : attachmentPoints.hashCode());
-        result = prime * result + ((mac == null) ? 0 : mac.hashCode());
-        return result;
+        return 31 * super.hashCode() + Objects.hash(attachmentPoints, mac);
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
+    public boolean equals(Object o) {
+        if (this == o) {
             return true;
         }
 
-        if (obj == null) {
+        if (o == null || getClass() != o.getClass()) {
             return false;
         }
 
-        if (getClass() != obj.getClass()) {
+        // Compare attributes
+        if (!super.equals(o)) {
             return false;
         }
 
-        if (!super.equals(obj)) {
-            return false;
-        }
-
-        HostEvent other = (HostEvent) obj;
-
+        HostEvent other = (HostEvent) o;
         // XXX lastSeenTime excluded from Equality condition, is it OK?
         return Objects.equals(mac, other.mac) &&
                 Objects.equals(this.attachmentPoints, other.attachmentPoints);
     }
 
-    // Assuming mac is unique cluster-wide
-    public static ByteBuffer getHostID(final byte[] mac) {
-        return (ByteBuffer) ByteBuffer.allocate(2 + mac.length)
-                .putChar('H').put(mac).flip();
-    }
-
-    public byte[] getID() {
-        return getHostID(mac.toBytes()).array();
-    }
-
-    public ByteBuffer getIDasByteBuffer() {
-        return getHostID(mac.toBytes());
+    @Override
+    public String toString() {
+        return "[HostEvent " + mac + " attachmentPoints:" + attachmentPoints + "]";
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/ITopologyElement.java b/src/main/java/net/onrc/onos/core/topology/ITopologyElement.java
index 277c957..3664d98 100644
--- a/src/main/java/net/onrc/onos/core/topology/ITopologyElement.java
+++ b/src/main/java/net/onrc/onos/core/topology/ITopologyElement.java
@@ -27,6 +27,4 @@
      * @return  AdminStatus
      */
     public AdminStatus getStatus();
-
-
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/LinkEvent.java b/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
index 807dcaf..bc5aa93 100644
--- a/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/LinkEvent.java
@@ -122,20 +122,6 @@
         this.capacity = capacity;
     }
 
-    /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
-    public Dpid getOriginDpid() {
-        return this.id.getDst().getDpid();
-    }
-
-    @Override
-    public String toString() {
-        return "[LinkEvent " + getSrc() + "->" + getDst() + "]";
-    }
-
     public static final int LINKID_BYTES = 2 + PortEvent.PORTID_BYTES * 2;
 
     public static ByteBuffer getLinkID(Dpid srcDpid, PortNumber srcPortNo,
@@ -152,10 +138,12 @@
                 .put(PortEvent.getPortID(dstDpid, dstPortNo)).flip();
     }
 
-    public byte[] getID() {
-        return getIDasByteBuffer().array();
+    @Override
+    public Dpid getOriginDpid() {
+        return this.id.getDst().getDpid();
     }
 
+    @Override
     public ByteBuffer getIDasByteBuffer() {
         return getLinkID(getSrc().getDpid(), getSrc().getPortNumber(),
                 getDst().getDpid(), getDst().getPortNumber());
@@ -163,32 +151,30 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = super.hashCode();
-        result = prime * result + Objects.hashCode(id);
-        return result;
+        return 31 * super.hashCode() + Objects.hashCode(id);
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
+    public boolean equals(Object o) {
+        if (this == o) {
             return true;
         }
 
-        if (obj == null) {
+        if (o == null || getClass() != o.getClass()) {
             return false;
         }
 
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        LinkEvent other = (LinkEvent) obj;
-
-        // compare attributes
-        if (!super.equals(obj)) {
+        // Compare attributes
+        if (!super.equals(o)) {
             return false;
         }
 
+        LinkEvent other = (LinkEvent) o;
         return Objects.equals(this.id, other.id);
     }
+
+    @Override
+    public String toString() {
+        return "[LinkEvent " + getSrc() + "->" + getDst() + "]";
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/MastershipEvent.java b/src/main/java/net/onrc/onos/core/topology/MastershipEvent.java
index 589174d..1d54a52 100644
--- a/src/main/java/net/onrc/onos/core/topology/MastershipEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/MastershipEvent.java
@@ -89,28 +89,16 @@
         return role;
     }
 
-    /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
+    @Override
     public Dpid getOriginDpid() {
         return this.dpid;
     }
 
     @Override
-    public String toString() {
-        return "[MastershipEvent " + getDpid() + "@" + getOnosInstanceId() +
-            "->" + getRole() + "]";
-    }
-
-    public byte[] getID() {
-        String keyStr = "M" + getDpid() + "@" + getOnosInstanceId();
-        return keyStr.getBytes(StandardCharsets.UTF_8);
-    }
-
     public ByteBuffer getIDasByteBuffer() {
-        ByteBuffer buf = ByteBuffer.wrap(getID());
+        String keyStr = "M" + getDpid() + "@" + getOnosInstanceId();
+        byte[] id = keyStr.getBytes(StandardCharsets.UTF_8);
+        ByteBuffer buf = ByteBuffer.wrap(id);
         return buf;
     }
 
@@ -124,30 +112,32 @@
      * MastershipEvent objects are equal if they have same DPID and same
      * ONOS Instance ID.
      *
-     * @param obj another object to compare to this
-     * @return true if equal, false otherwise false.
+     * @param o another object to compare to this.
+     * @return true if equal, false otherwise.
      */
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
+    public boolean equals(Object o) {
+        if (this == o) {
             return true;
         }
 
-        if (obj == null) {
+        if (o == null || getClass() != o.getClass()) {
             return false;
         }
 
-        if (getClass() != obj.getClass()) {
+        // Compare attributes
+        if (!super.equals(o)) {
             return false;
         }
 
-        // compare attributes
-        if (!super.equals(obj)) {
-            return false;
-        }
+        MastershipEvent other = (MastershipEvent) o;
+        return Objects.equals(dpid, other.dpid) &&
+            Objects.equals(onosInstanceId, other.onosInstanceId);
+    }
 
-        MastershipEvent other = (MastershipEvent) obj;
-        return dpid.equals(other.dpid) &&
-            onosInstanceId.equals(other.onosInstanceId);
+    @Override
+    public String toString() {
+        return "[MastershipEvent " + getDpid() + "@" + getOnosInstanceId() +
+            "->" + getRole() + "]";
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/PortEvent.java b/src/main/java/net/onrc/onos/core/topology/PortEvent.java
index 9907a19..b4b0b1b 100644
--- a/src/main/java/net/onrc/onos/core/topology/PortEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/PortEvent.java
@@ -95,48 +95,6 @@
         return id.getPortNumber();
     }
 
-    /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
-    public Dpid getOriginDpid() {
-        return this.id.getDpid();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        if (getClass() != o.getClass()) {
-            return false;
-        }
-        PortEvent other = (PortEvent) o;
-
-        // compare attributes
-        if (!super.equals(o)) {
-            return false;
-        }
-
-        return Objects.equals(this.id, other.id);
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * super.hashCode() + Objects.hashCode(id);
-    }
-
-    @Override
-    public String toString() {
-        return "[PortEvent " + getDpid() + "@" + getPortNumber() + "]";
-    }
-
     public static final int PORTID_BYTES = SwitchEvent.SWITCHID_BYTES + 2 + 8;
 
     public static ByteBuffer getPortID(Dpid dpid, PortNumber number) {
@@ -157,11 +115,42 @@
                 .putChar('P').putLong(number).flip();
     }
 
-    public byte[] getID() {
-        return getIDasByteBuffer().array();
+    @Override
+    public Dpid getOriginDpid() {
+        return this.id.getDpid();
     }
 
+    @Override
     public ByteBuffer getIDasByteBuffer() {
         return getPortID(getDpid(), getPortNumber());
     }
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + Objects.hashCode(id);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        // Compare attributes
+        if (!super.equals(o)) {
+            return false;
+        }
+
+        PortEvent other = (PortEvent) o;
+        return Objects.equals(this.id, other.id);
+    }
+
+    @Override
+    public String toString() {
+        return "[PortEvent " + getDpid() + "@" + getPortNumber() + "]";
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java b/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
index 47f8e81..ad078c6 100644
--- a/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/SwitchEvent.java
@@ -56,48 +56,6 @@
         return dpid;
     }
 
-    /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
-    public Dpid getOriginDpid() {
-        return this.dpid;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        if (getClass() != o.getClass()) {
-            return false;
-        }
-        SwitchEvent other = (SwitchEvent) o;
-
-        // compare attributes
-        if (!super.equals(o)) {
-            return false;
-        }
-
-        return Objects.equals(this.dpid, other.dpid);
-    }
-
-    @Override
-    public int hashCode() {
-        return 31 * super.hashCode() + Objects.hashCode(dpid);
-    }
-
-    @Override
-    public String toString() {
-        return "[SwitchEvent " + dpid + "]";
-    }
-
     public static final int SWITCHID_BYTES = 2 + 8;
 
     public static ByteBuffer getSwitchID(Dpid dpid) {
@@ -112,11 +70,42 @@
                 .putChar('S').putLong(dpid).flip();
     }
 
-    public byte[] getID() {
-        return getSwitchID(dpid.value()).array();
+    @Override
+    public Dpid getOriginDpid() {
+        return this.dpid;
     }
 
+    @Override
     public ByteBuffer getIDasByteBuffer() {
         return getSwitchID(dpid.value());
     }
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + Objects.hashCode(dpid);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        // Compare attributes
+        if (!super.equals(o)) {
+            return false;
+        }
+
+        SwitchEvent other = (SwitchEvent) o;
+        return Objects.equals(this.dpid, other.dpid);
+    }
+
+    @Override
+    public String toString() {
+        return "[SwitchEvent " + dpid + "]";
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyElement.java b/src/main/java/net/onrc/onos/core/topology/TopologyElement.java
index 81ecb1f..52304f4 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyElement.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyElement.java
@@ -1,5 +1,6 @@
 package net.onrc.onos.core.topology;
 
+import java.nio.ByteBuffer;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
@@ -8,6 +9,8 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import net.onrc.onos.core.util.Dpid;
+
 /**
  * Base class for Topology Elements.
  * <p/>
@@ -17,7 +20,7 @@
  * @param <T> Sub-class' type.
  *      (Required to define a method returning itself's type)
  */
-public class TopologyElement<T extends TopologyElement<T>>
+public abstract class TopologyElement<T extends TopologyElement<T>>
         implements ITopologyElement, StringAttributes, UpdateStringAttributes {
 
     // TODO: Where should the attribute names be defined?
@@ -208,4 +211,18 @@
     public AdminStatus getStatus() {
         return AdminStatus.valueOf(getStringAttribute(ELEMENT_ADMIN_STATUS));
     }
+
+    /**
+     * Gets the topology event origin DPID.
+     *
+     * @return the topology event origin DPID.
+     */
+    abstract Dpid getOriginDpid();
+
+    /**
+     * Gets the topology event ID as a ByteBuffer.
+     *
+     * @return the topology event ID as a ByteBuffer.
+     */
+    abstract ByteBuffer getIDasByteBuffer();
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java b/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
index a36d221..a71bbf7 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyEvent.java
@@ -20,24 +20,30 @@
  * are finalized.
  */
 public final class TopologyEvent implements BatchOperationTarget {
-    private final MastershipEvent mastershipEvent; // Set for Mastership event
-    private final SwitchEvent switchEvent;      // Set for Switch event
-    private final PortEvent portEvent;          // Set for Port event
-    private final LinkEvent linkEvent;          // Set for Link event
-    private final HostEvent hostEvent;          // Set for Host event
+    private final Type eventType;
+    private final TopologyElement<?> event;
     private final OnosInstanceId onosInstanceId;   // The ONOS Instance ID
 
     /**
+     * The topology event type.
+     */
+    public enum Type {
+        MASTERSHIP,
+        SWITCH,
+        PORT,
+        LINK,
+        HOST,
+        NOOP,                   // TODO: temporary type; should be removed
+    }
+
+    /**
      * Default constructor for serializer.
      */
     @Deprecated
     protected TopologyEvent() {
-        mastershipEvent = null;
-        switchEvent = null;
-        portEvent = null;
-        linkEvent = null;
-        hostEvent = null;
-        onosInstanceId = null;
+        this.eventType = Type.NOOP;
+        this.event = null;
+        this.onosInstanceId = null;
     }
 
     /**
@@ -46,11 +52,8 @@
      * @param onosInstanceId the ONOS Instance ID that originates the event.
      */
     protected TopologyEvent(OnosInstanceId onosInstanceId) {
-        mastershipEvent = null;
-        switchEvent = null;
-        portEvent = null;
-        linkEvent = null;
-        hostEvent = null;
+        this.eventType = Type.NOOP;
+        this.event = null;
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
@@ -62,11 +65,8 @@
      */
     TopologyEvent(MastershipEvent mastershipEvent,
                   OnosInstanceId onosInstanceId) {
-        this.mastershipEvent = checkNotNull(mastershipEvent);
-        this.switchEvent = null;
-        this.portEvent = null;
-        this.linkEvent = null;
-        this.hostEvent = null;
+        this.eventType = Type.MASTERSHIP;
+        this.event = checkNotNull(mastershipEvent);
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
@@ -77,11 +77,8 @@
      * @param onosInstanceId the ONOS Instance ID that originates the event.
      */
     TopologyEvent(SwitchEvent switchEvent, OnosInstanceId onosInstanceId) {
-        this.mastershipEvent = null;
-        this.switchEvent = checkNotNull(switchEvent);
-        this.portEvent = null;
-        this.linkEvent = null;
-        this.hostEvent = null;
+        this.eventType = Type.SWITCH;
+        this.event = checkNotNull(switchEvent);
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
@@ -92,11 +89,8 @@
      * @param onosInstanceId the ONOS Instance ID that originates the event.
      */
     TopologyEvent(PortEvent portEvent, OnosInstanceId onosInstanceId) {
-        this.mastershipEvent = null;
-        this.switchEvent = null;
-        this.portEvent = checkNotNull(portEvent);
-        this.linkEvent = null;
-        this.hostEvent = null;
+        this.eventType = Type.PORT;
+        this.event = checkNotNull(portEvent);
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
@@ -107,11 +101,8 @@
      * @param onosInstanceId the ONOS Instance ID that originates the event.
      */
     TopologyEvent(LinkEvent linkEvent, OnosInstanceId onosInstanceId) {
-        this.mastershipEvent = null;
-        this.switchEvent = null;
-        this.portEvent = null;
-        this.linkEvent = checkNotNull(linkEvent);
-        this.hostEvent = null;
+        this.eventType = Type.LINK;
+        this.event = checkNotNull(linkEvent);
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
@@ -122,20 +113,30 @@
      * @param onosInstanceId the ONOS Instance ID that originates the event.
      */
     TopologyEvent(HostEvent hostEvent, OnosInstanceId onosInstanceId) {
-        this.mastershipEvent = null;
-        this.switchEvent = null;
-        this.portEvent = null;
-        this.linkEvent = null;
-        this.hostEvent = checkNotNull(hostEvent);
+        this.eventType = Type.HOST;
+        this.event = checkNotNull(hostEvent);
         this.onosInstanceId = checkNotNull(onosInstanceId);
     }
 
     /**
+     * Gets the Topology Event type.
+     *
+     * @return the Topology Event type.
+     */
+    TopologyEvent.Type getEventType() {
+        return this.eventType;
+    }
+
+    /**
      * Gets the Mastership event.
      *
      * @return the Mastership event.
      */
     public MastershipEvent getMastershipEvent() {
+        if (eventType != Type.MASTERSHIP) {
+            return null;
+        }
+        MastershipEvent mastershipEvent = (MastershipEvent) event;
         return mastershipEvent;
     }
 
@@ -145,6 +146,10 @@
      * @return the Switch event.
      */
     public SwitchEvent getSwitchEvent() {
+        if (eventType != Type.SWITCH) {
+            return null;
+        }
+        SwitchEvent switchEvent = (SwitchEvent) event;
         return switchEvent;
     }
 
@@ -154,6 +159,10 @@
      * @return the Port event.
      */
     public PortEvent getPortEvent() {
+        if (eventType != Type.PORT) {
+            return null;
+        }
+        PortEvent portEvent = (PortEvent) event;
         return portEvent;
     }
 
@@ -163,6 +172,10 @@
      * @return the Link event.
      */
     public LinkEvent getLinkEvent() {
+        if (eventType != Type.LINK) {
+            return null;
+        }
+        LinkEvent linkEvent = (LinkEvent) event;
         return linkEvent;
     }
 
@@ -172,6 +185,10 @@
      * @return the Host event.
      */
     public HostEvent getHostEvent() {
+        if (eventType != Type.HOST) {
+            return null;
+        }
+        HostEvent hostEvent = (HostEvent) event;
         return hostEvent;
     }
 
@@ -185,30 +202,6 @@
     }
 
     /**
-     * Gets the event origin DPID.
-     *
-     * @return the event origin DPID.
-     */
-    public Dpid getOriginDpid() {
-        if (mastershipEvent != null) {
-            return mastershipEvent.getOriginDpid();
-        }
-        if (switchEvent != null) {
-            return switchEvent.getOriginDpid();
-        }
-        if (portEvent != null) {
-            return portEvent.getOriginDpid();
-        }
-        if (linkEvent != null) {
-            return linkEvent.getOriginDpid();
-        }
-        if (hostEvent != null) {
-            return hostEvent.getOriginDpid();
-        }
-        return null;
-    }
-
-    /**
      * Tests whether the event origin DPID equals the specified DPID.
      *
      * @param dpid the DPID to compare against.
@@ -218,108 +211,23 @@
         return dpid.equals(getOriginDpid());
     }
 
+    public Dpid getOriginDpid() {
+        if (eventType == Type.NOOP) {
+            return null;
+        }
+        return event.getOriginDpid();
+    }
+
     /**
      * Returns the config state of the topology element.
      *
      * @return the config state of the topology element.
      */
     public ConfigState getConfigState() {
-        if (mastershipEvent != null) {
-            return mastershipEvent.getConfigState();
+        if (eventType == Type.NOOP) {
+            return ConfigState.NOT_CONFIGURED;  // Default: not configured
         }
-        if (switchEvent != null) {
-            return switchEvent.getConfigState();
-        }
-        if (portEvent != null) {
-            return portEvent.getConfigState();
-        }
-        if (linkEvent != null) {
-            return linkEvent.getConfigState();
-        }
-        if (hostEvent != null) {
-            return hostEvent.getConfigState();
-        }
-        return ConfigState.NOT_CONFIGURED;      // Default: not configured
-    }
-
-    /**
-     * Checks if all events contained are equal.
-     *
-     * @param obj TopologyEvent to compare against
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj == null) {
-            return false;
-        }
-
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-
-        TopologyEvent other = (TopologyEvent) obj;
-        return Objects.equals(mastershipEvent, other.mastershipEvent) &&
-            Objects.equals(switchEvent, other.switchEvent) &&
-            Objects.equals(portEvent, other.portEvent) &&
-            Objects.equals(linkEvent, other.linkEvent) &&
-            Objects.equals(hostEvent, other.hostEvent) &&
-            Objects.equals(onosInstanceId, other.onosInstanceId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mastershipEvent, switchEvent, portEvent,
-                            linkEvent, hostEvent, onosInstanceId);
-    }
-
-    /**
-     * Gets the string representation of the event.
-     *
-     * @return the string representation of the event.
-     */
-    @Override
-    public String toString() {
-        String eventStr = null;
-
-        //
-        // Get the Event string
-        //
-        stringLabel: {
-            if (mastershipEvent != null) {
-                eventStr = mastershipEvent.toString();
-                break stringLabel;
-            }
-            if (switchEvent != null) {
-                eventStr = switchEvent.toString();
-                break stringLabel;
-            }
-            if (portEvent != null) {
-                eventStr = portEvent.toString();
-                break stringLabel;
-            }
-            if (linkEvent != null) {
-                eventStr = linkEvent.toString();
-                break stringLabel;
-            }
-            if (hostEvent != null) {
-                eventStr = hostEvent.toString();
-                break stringLabel;
-            }
-            // Test whether this is NO-OP event
-            if (onosInstanceId != null) {
-                eventStr = "NO-OP";
-                break stringLabel;
-            }
-            // No event found
-            return "[Unknown TopologyEvent]";
-        }
-
-        return "[TopologyEvent " + eventStr + " from " +
-            onosInstanceId.toString() + "]";
+        return event.getConfigState();
     }
 
     /**
@@ -331,46 +239,17 @@
         return getIDasByteBuffer().array();
     }
 
-    /**
-     * Gets the Topology event ID as a ByteBuffer.
-     *
-     * @return the Topology event ID as a ByteBuffer.
-     */
     public ByteBuffer getIDasByteBuffer() {
         ByteBuffer eventId = null;
 
         //
         // Get the Event ID
         //
-        idLabel: {
-            if (mastershipEvent != null) {
-                eventId = mastershipEvent.getIDasByteBuffer();
-                break idLabel;
-            }
-            if (switchEvent != null) {
-                eventId = switchEvent.getIDasByteBuffer();
-                break idLabel;
-            }
-            if (portEvent != null) {
-                eventId = portEvent.getIDasByteBuffer();
-                break idLabel;
-            }
-            if (linkEvent != null) {
-                eventId = linkEvent.getIDasByteBuffer();
-                break idLabel;
-            }
-            if (hostEvent != null) {
-                eventId = hostEvent.getIDasByteBuffer();
-                break idLabel;
-            }
-            // Test whether this is NO-OP event
-            if (onosInstanceId != null) {
-                String id = "NO-OP";
-                eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
-                break idLabel;
-            }
-            // No event found
-            throw new IllegalStateException("Invalid TopologyEvent ID");
+        if (eventType == Type.NOOP) {
+            String id = "NO-OP";
+            eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
+        } else {
+            eventId = event.getIDasByteBuffer();
         }
 
         //
@@ -388,4 +267,40 @@
         buf.flip();
         return buf;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        TopologyEvent other = (TopologyEvent) o;
+        return Objects.equals(eventType, other.eventType) &&
+            Objects.equals(event, other.event) &&
+            Objects.equals(onosInstanceId, other.onosInstanceId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(eventType, event, onosInstanceId);
+    }
+
+    @Override
+    public String toString() {
+        String eventStr = null;
+
+        //
+        // Get the Event string
+        //
+        if (eventType == Type.NOOP) {
+            eventStr = "NO-OP";
+        } else {
+            eventStr = event.toString();
+        }
+        return "[TopologyEvent " + eventStr + " from " +
+            onosInstanceId.toString() + "]";
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index b6c2c86..1280cf4 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -953,7 +953,7 @@
 
             // Cleanup the Host Event from the local cache
             // TODO: The implementation below is probably wrong
-            ByteBuffer id = ByteBuffer.wrap(hostEvent.getID());
+            ByteBuffer id = hostEvent.getIDasByteBuffer();
             for (SwitchPort swp : hostEvent.getAttachmentPoints()) {
                 Map<ByteBuffer, HostEvent> oldHostEvents =
                         discoveredAddedHostEvents.get(swp.getDpid());
diff --git a/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
index e48b01b..18e0767 100644
--- a/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
@@ -176,6 +176,7 @@
         kryo.register(TopologyBatchOperation.Operator.class);
         kryo.register(TopologyElement.class);
         kryo.register(TopologyEvent.class);
+        kryo.register(TopologyEvent.Type.class);
 
         // Intent-related classes
         kryo.register(Path.class);
diff --git a/src/test/java/net/onrc/onos/core/util/serializers/KryoFactoryTest.java b/src/test/java/net/onrc/onos/core/util/serializers/KryoFactoryTest.java
index 4d05849..f5e196d 100644
--- a/src/test/java/net/onrc/onos/core/util/serializers/KryoFactoryTest.java
+++ b/src/test/java/net/onrc/onos/core/util/serializers/KryoFactoryTest.java
@@ -238,7 +238,7 @@
             Result result = benchType(obj, EqualityCheck.TO_STRING);
             results.add(result);
             // update me if serialized form is expected to change
-            assertEquals(47, result.size);
+            assertEquals(45, result.size);
         }
 
         { // CHECKSTYLE IGNORE THIS LINE
@@ -272,7 +272,7 @@
             Result result = benchType(tbo, EqualityCheck.EQUALS);
             results.add(result);
             // update me if serialized form is expected to change
-            assertEquals(215, result.size);
+            assertEquals(186, result.size);
         }
 
         // TODO Add registered classes we still use.