1. Removed type serializers, added (write|read)[0-9]*Byte[s]?(ChannelBuffer) method to value types instead.
2. Updated Masked fields for IPv4, IPv6 with specific string methods.
3. Added value types for other fields from the spec
4. Updated unit tests accordingly
5. Changed java_type.py to support multiple read/write operations per type, per OF version.
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java b/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java
index 8a8c3e0..d344021 100644
--- a/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/IPv4Test.java
@@ -42,6 +42,27 @@
             "1.x.3.4",
             "1.2x.3.4"
     };
+    
+    String[] ipsWithMask = {
+                            "1.2.3.4/24",
+                            "192.168.130.140/255.255.192.0",
+                            "127.0.0.1/8",
+                            "8.8.8.8",
+    };
+    
+    boolean[] hasMask = {
+                         true,
+                         true,
+                         true,
+                         false
+    };
+    
+    byte[][][] ipsWithMaskValues = {
+                             new byte[][] { new byte[] { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04 }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00 } },
+                             new byte[][] { new byte[] { (byte)0xC0, (byte)0xA8, (byte)0x82, (byte)0x8C }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xC0, (byte)0x00 } },
+                             new byte[][] { new byte[] { (byte)0x7F, (byte)0x00, (byte)0x00, (byte)0x01 }, new byte[] { (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0x00 } },
+                             new byte[][] { new byte[] { (byte)0x08, (byte)0x08, (byte)0x08, (byte)0x08 }, null }
+    };
 
 
     @Test
@@ -67,7 +88,7 @@
     @Test
     public void testReadFrom() throws OFParseError, OFShortRead {
         for(int i=0; i < testAddresses.length; i++ ) {
-            IPv4 ip = IPv4.SERIALIZER_V10.readFrom(ChannelBuffers.copiedBuffer(testAddresses[i]));
+            IPv4 ip = IPv4.read4Bytes(ChannelBuffers.copiedBuffer(testAddresses[i]));
             assertEquals(testInts[i], ip.getInt());
             assertArrayEquals(testAddresses[i], ip.getBytes());
             assertEquals(testStrings[i], ip.toString());
@@ -86,4 +107,31 @@
             }
         }
     }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testOfPossiblyMasked() throws OFParseError, OFShortRead {
+        for (int i = 0; i < ipsWithMask.length; i++) {
+            OFValueType value = IPv4WithMask.ofPossiblyMasked(ipsWithMask[i]);
+            if (value instanceof IPv4 && !hasMask[i]) {
+                // Types OK, check values
+                IPv4 ip = (IPv4)value;
+                assertArrayEquals(ipsWithMaskValues[i][0], ip.getBytes());
+            } else if (value instanceof Masked && hasMask[i]) {
+                Masked<IPv4> ip = null;
+                try {
+                    ip = (Masked<IPv4>)value;
+                } catch (ClassCastException e) {
+                    fail("Invalid Masked<T> type.");
+                }
+                // Types OK, check values
+                assertArrayEquals(ipsWithMaskValues[i][0], ip.getValue().getBytes());
+                assertArrayEquals(ipsWithMaskValues[i][1], ip.getMask().getBytes());
+            } else if (value instanceof IPv4) {
+                fail("Expected masked IPv4, got unmasked IPv4.");
+            } else {
+                fail("Expected unmasked IPv4, got masked IPv4.");
+            }
+        }
+    }
 }
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java b/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java
index 9782429..f2f6fe8 100644
--- a/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/IPv6Test.java
@@ -21,6 +21,72 @@
             "ffe0::",
             "1:2:3:4:5:6:7:8"
     };
+    
+    String[] ipsWithMask = {
+                            "1::1/80",
+                            "1:2:3:4::/ffff:ffff:ffff:ff00::",
+                            "ffff:ffee:1::/ff00:ff00:ff00:ff00::",
+                            "8:8:8:8:8:8:8:8",
+    };
+    
+    byte[][] masks = {
+                    new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 
+                                 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 
+                                 (byte)0xff, (byte)0xff, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
+                    new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, 
+                                 (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
+                    new byte[] { (byte)0xff, (byte)0x00, (byte)0xff, (byte)0x00, 
+                                 (byte)0xff, (byte)0x00, (byte)0xff, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
+                    new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, 
+                                 (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
+    };
+    
+    boolean[] hasMask = {
+                         true,
+                         true,
+                         true,
+                         false
+    };
+
+    @Test
+    public void testMasked() throws UnknownHostException {
+        for(int i=0; i < ipsWithMask.length; i++ ) {
+            OFValueType value = IPv6WithMask.ofPossiblyMasked(ipsWithMask[i]);
+            if (value instanceof IPv6 && !hasMask[i]) {
+                // Types OK, check values
+                IPv6 ip = (IPv6)value;
+                InetAddress inetAddress = InetAddress.getByName(ipsWithMask[i]);
+
+                assertArrayEquals(ip.getBytes(), inetAddress.getAddress());
+                assertEquals(ipsWithMask[i], ip.toString());
+            } else if (value instanceof IPv6WithMask && hasMask[i]) {
+                IPv6WithMask ip = null;
+                try {
+                    ip = (IPv6WithMask)value;
+                } catch (ClassCastException e) {
+                    fail("Invalid Masked<T> type.");
+                }
+                // Types OK, check values
+                InetAddress inetAddress = InetAddress.getByName(ipsWithMask[i].substring(0, ipsWithMask[i].indexOf('/')));
+
+                assertArrayEquals(ip.value.getBytes(), inetAddress.getAddress());
+                assertEquals(ipsWithMask[i].substring(0, ipsWithMask[i].indexOf('/')), ip.value.toString());
+                assertArrayEquals(masks[i], ip.mask.getBytes());
+            } else if (value instanceof IPv6) {
+                fail("Expected masked IPv6, got unmasked IPv6.");
+            } else {
+                fail("Expected unmasked IPv6, got masked IPv6.");
+            }
+        }
+    }
+
 
     @Test
     public void testOfString() throws UnknownHostException {
@@ -47,7 +113,7 @@
     public void testReadFrom() throws OFParseError, OFShortRead, UnknownHostException {
         for(int i=0; i < testStrings.length; i++ ) {
             byte[] bytes = Inet6Address.getByName(testStrings[i]).getAddress();
-            IPv6 ip = IPv6.SERIALIZER_V12.readFrom(ChannelBuffers.copiedBuffer(bytes));
+            IPv6 ip = IPv6.read16Bytes(ChannelBuffers.copiedBuffer(bytes));
             assertEquals(testStrings[i], ip.toString());
             assertArrayEquals(bytes, ip.getBytes());
         }
diff --git a/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java b/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java
index f6326d1..78728e1 100644
--- a/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/openflow/types/MacAddressTest.java
@@ -64,7 +64,7 @@
     @Test
     public void testReadFrom() throws OFParseError, OFShortRead {
         for(int i=0; i < testAddresses.length; i++ ) {
-            MacAddress ip = MacAddress.SERIALIZER_V10.readFrom(ChannelBuffers.copiedBuffer(testAddresses[i]));
+            MacAddress ip = MacAddress.read6Bytes(ChannelBuffers.copiedBuffer(testAddresses[i]));
             assertEquals(testInts[i], ip.getLong());
             assertArrayEquals(testAddresses[i], ip.getBytes());
             assertEquals(testStrings[i], ip.toString());