Merge into master from pull request #298:
Add bsn_disable_vlan_counters instruction. (https://github.com/floodlight/loxigen/pull/298)
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 5e4e818..4cb0fa5 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
@@ -10,6 +10,11 @@
 
 public abstract class IPAddress<F extends IPAddress<F>> implements OFValueType<F> {
 
+    /**
+     * Returns the Internet Protocol (IP) version of this object
+     *
+     * @return  the Internet Protocol (IP) version of this object
+     */
     public abstract IPVersion getIpVersion();
 
     /**
@@ -55,6 +60,52 @@
      */
     public abstract F not();
 
+    /**
+     * Returns an {@code IPAddressWithMask<F>} object that represents this
+     * IP address masked by the given IP address mask.
+     *
+     * @param mask  the {@code F} object that represents the mask
+     * @return      an {@code IPAddressWithMask<F>} object that represents this
+     *              IP address masked by the given mask
+     * @throws NullPointerException  if the given mask was {@code null}
+     */
+    @Nonnull
+    public abstract IPAddressWithMask<F> withMask(@Nonnull final F mask);
+
+    /**
+     * Returns an {@code IPAddressWithMask<F>} object that represents this
+     * IP address masked by the CIDR subnet mask of the given prefix length.
+     *
+     * @param cidrMaskLength  the prefix length of the CIDR subnet mask
+     *                        (i.e. the number of leading one-bits),
+     *                        where <code>
+     *                        0 <= cidrMaskLength <= (F.getLength() * 8)
+     *                        </code>
+     * @return                an {@code IPAddressWithMask<F>} object that
+     *                        represents this IP address masked by the CIDR
+     *                        subnet mask of the given prefix length
+     * @throws IllegalArgumentException  if the given prefix length was invalid
+     * @see #ofCidrMaskLength(int)
+     */
+    @Nonnull
+    public abstract IPAddressWithMask<F> withMaskOfLength(
+            final int cidrMaskLength);
+
+    /**
+     * Returns the raw IP address of this {@code IPAddress} object. The result
+     * is in network byte order: the highest order byte of the address is in
+     * {@code getBytes()[0]}.
+     * <p>
+     * Similar to {@link InetAddress#getAddress()}
+     *
+     * @return  the raw IP address of this object
+     * @see InetAddress#getAddress()
+     */
+    public abstract byte[] getBytes();
+
+    @Override
+    public abstract String toString();
+
     @Override
     public abstract boolean equals(Object other);
 
@@ -88,14 +139,26 @@
      * @throws NullPointerException if address is null
      */
     @Nonnull
-    public static IPAddress<?> fromInetAddress(@Nonnull InetAddress address) {
+    public static IPAddress<?> of(@Nonnull InetAddress address) {
         Preconditions.checkNotNull(address, "address must not be null");
-        byte [] bytes = address.getAddress();
         if(address instanceof Inet4Address)
-            return IPv4Address.of(bytes);
+            return IPv4Address.of(address);
         else if (address instanceof Inet6Address)
-            return IPv6Address.of(bytes);
+            return IPv6Address.of(address);
         else
             return IPAddress.of(address.getHostAddress());
     }
+
+    /**
+     * Factory function for InetAddress values.
+     * @param address the InetAddress you wish to parse into an IPAddress object.
+     * @return the IPAddress object.
+     * @throws NullPointerException if address is null
+     * @deprecated  replaced by {@link #of(InetAddress)}
+     */
+    @Deprecated
+    @Nonnull
+    public static IPAddress<?> fromInetAddress(@Nonnull InetAddress address) {
+        return of(address);
+    }
 }
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 d398a85..3a1b15e 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
@@ -1,5 +1,7 @@
 package org.projectfloodlight.openflow.types;
 
+import java.net.Inet4Address;
+import java.net.InetAddress;
 import java.util.Arrays;
 
 import javax.annotation.Nonnull;
@@ -98,12 +100,30 @@
         return IPv4Address.of(~rawValue);
     }
 
-    public static IPv4Address of(final byte[] address) {
+    /**
+     * Returns an {@code IPv4Address} object that represents the given
+     * IP address. The argument is in network byte order: the highest
+     * order byte of the address is in {@code address[0]}.
+     * <p>
+     * The address byte array must be 4 bytes long (32 bits long).
+     * <p>
+     * Similar to {@link InetAddress#getByAddress(byte[])}.
+     *
+     * @param address  the raw IP address in network byte order
+     * @return         an {@code IPv4Address} object that represents the given
+     *                 raw IP address
+     * @throws NullPointerException      if the given address was {@code null}
+     * @throws IllegalArgumentException  if the given address was of an invalid
+     *                                   byte array length
+     * @see InetAddress#getByAddress(byte[])
+     */
+    @Nonnull
+    public static IPv4Address of(@Nonnull final byte[] address) {
         Preconditions.checkNotNull(address, "address must not be null");
 
         if (address.length != LENGTH) {
             throw new IllegalArgumentException(
-                    "Invalid byte array length for IPv4Address address: " + address.length);
+                    "Invalid byte array length for IPv4 address: " + address.length);
         }
 
         int raw =
@@ -112,24 +132,32 @@
         return IPv4Address.of(raw);
     }
 
-    /** construct an IPv4Address from a 32-bit integer value.
+    /**
+     * Returns an {@code IPv4Address} object that represents the given
+     * IP address.
      *
-     * @param raw the IPAdress represented as a 32-bit integer
-     * @return the constructed IPv4Address
+     * @param raw  the raw IP address represented as a 32-bit integer
+     * @return     an {@code IPv4Address} object that represents the given
+     *             raw IP address
      */
+    @Nonnull
     public static IPv4Address of(final int raw) {
         if(raw == NONE_VAL)
             return NONE;
         return new IPv4Address(raw);
     }
 
-    /** parse an IPv4Address from the canonical dotted-quad representation
-     * (1.2.3.4).
+    /**
+     * Returns an {@code IPv4Address} object that represents the given
+     * IP address. The argument is in the canonical quad-dotted notation.
+     * For example, {@code 1.2.3.4}.
      *
-     * @param string an IPv4 address in dotted-quad representation
-     * @return the parsed IPv4 address
-     * @throws NullPointerException if string is null
-     * @throws IllegalArgumentException if string is not a valid IPv4Address
+     * @param string  the IP address in the canonical quad-dotted notation
+     * @return        an {@code IPv4Address} object that represents the given
+     *                IP address
+     * @throws NullPointerException      if the given string was {@code null}
+     * @throws IllegalArgumentException  if the given string was not a valid
+     *                                   IPv4 address
      */
     @Nonnull
     public static IPv4Address of(@Nonnull final String string) throws IllegalArgumentException {
@@ -158,12 +186,90 @@
         return IPv4Address.of(raw);
     }
 
+    /**
+     * Returns an {@code IPv4Address} object that represents the given
+     * IP address. The argument is given as an {@code Inet4Address} object.
+     *
+     * @param address  the IP address as an {@code Inet4Address} object
+     * @return         an {@code IPv4Address} object that represents the
+     *                 given IP address
+     * @throws NullPointerException  if the given {@code Inet4Address} was
+     *                               {@code null}
+     */
+    @Nonnull
+    public static IPv4Address of(@Nonnull final Inet4Address address) {
+        Preconditions.checkNotNull(address, "address must not be null");
+        return IPv4Address.of(address.getAddress());
+    }
+
+    /**
+     * Returns an {@code IPv4Address} object that represents the
+     * CIDR subnet mask of the given prefix length.
+     *
+     * @param cidrMaskLength  the prefix length of the CIDR subnet mask
+     *                        (i.e. the number of leading one-bits),
+     *                        where {@code 0 <= cidrMaskLength <= 32}
+     * @return                an {@code IPv4Address} object that represents the
+     *                        CIDR subnet mask of the given prefix length
+     * @throws IllegalArgumentException  if the given prefix length was invalid
+     */
+    @Nonnull
+    public static IPv4Address ofCidrMaskLength(final int cidrMaskLength) {
+        Preconditions.checkArgument(
+                cidrMaskLength >= 0 && cidrMaskLength <= 32,
+                "Invalid IPv4 CIDR mask length: %s", cidrMaskLength);
+
+        if (cidrMaskLength == 32) {
+            return IPv4Address.NO_MASK;
+        } else if (cidrMaskLength == 0) {
+            return IPv4Address.FULL_MASK;
+        } else {
+            int mask = (-1) << (32 - cidrMaskLength);
+            return IPv4Address.of(mask);
+        }
+    }
+
+    /**
+     * Returns an {@code IPv4AddressWithMask} object that represents this
+     * IP address masked by the given IP address mask.
+     *
+     * @param mask  the {@code IPv4Address} object that represents the mask
+     * @return      an {@code IPv4AddressWithMask} object that represents this
+     *              IP address masked by the given mask
+     * @throws NullPointerException  if the given mask was {@code null}
+     */
+    @Nonnull
+    @Override
+    public IPv4AddressWithMask withMask(@Nonnull final IPv4Address mask) {
+        return IPv4AddressWithMask.of(this, mask);
+    }
+
+    /**
+     * Returns an {@code IPv4AddressWithMask} object that represents this
+     * IP address masked by the CIDR subnet mask of the given prefix length.
+     *
+     * @param cidrMaskLength  the prefix length of the CIDR subnet mask
+     *                        (i.e. the number of leading one-bits),
+     *                        where {@code 0 <= cidrMaskLength <= 32}
+     * @return                an {@code IPv4AddressWithMask} object that
+     *                        represents this IP address masked by the CIDR
+     *                        subnet mask of the given prefix length
+     * @throws IllegalArgumentException  if the given prefix length was invalid
+     * @see #ofCidrMaskLength(int)
+     */
+    @Nonnull
+    @Override
+    public IPv4AddressWithMask withMaskOfLength(final int cidrMaskLength) {
+        return this.withMask(IPv4Address.ofCidrMaskLength(cidrMaskLength));
+    }
+
     public int getInt() {
         return rawValue;
     }
 
     private volatile byte[] bytesCache = null;
 
+    @Override
     public byte[] getBytes() {
         if (bytesCache == null) {
             synchronized (this) {
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 2d08e1a..b6dc1b9 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
@@ -1,5 +1,7 @@
 package org.projectfloodlight.openflow.types;
 
+import javax.annotation.Nonnull;
+
 import com.google.common.base.Preconditions;
 
 
@@ -19,23 +21,77 @@
         return IPVersion.IPv4;
     }
 
-    public static IPv4AddressWithMask of(int rawValue, int rawMask) {
+    /**
+     * Returns an {@code IPv4AddressWithMask} object that represents the given
+     * raw IP address masked by the given raw IP address mask.
+     *
+     * @param rawValue  the raw IP address to be masked
+     * @param rawMask   the raw IP address mask
+     * @return          an {@code IPv4AddressWithMask} object that represents
+     *                  the given raw IP address masked by the given raw IP
+     *                  address mask
+     * @deprecated      replaced by {@link IPv4Address#of(int)} and
+     *                  {@link IPv4Address#withMask(IPv4Address), e.g. <code>
+     *                  IPv4Address.of(int).withMask(IPv4Address.of(int))
+     *                  </code>
+     */
+    @Nonnull
+    @Deprecated
+    public static IPv4AddressWithMask of(final int rawValue, final int rawMask) {
         return new IPv4AddressWithMask(rawValue, rawMask);
     }
 
-    public static IPv4AddressWithMask of(IPv4Address value, IPv4Address mask) {
+    /**
+     * Returns an {@code IPv4AddressWithMask} object that represents the given
+     * IP address masked by the given IP address mask. Both arguments are given
+     * as {@code IPv4Address} objects.
+     *
+     * @param value  the IP address to be masked
+     * @param mask   the IP address mask
+     * @return       an {@code IPv4AddressWithMask} object that represents
+     *               the given IP address masked by the given IP address mask
+     * @throws NullPointerException  if any of the given {@code IPv4Address}
+     *                               objects were {@code null}
+     */
+    @Nonnull
+    public static IPv4AddressWithMask of(
+            @Nonnull final IPv4Address value,
+            @Nonnull final IPv4Address mask) {
         Preconditions.checkNotNull(value, "value must not be null");
         Preconditions.checkNotNull(mask, "mask must not be null");
 
         return new IPv4AddressWithMask(value, mask);
     }
 
-    public static IPv4AddressWithMask of(final String string) {
+    /**
+     * Returns an {@code IPv4AddressWithMask} object that corresponds to
+     * the given string in CIDR notation or other acceptable notations.
+     * <p>
+     * The following notations are accepted.
+     * <table><tr>
+     * <th>Notation</th><th>Example</th><th>Notes</th>
+     * </tr><tr>
+     * <td>IPv4 address only</td><td>{@code 1.2.3.4}</td><td>The subnet mask of
+     * prefix length 32 (i.e. {@code 255.255.255.255}) is assumed.</td>
+     * </tr><tr>
+     * <td>IPv4 address/mask</td><td>{@code 1.2.3.4/255.255.255.0}</td>
+     * </tr><tr>
+     * <td>CIDR notation</td><td>{@code 1.2.3.4/24}</td>
+     * </tr></table>
+     *
+     * @param string  the string in acceptable notations
+     * @return        an {@code IPv4AddressWithMask} object that corresponds to
+     *                the given string in acceptable notations
+     * @throws NullPointerException      if the given string was {@code null}
+     * @throws IllegalArgumentException  if the given string was malformed
+     */
+    @Nonnull
+    public static IPv4AddressWithMask of(@Nonnull final String string) {
         Preconditions.checkNotNull(string, "string must not be null");
 
         int slashPos;
         String ip = string;
-        int maskBits = 32;
+        int cidrMaskLength = 32;
         IPv4Address maskAddress = null;
 
         // Read mask suffix
@@ -50,14 +106,11 @@
                     maskAddress = IPv4Address.of(suffix);
                 } else {
                     // CIDR Suffix
-                    maskBits = Integer.parseInt(suffix);
+                    cidrMaskLength = Integer.parseInt(suffix);
                 }
             } catch (NumberFormatException e) {
                 throw new IllegalArgumentException("IP Address not well formed: " + string);
             }
-            if (maskBits < 0 || maskBits > 32) {
-                throw new IllegalArgumentException("IP Address not well formed: " + string);
-            }
         }
 
         // Read IP
@@ -66,16 +119,9 @@
         if (maskAddress != null) {
             // Full address mask
             return IPv4AddressWithMask.of(ipv4, maskAddress);
-        } else if (maskBits == 32) {
-            // No mask
-            return IPv4AddressWithMask.of(ipv4, IPv4Address.NO_MASK);
-        } else if (maskBits == 0) {
-            // No mask
-            return IPv4AddressWithMask.of(ipv4, IPv4Address.FULL_MASK);
         } else {
-            // With mask
-            int mask = (-1) << (32 - maskBits);
-            return IPv4AddressWithMask.of(ipv4, IPv4Address.of(mask));
+            return IPv4AddressWithMask.of(
+                    ipv4, IPv4Address.ofCidrMaskLength(cidrMaskLength));
         }
     }
 
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 dbf5a90..471d0fb 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,7 @@
 package org.projectfloodlight.openflow.types;
 
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.util.Arrays;
 import java.util.regex.Pattern;
 
@@ -122,7 +124,25 @@
         return IPv6Address.of(~raw1, ~raw2);
     }
 
-    public static IPv6Address of(final byte[] address) {
+    /**
+     * Returns an {@code IPv6Address} object that represents the given
+     * IP address. The argument is in network byte order: the highest
+     * order byte of the address is in {@code address[0]}.
+     * <p>
+     * The address byte array must be 16 bytes long (128 bits long).
+     * <p>
+     * Similar to {@link InetAddress#getByAddress(byte[])}.
+     *
+     * @param address  the raw IP address in network byte order
+     * @return         an {@code IPv6Address} object that represents the given
+     *                 raw IP address
+     * @throws NullPointerException      if the given address was {@code null}
+     * @throws IllegalArgumentException  if the given address was of an invalid
+     *                                   byte array length
+     * @see InetAddress#getByAddress(byte[])
+     */
+    @Nonnull
+    public static IPv6Address of(@Nonnull final byte[] address) {
         Preconditions.checkNotNull(address, "address must not be null");
 
         if (address.length != LENGTH) {
@@ -169,19 +189,25 @@
 
     private final static Pattern colonPattern = Pattern.compile(":");
 
-    /** parse an IPv6Address from its conventional string representation.
-     *  <p>
-     *  Expects up to 8 groups of 16-bit hex words seperated by colons
-     *  (e.g., 2001:db8:85a3:8d3:1319:8a2e:370:7348).
-     *  <p>
-     *  Supports zero compression (e.g., 2001:db8::7348).
-     *  Does <b>not</b> currently support embedding a dotted-quad IPv4 address
-     *  into the IPv6 address (e.g., 2001:db8::192.168.0.1).
+    /**
+     * Returns an {@code IPv6Address} object that represents the given
+     * IP address. The argument is in the conventional string representation
+     * of IPv6 addresses.
+     * <p>
+     * Expects up to 8 groups of 16-bit hex words seperated by colons
+     * (e.g., 2001:db8:85a3:8d3:1319:8a2e:370:7348).
+     * <p>
+     * Supports zero compression (e.g., 2001:db8::7348).
+     * Does <b>not</b> currently support embedding a dotted-quad IPv4 address
+     * into the IPv6 address (e.g., 2001:db8::192.168.0.1).
      *
-     * @param string a string representation of an IPv6 address
-     * @return the parsed IPv6 address
-     * @throws NullPointerException if string is null
-     * @throws IllegalArgumentException if string is not a valid IPv6Address
+     * @param string  the IP address in the conventional string representation
+     *                of IPv6 addresses
+     * @return        an {@code IPv6Address} object that represents the given
+     *                IP address
+     * @throws NullPointerException      if the given string was {@code null}
+     * @throws IllegalArgumentException  if the given string was not a valid
+     *                                   IPv6 address
      */
     @Nonnull
     public static IPv6Address of(@Nonnull final String string) throws IllegalArgumentException {
@@ -239,19 +265,104 @@
         return builder.getIPv6();
     }
 
-    /** construct an IPv6 adress from two 64 bit integers representing the first and
-     *  second 8-byte blocks of the address.
+    /**
+     * Returns an {@code IPv6Address} object that represents the given
+     * IP address. The arguments are the two 64-bit integers representing
+     * the first (higher-order) and second (lower-order) 64-bit blocks
+     * of the IP address.
      *
-     * @param raw1 - the first 8 byte block of the address
-     * @param raw2 - the second 8 byte block of the address
-     * @return the constructed IPv6Address
+     * @param raw1  the first (higher-order) 64-bit block of the IP address
+     * @param raw2  the second (lower-order) 64-bit block of the IP address
+     * @return      an {@code IPv6Address} object that represents the given
+     *              raw IP address
      */
+    @Nonnull
     public static IPv6Address of(final long raw1, final long raw2) {
         if(raw1==NONE_VAL1 && raw2 == NONE_VAL2)
             return NONE;
         return new IPv6Address(raw1, raw2);
     }
 
+    /**
+     * Returns an {@code IPv6Address} object that represents the given
+     * IP address. The argument is given as an {@code Inet6Address} object.
+     *
+     * @param address  the IP address as an {@code Inet6Address} object
+     * @return         an {@code IPv6Address} object that represents the
+     *                 given IP address
+     * @throws NullPointerException  if the given {@code Inet6Address} was
+     *                               {@code null}
+     */
+    @Nonnull
+    public static IPv6Address of(@Nonnull final Inet6Address address) {
+        Preconditions.checkNotNull(address, "address must not be null");
+        return IPv6Address.of(address.getAddress());
+    }
+
+    /**
+     * Returns an {@code IPv6Address} object that represents the
+     * CIDR subnet mask of the given prefix length.
+     *
+     * @param cidrMaskLength  the prefix length of the CIDR subnet mask
+     *                        (i.e. the number of leading one-bits),
+     *                        where {@code 0 <= cidrMaskLength <= 128}
+     * @return                an {@code IPv6Address} object that represents the
+     *                        CIDR subnet mask of the given prefix length
+     * @throws IllegalArgumentException  if the given prefix length was invalid
+     */
+    @Nonnull
+    public static IPv6Address ofCidrMaskLength(final int cidrMaskLength) {
+        Preconditions.checkArgument(
+                cidrMaskLength >= 0 && cidrMaskLength <= 128,
+                "Invalid IPv6 CIDR mask length: %s", cidrMaskLength);
+
+        if (cidrMaskLength == 128) {
+            return IPv6Address.NO_MASK;
+        } else if (cidrMaskLength == 0) {
+            return IPv6Address.FULL_MASK;
+        } else {
+            int shift1 = Math.min(cidrMaskLength, 64);
+            long raw1 = shift1 == 0 ? 0 : -1L << (64 - shift1);
+            int shift2 = Math.max(cidrMaskLength - 64, 0);
+            long raw2 = shift2 == 0 ? 0 : -1L << (64 - shift2);
+            return IPv6Address.of(raw1, raw2);
+        }
+    }
+
+    /**
+     * Returns an {@code IPv6AddressWithMask} object that represents this
+     * IP address masked by the given IP address mask.
+     *
+     * @param mask  the {@code IPv6Address} object that represents the mask
+     * @return      an {@code IPv6AddressWithMask} object that represents this
+     *              IP address masked by the given mask
+     * @throws NullPointerException  if the given mask was {@code null}
+     */
+    @Nonnull
+    @Override
+    public IPv6AddressWithMask withMask(@Nonnull final IPv6Address mask) {
+        return IPv6AddressWithMask.of(this, mask);
+    }
+
+    /**
+     * Returns an {@code IPv6AddressWithMask} object that represents this
+     * IP address masked by the CIDR subnet mask of the given prefix length.
+     *
+     * @param cidrMaskLength  the prefix length of the CIDR subnet mask
+     *                        (i.e. the number of leading one-bits),
+     *                        where {@code 0 <= cidrMaskLength <= 128}
+     * @return                an {@code IPv6AddressWithMask} object that
+     *                        represents this IP address masked by the CIDR
+     *                        subnet mask of the given prefix length
+     * @throws IllegalArgumentException  if the given prefix length was invalid
+     * @see #ofCidrMaskLength(int)
+     */
+    @Nonnull
+    @Override
+    public IPv6AddressWithMask withMaskOfLength(final int cidrMaskLength) {
+        return this.withMask(IPv6Address.ofCidrMaskLength(cidrMaskLength));
+    }
+
     private volatile byte[] bytesCache = null;
 
     public byte[] getBytes() {
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 f015871..ee34923 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
@@ -1,8 +1,5 @@
 package org.projectfloodlight.openflow.types;
 
-import java.math.BigInteger;
-import java.util.Arrays;
-
 import com.google.common.base.Preconditions;
 
 public class IPv6AddressWithMask extends IPAddressWithMask<IPv6Address> {
@@ -23,13 +20,12 @@
         return new IPv6AddressWithMask(value, mask);
     }
 
-
     public static IPv6AddressWithMask of(final String string) {
         Preconditions.checkNotNull(string, "string must not be null");
 
         int slashPos;
         String ip = string;
-        int maskBits = 128;
+        int cidrMaskLength = 128;
         IPv6Address maskAddress = null;
 
         // Read mask suffix
@@ -44,14 +40,11 @@
                     maskAddress = IPv6Address.of(suffix);
                 } else {
                     // CIDR Suffix
-                    maskBits = Integer.parseInt(suffix);
+                    cidrMaskLength = Integer.parseInt(suffix);
                 }
             } catch (NumberFormatException e) {
                 throw new IllegalArgumentException("IPv6 Address not well formed: " + string);
             }
-            if (maskBits < 0 || maskBits > 128) {
-                throw new IllegalArgumentException("IPv6 Address not well formed: " + string);
-            }
         }
 
         // Read IP
@@ -60,28 +53,9 @@
         if (maskAddress != null) {
             // Full address mask
             return IPv6AddressWithMask.of(ipv6, maskAddress);
-        } else if (maskBits == 128) {
-            // No mask
-            return IPv6AddressWithMask.of(ipv6, IPv6Address.NO_MASK);
-        } else if (maskBits == 0) {
-            // Entirely masked out
-            return IPv6AddressWithMask.of(ipv6, IPv6Address.FULL_MASK);
-        }else {
-            // With mask
-            BigInteger mask = BigInteger.ONE.negate().shiftLeft(128 - maskBits);
-            byte[] maskBytesTemp = mask.toByteArray();
-            byte[] maskBytes;
-            if (maskBytesTemp.length < 16) {
-                maskBytes = new byte[16];
-                System.arraycopy(maskBytesTemp, 0, maskBytes, 16 - maskBytesTemp.length, maskBytesTemp.length);
-                Arrays.fill(maskBytes, 0, 16 - maskBytesTemp.length, (byte)(0xFF));
-            } else if (maskBytesTemp.length > 16) {
-                maskBytes = new byte[16];
-                System.arraycopy(maskBytesTemp, 0, maskBytes, 0, maskBytes.length);
-            } else {
-                maskBytes = maskBytesTemp;
-            }
-            return IPv6AddressWithMask.of(ipv6, IPv6Address.of(maskBytes));
+        } else {
+            return IPv6AddressWithMask.of(ipv6,
+                    IPv6Address.ofCidrMaskLength(cidrMaskLength));
         }
     }
 
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
index cbab734..63c9c8f 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
@@ -31,7 +31,7 @@
             // expected
         }
         try {
-            IPAddress.of(null);
+            IPAddress.of((String) null);
             fail("Should have thrown NullPointerException");
         } catch (NullPointerException e) {
             assertNotNull(e.getMessage());
@@ -43,7 +43,7 @@
             assertNotNull(e.getMessage());
         }
         try {
-            IPAddress.of(null);
+            IPAddress.of((String) null);
             fail("Should have thrown NullPointerException");
         } catch (NullPointerException e) {
             assertNotNull(e.getMessage());
@@ -56,6 +56,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void testFromInetAddressException() throws UnknownHostException {
         try {
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
index a57b42a..0716b50 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
@@ -9,6 +9,9 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.net.Inet4Address;
+import java.net.InetAddress;
+
 import org.hamcrest.CoreMatchers;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
@@ -224,6 +227,83 @@
     }
 
     @Test
+    public void testOfCidrMaskLength() {
+        for (int i = 0; i <= 32; i++) {
+            assertEquals(IPv4Address.ofCidrMaskLength(i).asCidrMaskLength(), i);
+        }
+
+        assertEquals(IPv4Address.ofCidrMaskLength(0).getInt(), 0x0000_0000);
+
+        assertEquals(IPv4Address.ofCidrMaskLength(1).getInt(), 0x8000_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(2).getInt(), 0xC000_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(3).getInt(), 0xE000_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(4).getInt(), 0xF000_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(5).getInt(), 0xF800_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(6).getInt(), 0xFC00_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(7).getInt(), 0xFE00_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(8).getInt(), 0xFF00_0000);
+
+        assertEquals(IPv4Address.ofCidrMaskLength(9).getInt(), 0xFF80_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(10).getInt(), 0xFFC0_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(11).getInt(), 0xFFE0_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(12).getInt(), 0xFFF0_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(13).getInt(), 0xFFF8_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(14).getInt(), 0xFFFC_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(15).getInt(), 0xFFFE_0000);
+        assertEquals(IPv4Address.ofCidrMaskLength(16).getInt(), 0xFFFF_0000);
+
+        assertEquals(IPv4Address.ofCidrMaskLength(17).getInt(), 0xFFFF_8000);
+        assertEquals(IPv4Address.ofCidrMaskLength(18).getInt(), 0xFFFF_C000);
+        assertEquals(IPv4Address.ofCidrMaskLength(19).getInt(), 0xFFFF_E000);
+        assertEquals(IPv4Address.ofCidrMaskLength(20).getInt(), 0xFFFF_F000);
+        assertEquals(IPv4Address.ofCidrMaskLength(21).getInt(), 0xFFFF_F800);
+        assertEquals(IPv4Address.ofCidrMaskLength(22).getInt(), 0xFFFF_FC00);
+        assertEquals(IPv4Address.ofCidrMaskLength(23).getInt(), 0xFFFF_FE00);
+        assertEquals(IPv4Address.ofCidrMaskLength(24).getInt(), 0xFFFF_FF00);
+
+        assertEquals(IPv4Address.ofCidrMaskLength(25).getInt(), 0xFFFF_FF80);
+        assertEquals(IPv4Address.ofCidrMaskLength(26).getInt(), 0xFFFF_FFC0);
+        assertEquals(IPv4Address.ofCidrMaskLength(27).getInt(), 0xFFFF_FFE0);
+        assertEquals(IPv4Address.ofCidrMaskLength(28).getInt(), 0xFFFF_FFF0);
+        assertEquals(IPv4Address.ofCidrMaskLength(29).getInt(), 0xFFFF_FFF8);
+        assertEquals(IPv4Address.ofCidrMaskLength(30).getInt(), 0xFFFF_FFFC);
+        assertEquals(IPv4Address.ofCidrMaskLength(31).getInt(), 0xFFFF_FFFE);
+        assertEquals(IPv4Address.ofCidrMaskLength(32).getInt(), 0xFFFF_FFFF);
+    }
+
+    @Test
+    public void testWithMask() throws Exception {
+        // Sanity tests for the withMask*() syntactic sugars
+
+        IPv4Address original = IPv4Address.of("192.168.1.101");
+        IPv4Address expectedValue = IPv4Address.of("192.168.1.0");
+        IPv4Address expectedMask = IPv4Address.of("255.255.255.0");
+
+        IPv4AddressWithMask v;
+
+        v = original.withMask(IPv4Address.of(new byte[] {-1, -1, -1, 0}));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMask(IPv4Address.of(0xFFFF_FF00));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMask(IPv4Address.of("255.255.255.0"));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        Inet4Address i4a = (Inet4Address) InetAddress.getByName("255.255.255.0");
+        v = original.withMask(IPv4Address.of(i4a));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMaskOfLength(24);
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+    }
+
+    @Test
     public void testReadFrom() throws OFParseError {
         for(int i=0; i < testAddresses.length; i++ ) {
             IPv4Address ip = IPv4Address.read4Bytes(ChannelBuffers.copiedBuffer(testAddresses[i]));
@@ -367,5 +447,17 @@
         } catch (IllegalArgumentException e) {
             assertNotNull(e.getMessage());
         }
+        try {
+            IPv4Address.ofCidrMaskLength(-1);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPv4Address.ofCidrMaskLength(33);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            assertNotNull(e.getMessage());
+        }
     }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
index 6963c21..a397c2a 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
@@ -198,6 +198,79 @@
         }
     }
 
+    private static void testOfCidrMaskLengthHelper(
+            int cidrMaskLength, String ipStr) throws UnknownHostException {
+        byte[] ba0 = IPv6Address.ofCidrMaskLength(cidrMaskLength).getBytes();
+        byte[] ba1 = Inet6Address.getByName(ipStr).getAddress();
+        assertArrayEquals(ba0, ba1);
+    }
+
+    @Test
+    public void testOfCidrMaskLength() throws UnknownHostException {
+        for (int i = 0; i <= 128; i++) {
+            assertTrue(IPv6Address.ofCidrMaskLength(i).isCidrMask());
+            assertEquals(IPv6Address.ofCidrMaskLength(i).asCidrMaskLength(), i);
+        }
+        testOfCidrMaskLengthHelper(0, "::");
+        testOfCidrMaskLengthHelper(1, "8000::");
+        testOfCidrMaskLengthHelper(2, "c000::");
+        testOfCidrMaskLengthHelper(8, "ff00::");
+        testOfCidrMaskLengthHelper(16, "ffff::");
+        testOfCidrMaskLengthHelper(17, "ffff:8000::");
+        testOfCidrMaskLengthHelper(31, "ffff:fffe::");
+        testOfCidrMaskLengthHelper(32, "ffff:ffff::");
+        testOfCidrMaskLengthHelper(33, "ffff:ffff:8000::");
+        testOfCidrMaskLengthHelper(46, "ffff:ffff:fffc::");
+        testOfCidrMaskLengthHelper(48, "ffff:ffff:ffff::");
+        testOfCidrMaskLengthHelper(55, "ffff:ffff:ffff:fe00::");
+        testOfCidrMaskLengthHelper(56, "ffff:ffff:ffff:ff00::");
+        testOfCidrMaskLengthHelper(59, "ffff:ffff:ffff:ffe0::");
+        testOfCidrMaskLengthHelper(63, "ffff:ffff:ffff:fffe::");
+        testOfCidrMaskLengthHelper(64, "ffff:ffff:ffff:ffff::");
+        testOfCidrMaskLengthHelper(65, "ffff:ffff:ffff:ffff:8000::");
+        testOfCidrMaskLengthHelper(67, "ffff:ffff:ffff:ffff:e000::");
+        testOfCidrMaskLengthHelper(100, "ffff:ffff:ffff:ffff:ffff:ffff:f000::");
+        testOfCidrMaskLengthHelper(101, "ffff:ffff:ffff:ffff:ffff:ffff:f800::");
+        testOfCidrMaskLengthHelper(126, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc");
+        testOfCidrMaskLengthHelper(127, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe");
+        testOfCidrMaskLengthHelper(128, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+    }
+
+    @Test
+    public void testWithMask() throws Exception {
+        // Sanity tests for the withMask*() syntactic sugars
+
+        IPv6Address original = IPv6Address.of("fd12:3456:ABCD:7890::1");
+        IPv6Address expectedValue = IPv6Address.of("fd12:3456:ABCD::");
+        IPv6Address expectedMask = IPv6Address.of("ffff:ffff:ffff::");
+
+        IPv6AddressWithMask v;
+
+        v = original.withMask(IPv6Address.of(new byte[] {
+                -1, -1, -1, -1, -1, -1, 0, 0,
+                0, 0, 0, 0, 0, 0, 0, 0 }));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMask(IPv6Address.of(
+                0xFFFF_FFFF_FFFF_0000L, 0x0000_0000_0000_0000L));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMask(IPv6Address.of("ffff:ffff:ffff::"));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        Inet6Address i6a = (Inet6Address) InetAddress.getByName("ffff:ffff:ffff::");
+        v = original.withMask(IPv6Address.of(i6a));
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+
+        v = original.withMaskOfLength(48);
+        assertEquals(v.getValue(), expectedValue);
+        assertEquals(v.getMask(), expectedMask);
+    }
+
     @Test
     public void testReadFrom() throws OFParseError, UnknownHostException {
         for(int i=0; i < testStrings.length; i++ ) {
@@ -313,5 +386,17 @@
         } catch (IllegalArgumentException e) {
             assertNotNull(e.getMessage());
         }
+        try {
+            IPv6Address.ofCidrMaskLength(-1);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPv6Address.ofCidrMaskLength(129);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            assertNotNull(e.getMessage());
+        }
     }
 }