IPAddress and IPAddressWithMask updates and fixes

* Provide asCidrPrefixMask to determine if an IPAddress represents a valid CIDR netmask
* cidr prefix length computation was broken:
  + 0 not detected as valid CIDR
  + BigInteger is signed. Grrr
* Add more unit test cases
* Test asCidrPrefixMask
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
index 7c50aed..ed8a11b 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
@@ -4,6 +4,29 @@
 
     public abstract IPVersion getIpVersion();
 
+    /**
+     * Checks if this IPAddress represents a valid CIDR style netmask, i.e.,
+     * it has a set of leading "1" bits followed by only "0" bits
+     * @return true if this represents a valid CIDR style netmask, false
+     * otherwise
+     */
+    public boolean isCidrMask() {
+        return asCidrMaskLength() != -1;
+    }
+
+    /**
+     * If this IPAddress represents a valid CIDR style netmask (see
+     * isCidrMask()) returns the length of the prefix (the number of "1" bits).
+     * @return length of CIDR mask or -1 if this is not a CIDR netmask
+     */
+    public abstract int asCidrMaskLength();
+
+    @Override
+    public abstract boolean equals(Object other);
+
+    @Override
+    public abstract int hashCode();
+
     public static IPAddress<?> of(String ip) {
         if (ip.indexOf('.') != -1)
             return IPv4Address.of(ip);
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
index 11ef103..d0632c5 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
@@ -18,4 +18,20 @@
             throw new IllegalArgumentException("IP Address not well formed: " + ip);
     }
 
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+        res.append(value.toString());
+
+        res.append('/');
+        if (mask.asCidrMaskLength() != -1) {
+            // CIDR notation
+            res.append(mask.asCidrMaskLength());
+        } else {
+            // Full address mask
+            res.append(mask.toString());
+        }
+
+        return res.toString();
+    }
+
 }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
index 51d10f3..970a65c 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
@@ -33,6 +33,21 @@
         return IPVersion.IPv4;
     }
 
+
+    @Override
+    public int asCidrMaskLength() {
+        int maskint = getInt();
+        if (maskint == 0)
+            return 0;
+        else if (Integer.bitCount((~maskint) + 1) == 1) {
+            // IP represents a true CIDR prefix length
+            return Integer.bitCount(maskint);
+        } else {
+            // IP is not a true prefix.
+            return -1;
+        }
+    }
+
     public static IPv4Address of(final byte[] address) {
         if (address.length != LENGTH) {
             throw new IllegalArgumentException(
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
index f30fcbb..1f23f2d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
@@ -25,24 +25,6 @@
         return new IPv4AddressWithMask(value, mask);
     }
 
-    @Override
-    public String toString() {
-        StringBuilder res = new StringBuilder();
-        res.append(value.toString());
-
-        int maskint = mask.getInt();
-        res.append('/');
-        if (Integer.bitCount((~maskint) + 1) == 1) {
-            // CIDR notation
-            res.append(Integer.bitCount(maskint));
-        } else {
-            // Full address mask
-            res.append(mask.toString());
-        }
-
-        return res.toString();
-    }
-
     public static IPv4AddressWithMask of(final String string) {
         int slashPos;
         String ip = string;
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
index 1aad85b..531dadf 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
@@ -1,5 +1,6 @@
 package org.projectfloodlight.openflow.types;
 
+import java.math.BigInteger;
 import java.util.regex.Pattern;
 
 import org.jboss.netty.buffer.ChannelBuffer;
@@ -36,6 +37,21 @@
         return IPVersion.IPv6;
     }
 
+
+    @Override
+    public int asCidrMaskLength() {
+        BigInteger maskBigint = new BigInteger(getBytes());
+        if (maskBigint.equals(BigInteger.ZERO))
+            return 0; // Thanks, signed BigInteger
+        else if (maskBigint.not().add(BigInteger.ONE).bitCount() == 1) {
+            // Need to get a positive BigInteger before we can count
+            return new BigInteger(1, getBytes()).bitCount();
+        } else {
+            // IP is not a true prefix.
+            return -1;
+        }
+    }
+
     public static IPv6Address of(final byte[] address) {
         if (address.length != LENGTH) {
             throw new IllegalArgumentException(
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
index 6faf0b8..8376e5e 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
@@ -19,23 +19,6 @@
         return new IPv6AddressWithMask(value, mask);
     }
 
-    @Override
-    public String toString() {
-        StringBuilder res = new StringBuilder();
-        res.append(value.toString());
-        res.append('/');
-
-        BigInteger maskint = new BigInteger(mask.getBytes());
-        if (maskint.not().add(BigInteger.ONE).bitCount() == 1) {
-            // CIDR notation
-            res.append(maskint.bitCount());
-        } else {
-            // Full address mask
-            res.append(mask.toString());
-        }
-
-        return res.toString();
-    }
 
     public static IPv6AddressWithMask of(final String string) {
         int slashPos;