java/HashValue: add+subtract, remove combineWithValue

Added arithmetic add and subtract operations to HashValue types. Also
removed the obsolete combineWithValue operation that had weird/broken
semantics.
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
index 18f524e..5393db9 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
@@ -9,6 +9,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.text.MessageFormat;
+
 import org.hamcrest.Matchers;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
@@ -141,6 +143,66 @@
         }
     }
 
+    public static class Triple {
+        U128 a, b, c;
+
+        public Triple(U128 a, U128 b, U128 c) {
+            this.a = a;
+            this.b = b;
+            this.c = c;
+        }
+
+        public static Triple of(U128 a, U128 b, U128 c) {
+            return new Triple(a, b, c);
+        }
+
+        public String msg(String string) {
+            return MessageFormat.format(string, a,b,c);
+        }
+    }
+
+    @Test
+    public void testAddSubtract() {
+        U128 u0_0 = U128.of(0, 0);
+        U128 u0_1 = U128.of(0, 1);
+        U128 u1_0 = U128.of(1, 0);
+        U128 u1_1 = U128.of(1, 1);
+
+        U128 u0_2 = U128.of(0, 2);
+        U128 u2_0 = U128.of(2, 0);
+
+        U128 u0_f = U128.of(0, -1L);
+        U128 uf_0 = U128.of(-1L, 0);
+
+        Triple[] triples = new Triple[] {
+              Triple.of(u0_0, u0_0, u0_0),
+              Triple.of(u0_0, u0_1, u0_1),
+              Triple.of(u0_0, u1_0, u1_0),
+              Triple.of(u0_1, u1_0, u1_1),
+
+              Triple.of(u0_1, u0_1, u0_2),
+              Triple.of(u1_0, u1_0, u2_0),
+
+              Triple.of(u0_1, u0_f, u1_0),
+
+              Triple.of(u0_1, u0_f, u1_0),
+              Triple.of(u0_f, u0_f, U128.of(1, 0xffff_ffff_ffff_fffeL)),
+              Triple.of(uf_0, u0_f, U128.of(-1, -1)),
+              Triple.of(uf_0, u1_0, U128.ZERO),
+
+              Triple.of(U128.of(0x1234_5678_9abc_def1L, 0x1234_5678_9abc_def1L),
+                        U128.of(0xedcb_a987_6543_210eL, 0xedcb_a987_6543_210fL),
+                        U128.ZERO)
+        };
+
+        for(Triple t: triples) {
+            assertThat(t.msg("{0} + {1} = {2}"), t.a.add(t.b), equalTo(t.c));
+            assertThat(t.msg("{1} + {0} = {2}"), t.b.add(t.a), equalTo(t.c));
+
+            assertThat(t.msg("{2} - {0} = {1}"), t.c.subtract(t.a), equalTo(t.b));
+            assertThat(t.msg("{2} - {1} = {0}"), t.c.subtract(t.b), equalTo(t.a));
+        }
+    }
 
     @Test
     public void testCompare() {
@@ -180,21 +242,4 @@
         }
     }
 
-    @Test
-    public void testCombine() {
-        long key = 0x1234567890abcdefL;
-        long val = 0xdeafbeefdeadbeefL;
-        U128 hkey = U128.of(key, key*2);
-        U128 hVal = U128.of(val, val/2);
-
-        assertThat(hkey.combineWithValue(hVal, 0), equalTo(hkey.xor(hVal)));
-        assertThat(hkey.combineWithValue(hVal, 64), equalTo(U128.of(hkey.getMsb(), hkey.getLsb() ^ hVal.getLsb())));
-        assertThat(hkey.combineWithValue(hVal, 128), equalTo(hkey));
-
-        long mask8 = 0xFF00_0000_0000_0000L;
-
-        assertThat(hkey.combineWithValue(hVal, 8), equalTo(U128.of(hkey.getMsb() & mask8 |  hkey.getMsb() ^ hVal.getMsb() & ~mask8,
-                                                                   hkey.getLsb() ^ hVal.getLsb() )));
-    }
-
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
index b0cca23..7bd1c46 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
@@ -9,6 +9,7 @@
 import static org.junit.Assert.fail;
 
 import java.math.BigInteger;
+import java.text.MessageFormat;
 
 import org.junit.Test;
 
@@ -24,10 +25,10 @@
 
     @Test
     public void testNegativeRaws() {
-        long minus_1 = 0xFFFF_FFFF_FFFF_FFFFL;
-        assertEquals(minus_1, U64.ofRaw(minus_1).getValue());
-        assertEquals(new BigInteger("FFFF_FFFF_FFFF_FFFF".replace("_", ""), 16),  U64.ofRaw(minus_1).getBigInteger());
-        assertEquals(new BigInteger("18446744073709551615"),  U64.ofRaw(minus_1).getBigInteger());
+        long minu1 = 0xFFFF_FFFF_FFFF_FFFFL;
+        assertEquals(minu1, U64.ofRaw(minu1).getValue());
+        assertEquals(new BigInteger("FFFF_FFFF_FFFF_FFFF".replace("_", ""), 16),  U64.ofRaw(minu1).getBigInteger());
+        assertEquals(new BigInteger("18446744073709551615"),  U64.ofRaw(minu1).getBigInteger());
     }
 
     @Test
@@ -62,24 +63,6 @@
     }
 
     @Test
-    public void testCombine() {
-        long key = 0x1234567890abcdefL;
-        long val = 0xdeafbeefdeadbeefL;
-        U64 hkey = U64.of(key);
-        U64 hVal = U64.of(val);
-
-        assertThat(hkey.combineWithValue(hVal, 0), equalTo(hkey.xor(hVal)));
-        assertThat(hkey.combineWithValue(hVal, 64), equalTo(hkey));
-        long mask32 = 0x00000000FFFFFFFFL;
-        assertThat(hkey.combineWithValue(hVal, 32),
-                equalTo(U64.of(key & ~mask32| (key ^ val) & mask32)));
-
-        long tenMask = 0x003FFFFFFFFFFFFFL;
-        assertThat(hkey.combineWithValue(hVal, 10),
-                equalTo(U64.of(key & ~tenMask | (key ^ val) & tenMask)));
-    }
-
-    @Test
     public void testKeyBits() {
         U64 zeroU = U64.of(0);
         assertThat(zeroU.prefixBits(0), equalTo(0));
@@ -105,6 +88,62 @@
         checkInvalidKeyBitSize(signedBitU, 64);
     }
 
+    public static class Triple {
+        U64 a, b, c;
+
+        public Triple(U64 a, U64 b, U64 c) {
+            this.a = a;
+            this.b = b;
+            this.c = c;
+        }
+
+        public static Triple of(U64 a, U64 b, U64 c) {
+            return new Triple(a, b, c);
+        }
+
+        public String msg(String string) {
+            return MessageFormat.format(string, a,b,c);
+        }
+    }
+
+    @Test
+    public void testAddSubtract() {
+        U64 u0 = U64.of(0);
+        U64 u1 = U64.of(1);
+
+        U64 u2 = U64.of(2);
+        U64 u7f = U64.of(0x7fff_ffff_ffff_ffffL);
+        U64 u8 = U64.of(0x8000_0000_0000_0000L);
+
+        U64 uf = U64.of(-1L);
+
+        Triple[] triples = new Triple[] {
+              Triple.of(u0, u0, u0),
+              Triple.of(u0, u1, u1),
+
+              Triple.of(u1, u1, u2),
+
+              Triple.of(u1, uf, u0),
+
+              Triple.of(uf, uf, U64.of(0xffff_ffff_ffff_fffeL)),
+              Triple.of(u0, uf, uf),
+
+              Triple.of(u7f, u1, u8),
+
+              Triple.of(U64.of(0x1234_5678_9abc_def1L),
+                        U64.of(0xedcb_a987_6543_210fL),
+                        U64.ZERO)
+        };
+
+        for(Triple t: triples) {
+            assertThat(t.msg("{0} + {1} = {2}"), t.a.add(t.b), equalTo(t.c));
+            assertThat(t.msg("{1} + {0} = {2}"), t.b.add(t.a), equalTo(t.c));
+
+            assertThat(t.msg("{2} - {0} = {1}"), t.c.subtract(t.a), equalTo(t.b));
+            assertThat(t.msg("{2} - {1} = {0}"), t.c.subtract(t.b), equalTo(t.a));
+        }
+    }
+
     private void
             checkInvalidKeyBitSize(U64 u, int prefixBit) {
         try {