diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java b/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java
index ffca61530dbcab3eda7159bec0a7f86014682ac1..2259e6f0a53e26166a210e55925cbe11966a9101 100644
--- a/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java
+++ b/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java
@@ -35,6 +35,61 @@ public class OFMessageUtils {
 	 */
 	private OFMessageUtils() {};
 
+	/**
+	 * Simple class to streamline the use of OFMessage's
+	 * equalsIgnoreXid() and hashCodeIgnoreXid() functions.
+	 * Use this class to wrap OFMessages prior to inserting
+	 * them in containers where lookup or equality checks
+	 * should not include the XID.
+	 * 
+	 * See {@link net.floodlightcontroller.util.OFMessageDamper}
+	 * as an example where it's used to help cache OFMessages.
+	 * @author rizard
+	 */
+	public static class OFMessageIgnoreXid {
+	    private OFMessage m;
+	    
+	    private OFMessageIgnoreXid() {}
+	    private OFMessageIgnoreXid(OFMessage m) {
+	        this.m = m;
+	    }
+	    
+	    /**
+	     * Wrap an OFMessage to ignore the XID
+	     * when checking for equality or computing
+	     * the OFMessage's hash.
+	     * @param m
+	     * @return
+	     */
+	    public static OFMessageIgnoreXid of(OFMessage m) {
+	        return new OFMessageIgnoreXid(m);
+	    }
+	    
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((m == null) ? 0 : m.hashCodeIgnoreXid());
+            return result;
+        }
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            OFMessageIgnoreXid other = (OFMessageIgnoreXid) obj;
+            if (m == null) {
+                if (other.m != null)
+                    return false;
+            } else if (!m.equalsIgnoreXid(other.m))
+                return false;
+            return true;
+        }
+	}
+	
 	/**
 	 * Get the ingress port of a packet-in message. The manner in which
 	 * this is done depends on the OpenFlow version. OF1.0 and 1.1 have
@@ -81,24 +136,6 @@ public class OFMessageUtils {
 		return pi.getMatch().get(MatchField.VLAN_VID) == null ? OFVlanVidMatch.UNTAGGED : pi.getMatch().get(MatchField.VLAN_VID);
 	}
 
-	/**
-	 * Returns true if each object is deeply-equal in the same manner that
-	 * Object's equals() does with the exception of the XID field, which is
-	 * ignored; otherwise, returns false.
-	 * 
-	 * NOTE: This function is VERY INEFFICIENT and creates a new OFMessage
-	 * object in order to the the comparison minus the XID. It is advised
-	 * that you use it sparingly and ideally only within unit tests.
-	 * 
-	 * @param a; object A to compare
-	 * @param b; object B to compare
-	 * @return true if A and B are deeply-equal; false otherwise
-	 */
-	public static boolean equalsIgnoreXid(OFMessage a, OFMessage b) {
-		OFMessage.Builder mb = b.createBuilder().setXid(a.getXid());
-		return a.equals(mb.build());
-	}
-
 	/**
 	 * Writes an OFPacketOut message to a switch.
 	 * 
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 9d68ba9f98a4309d13fda155978e799f12b083db..a3e5dab0b3add80a12ce3e48291b292c31e8bd45 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -488,15 +488,15 @@ public class ForwardingTest extends FloodlightTestCase {
 
 		for (OFMessage m: msglist) {
 			if (m instanceof OFFlowMod)
-				assertTrue(OFMessageUtils.equalsIgnoreXid(fm1, m));
+				assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(fm1), OFMessageUtils.OFMessageIgnoreXid.of(m));
 			else if (m instanceof OFPacketOut) {
-				assertTrue(OFMessageUtils.equalsIgnoreXid(packetOut, m));
+                assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(packetOut), OFMessageUtils.OFMessageIgnoreXid.of(m));
 			}
 		}
 
 		OFMessage m = wc2.getValue();
 		assert (m instanceof OFFlowMod);
-		assertTrue(OFMessageUtils.equalsIgnoreXid(m, fm2));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(fm2));
 		
 		removeDeviceFromContext();
 	}
@@ -558,15 +558,15 @@ public class ForwardingTest extends FloodlightTestCase {
 
 		for (OFMessage m: msglist) {
 			if (m instanceof OFFlowMod)
-				assertTrue(OFMessageUtils.equalsIgnoreXid(fm1, m));
+                assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(fm1), OFMessageUtils.OFMessageIgnoreXid.of(m));
 			else if (m instanceof OFPacketOut) {
-				assertTrue(OFMessageUtils.equalsIgnoreXid(packetOutIPv6, m));
+                assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(packetOutIPv6), OFMessageUtils.OFMessageIgnoreXid.of(m));
 			}
 		}
 
 		OFMessage m = wc2.getValue();
 		assert (m instanceof OFFlowMod);
-		assertTrue(OFMessageUtils.equalsIgnoreXid(m, fm2));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(fm2));
 		
 		removeDeviceFromContext();
 	}
@@ -619,8 +619,8 @@ public class ForwardingTest extends FloodlightTestCase {
 		assertTrue(wc1.hasCaptured());
 		assertTrue(wc2.hasCaptured());
 
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), fm1));
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), packetOut));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOut));
 		
 		removeDeviceFromContext();
 	}
@@ -673,8 +673,8 @@ public class ForwardingTest extends FloodlightTestCase {
 		assertTrue(wc1.hasCaptured());
 		assertTrue(wc2.hasCaptured());
 
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), fm1));
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), packetOutIPv6));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutIPv6));
 		
 		removeDeviceFromContext();
 	}
@@ -763,7 +763,7 @@ public class ForwardingTest extends FloodlightTestCase {
 		verify(sw1, sw2, routingEngine);
 
 		assertTrue(wc1.hasCaptured());
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOutFlooded));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutFlooded));
 		
 		removeDeviceFromContext();
 	}
@@ -796,7 +796,7 @@ public class ForwardingTest extends FloodlightTestCase {
 		verify(sw1, sw2, routingEngine);
 
 		assertTrue(wc1.hasCaptured());
-		assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOutFloodedIPv6));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutFloodedIPv6));
 		
 		removeDeviceFromContext();
 	}
diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java
index 6fcd37e81669945e853450426cb09a2fb97b8c23..61ddd24bad2daa35e5e9f44e11cb2b2bc1547b95 100644
--- a/src/test/java/net/floodlightcontroller/hub/HubTest.java
+++ b/src/test/java/net/floodlightcontroller/hub/HubTest.java
@@ -138,7 +138,7 @@ public class HubTest extends FloodlightTestCase {
         
         assertTrue(wc1.hasCaptured());
         OFMessage m = wc1.getValue();
-        assertTrue(OFMessageUtils.equalsIgnoreXid(m, po));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(po));
     }
 
     @Test
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
index eb884f4406694a574b31dd31a1a3fb33d1dd176b..8796e3f62f5f8b0153cc18565b55d10de5985e62 100644
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
@@ -204,7 +204,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
         verify(mockSwitch);
         
         assertTrue(wc1.hasCaptured());
-        assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), po));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(po));
 
         // Verify the MAC table inside the switch
         assertEquals(OFPort.of(1), result);
@@ -291,9 +291,9 @@ public class LearningSwitchTest extends FloodlightTestCase {
         assertTrue(wc1.hasCaptured());
         assertTrue(wc2.hasCaptured());
         assertTrue(wc3.hasCaptured());
-        assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOut));
-        assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), fm1));
-        assertTrue(OFMessageUtils.equalsIgnoreXid(wc3.getValue(), fm2));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOut));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc3.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm2));
 
         // Verify the MAC table inside the switch
         assertEquals(OFPort.of(1), result);
diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
index 09bfec33a7769a78c7896a7204cf0de561b30868..9bd3c98fe87de373c3cd5b2ebfb42d32fa8be5f2 100644
--- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
+++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
@@ -541,7 +541,7 @@ public class LoadBalancerTest extends FloodlightTestCase {
 
 		for (OFMessage m: msglist1) {
 			if (m instanceof OFPacketOut)
-				assertTrue(OFMessageUtils.equalsIgnoreXid(arpReplyPacketOut1, m));
+                assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(arpReplyPacketOut1), OFMessageUtils.OFMessageIgnoreXid.of(m));
 			else
 				assertTrue(false); // unexpected message
 		}
diff --git a/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java
index a2a6eb964d58d84c71b0d1d777927bb6859b6c3e..e2b52156f53676e2986fefc099687274aa590361 100644
--- a/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java
+++ b/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java
@@ -175,7 +175,7 @@ public class StaticFlowTests extends FloodlightTestCase {
 		// dont' bother testing the cookie; just copy it over
 		goodFlowMod = goodFlowMod.createBuilder().setCookie(testFlowMod.getCookie()).build();
 		// .. so we can continue to use .equals()
-		assertTrue(OFMessageUtils.equalsIgnoreXid(goodFlowMod, testFlowMod));
+        assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(goodFlowMod), OFMessageUtils.OFMessageIgnoreXid.of(testFlowMod));
 	}