Fixes to in ports masked

Conflicts:
	test_data/of13/oxm_bsn_in_ports_masked_128.data
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index f40bc71..1bc75e6 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -230,7 +230,8 @@
                 "OFOxmMplsLabelMasked":     OxmMapEntry("U32", "MPLS_LABEL", True),
                 "OFOxmMplsTc":              OxmMapEntry("U8", "MPLS_TC", False),
                 "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True),
-                "OFOxmBsnInPortsMasked128": OxmMapEntry("OFPortMap", "BSN_IN_PORTS_MASKED_128", True)
+                "OFOxmBsnInPorts128":       OxmMapEntry("OFPortBitmap", "BSN_IN_PORTS_128", False),
+                "OFOxmBsnInPorts128Masked": OxmMapEntry("OFPortBitmap", "BSN_IN_PORTS_128", True)
                 }
 
     # Registry of nullable properties:
@@ -399,6 +400,13 @@
                         factory.members.append(i)
                         break
         return factories.values()
+    
+    @memoize
+    def factory_of(self, interface):
+        for factory in self.of_factories:
+            if interface in factory.members:
+                return factory
+        return None
 
     def generate_class(self, clazz):
         """ return wether or not to generate implementation class clazz.
@@ -441,6 +449,12 @@
             return "build" + n[0].upper() + n[1:]
         else:
             return n
+    
+    def of_version(self, version):
+        for fc in self.factory_classes:
+            if fc.version == version:
+                return fc
+        return None
 
 OFGenericClass = namedtuple("OFGenericClass", ("package", "name"))
 class OFFactoryClass(namedtuple("OFFactoryClass", ("package", "name", "interface", "version"))):
@@ -1107,7 +1121,11 @@
     @property
     def name(self):
         return self.test_class_name
-
+    
+    @property
+    def interface(self):
+        return self.java_class.interface
+    
     @property
     def has_test_data(self):
         return test_data.exists(self.data_file_name)
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 035b11e..b6365d8 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -380,10 +380,10 @@
 table_stats_wildcards = JType("int") \
         .op(read='bb.readInt()',
             write='bb.writeInt($name)')
-port_map = JType('OFPortMap') \
-            .op(read='OFPortMap.read16Bytes(bb)',
+port_bitmap = JType('OFPortBitmap') \
+            .op(read='OFPortBitmap.read16Bytes(bb)',
                 write='$name.write16Bytes(bb)',
-                default='OFPortMap.NONE')
+                default='OFPortBitmap.NONE')
 
 
 port_speed = JType("PortSpeed")
@@ -421,7 +421,7 @@
         'of_wc_bmap_t': flow_wildcards,
         'of_oxm_t': oxm,
         'of_meter_features_t': meter_features,
-        'of_bitmap_128': port_map
+        'of_bitmap_128_t': port_bitmap
         }
 
 ## Map that defines exceptions from the standard loxi->java mapping scheme
@@ -476,7 +476,8 @@
         'of_oxm_mpls_tc' : { 'value' : u8obj },
         'of_oxm_mpls_tc_masked' : { 'value' : u8obj, 'value_mask' : u8obj },
         
-        'of_oxm_bsn_in_ports_masked_128' : { 'value': port_map, 'value_mask': port_map },
+        'of_oxm_bsn_in_ports_128' : { 'value': port_bitmap },
+        'of_oxm_bsn_in_ports_128_masked' : { 'value': port_bitmap, 'value_mask': port_bitmap },
 
         'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
         'of_match_v1': { 'vlan_vid' : vlan_vid, 'vlan_pcp': vlan_pcp,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index 08a368d..3eaaa95 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -13,7 +13,7 @@
 import org.projectfloodlight.openflow.types.MacAddress;
 import org.projectfloodlight.openflow.types.OFMetadata;
 import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.OFPortMap;
+import org.projectfloodlight.openflow.types.OFPortBitmap;
 import org.projectfloodlight.openflow.types.OFValueType;
 import org.projectfloodlight.openflow.types.TransportPort;
 import org.projectfloodlight.openflow.types.U32;
@@ -171,8 +171,8 @@
             new MatchField<U8>("mpls_tc", MatchFields.MPLS_TC,
                     new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.MPLS_UNICAST, EthType.MPLS_MULTICAST));
 
-    public final static MatchField<OFPortMap> BSN_IN_PORTS_MASKED_128 =
-            new MatchField<OFPortMap>("bsn_in_port_masked_128", MatchFields.BSN_IN_PORTS_MASKED_128);
+    public final static MatchField<OFPortBitmap> BSN_IN_PORTS_128 =
+            new MatchField<OFPortBitmap>("bsn_in_port_masked_128", MatchFields.BSN_IN_PORTS_128);
 
     public String getName() {
         return name;
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index c73530b..0de5caf 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -38,5 +38,5 @@
     IPV6_ND_TLL,
     MPLS_LABEL,
     MPLS_TC,
-    BSN_IN_PORTS_MASKED_128
+    BSN_IN_PORTS_128
 }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitmap.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitmap.java
new file mode 100644
index 0000000..ecf9bc5
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitmap.java
@@ -0,0 +1,85 @@
+package org.projectfloodlight.openflow.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+public class OFPortBitmap implements OFValueType<OFPortBitmap> {
+
+    static final int LENGTH = 16;
+
+    private final long raw1; // MSBs (ports 64-127)
+    private final long raw2; // LSBs (ports 0-63)
+
+    public static final OFPortBitmap ALL = new OFPortBitmap(-1, -1);
+    public static final OFPortBitmap NONE = new OFPortBitmap(0, 0);
+
+    private OFPortBitmap(long raw1, long raw2) {
+        this.raw1 = raw1;
+        this.raw2 = raw2;
+    }
+
+    static OFPortBitmap of(long raw1, long raw2) {
+        if (raw1 == -1 && raw2 == -1)
+            return ALL;
+        if (raw1 == 0 && raw2 == 0)
+            return NONE;
+        return new OFPortBitmap(raw1, raw2);
+    }
+
+    @Override
+    public int getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public OFPortBitmap applyMask(OFPortBitmap mask) {
+        return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof OFPortBitmap))
+            return false;
+        OFPortBitmap other = (OFPortBitmap)obj;
+        return (other.raw1 == this.raw1 && other.raw2 == this.raw2);
+    }
+
+    @Override
+    public int hashCode() {
+        return (int)(31 * raw1 + raw2);
+    }
+
+    protected static boolean isBitOn(long raw1, long raw2, int bit) {
+        if (bit < 0 || bit >= 128)
+            throw new IndexOutOfBoundsException("Port number is out of bounds");
+        long word;
+        if (bit < 64) {
+            word = raw2; // ports 0-63
+        } else {
+            word = raw1; // ports 64-127
+            bit -= 64;
+        }
+        return (word & ((long)1 << bit)) != 0;
+    }
+
+
+    public void write16Bytes(ChannelBuffer cb) {
+        cb.writeLong(raw1);
+        cb.writeLong(raw2);
+    }
+
+    public static OFPortBitmap read16Bytes(ChannelBuffer cb) {
+        long raw1 = cb.readLong();
+        long raw2 = cb.readLong();
+        return of(raw1, raw2);
+    }
+
+    public boolean isOn(OFPort port) {
+        return isBitOn(raw1, raw2, port.getPortNumber());
+    }
+
+    @Override
+    public String toString() {
+        return (String.format("%64s", Long.toBinaryString(raw2)) + String.format("%64s", Long.toBinaryString(raw1))).replaceAll(" ", "0");
+    }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortMap.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortMap.java
index b666782..0454d39 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortMap.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortMap.java
@@ -1,64 +1,14 @@
 package org.projectfloodlight.openflow.types;
 
-import org.jboss.netty.buffer.ChannelBuffer;
 
-public class OFPortMap implements OFValueType<OFPortMap> {
+public class OFPortMap extends Masked<OFPortBitmap> {
 
-    static final int LENGTH = 16;
-
-    private final long raw1;
-    private final long raw2;
-
-    public static final OFPortMap NONE = of(0, 0);
-
-    private OFPortMap(long raw1, long raw2) {
-        this.raw1 = raw1;
-        this.raw2 = raw2;
-
-    }
-
-    public static OFPortMap of(long raw1, long raw2) {
-        if (raw1 == 0 && raw2 == 0)
-            return NONE;
-        return new OFPortMap(raw1, raw2);
-    }
-
-    @Override
-    public int getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public OFPortMap applyMask(OFPortMap mask) {
-        return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2);
-    }
-
-    public void write16Bytes(ChannelBuffer cb) {
-        cb.writeLong(raw1);
-        cb.writeLong(raw2);
-    }
-
-    public static OFPortMap read16Bytes(ChannelBuffer cb) {
-        long raw1 = cb.readLong();
-        long raw2 = cb.readLong();
-        return of(raw1, raw2);
-    }
-
-    private static boolean isBitOn(long raw1, long raw2, int bit) {
-        if (bit < 0 || bit >= 128)
-            throw new IndexOutOfBoundsException("Port number is out of bounds");
-        long word;
-        if (bit < 64) {
-            word = raw1;
-        } else {
-            word = raw2;
-            bit -= 64;
-        }
-        return (word & ((long)1 << bit)) != 0;
+    private OFPortMap(OFPortBitmap mask) {
+        super(OFPortBitmap.NONE, mask);
     }
 
     public boolean isOn(OFPort port) {
-        return isBitOn(raw1, raw2, port.getPortNumber());
+        return this.mask.isOn(port);
     }
 
     public static OFPortMap ofPorts(OFPort... ports) {
@@ -70,8 +20,16 @@
     }
 
     @Override
-    public String toString() {
-        return (String.format("%64s", Long.toBinaryString(raw2)) + String.format("%64s", Long.toBinaryString(raw1))).replaceAll(" ", "0");
+    public boolean equals(Object obj) {
+        if (!(obj instanceof OFPortMap))
+            return false;
+        OFPortMap other = (OFPortMap)obj;
+        return (other.value.equals(this.value) && other.mask.equals(this.mask));
+    }
+
+    @Override
+    public int hashCode() {
+        return 619 * mask.hashCode() + 257 * value.hashCode();
     }
 
     public static class Builder {
@@ -82,7 +40,7 @@
         }
 
         public boolean isOn(OFPort port) {
-            return isBitOn(raw1, raw2, port.getPortNumber());
+            return OFPortBitmap.isBitOn(raw1, raw2, port.getPortNumber());
         }
 
         public Builder set(OFPort port) {
@@ -90,9 +48,9 @@
             if (bit < 0 || bit >= 128)
                 throw new IndexOutOfBoundsException("Port number is out of bounds");
             if (bit < 64) {
-                raw1 |= ((long)1 << bit);
+                raw2 |= ((long)1 << bit);
             } else {
-                raw2 |= ((long)1 << (bit - 64));
+                raw1 |= ((long)1 << (bit - 64));
             }
             return this;
         }
@@ -102,15 +60,15 @@
             if (bit < 0 || bit >= 128)
                 throw new IndexOutOfBoundsException("Port number is out of bounds");
             if (bit < 64) {
-                raw1 &= ~((long)1 << bit);
+                raw2 &= ~((long)1 << bit);
             } else {
-                raw2 &= ~((long)1 << (bit - 64));
+                raw1 &= ~((long)1 << (bit - 64));
             }
             return this;
         }
 
         public OFPortMap build() {
-            return OFPortMap.of(raw1, raw2);
+            return new OFPortMap(OFPortBitmap.of(raw1, raw2));
         }
     }
 
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortMapTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortMapTest.java
index 8f31c3b..7a75248 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortMapTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortMapTest.java
@@ -24,7 +24,7 @@
 
         // Test that all ports that were added are actually on, and all other ports are off
         OFPortMap portmap = builder.build();
-        System.out.println(portmap);
+        //System.out.println(portmap);
         Boolean[] actual = new Boolean[128];
         for (int i = 0; i < 128; i++) {
             actual[i] = false;
diff --git a/java_gen/templates/unit_test.java b/java_gen/templates/unit_test.java
index 47dcc24..7fb52bb 100644
--- a/java_gen/templates/unit_test.java
+++ b/java_gen/templates/unit_test.java
@@ -28,6 +28,7 @@
 //:: from loxi_ir import *
 //:: import itertools
 //:: import of_g
+//:: import java_gen.java_model as java_model
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
@@ -40,22 +41,25 @@
 import static org.junit.Assert.*;
 
 public class ${test.name} {
+    //:: factory = java_model.model.factory_of(test.interface)
     //:: var_type = msg.interface.name
     //:: var_name = msg.interface.variable_name
-    OFFactory factory;
+    //:: builder_method = factory.method_name(msg.interface)
+    //:: factory_impl = java_model.model.factory_of(test.interface).of_version(test.java_class.version).name
+    ${factory.name if factory.name is not None else OFFactory} factory;
 
     final static byte[] ${msg.constant_name}_SERIALIZED =
         new byte[] { ${", ".join("%s0x%x" % (("" if ord(c)<128 else "(byte) "),  ord(c)) for c in test_data["binary"] ) } };
 
     @Before
     public void setup() {
-        factory = OFFactories.getFactory(OFVersion.${version.constant_version});
+        factory = ${factory_impl + ".INSTANCE" if factory_impl is not None else "OFFactories.getFactory(OFVersion." + version.constant_version + ")"};
     }
 
     //:: if "java" in test_data:
     @Test
     public void testWrite() {
-        ${var_type}.Builder builder = factory.build${var_type[2:]}();
+        ${var_type}.Builder builder = factory.${builder_method}();
         ${test_data["java"]};
         ${var_type} ${var_name} = builder.build();
         ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
@@ -68,7 +72,7 @@
 
     @Test
     public void testRead() throws Exception {
-        ${var_type}.Builder builder = factory.build${var_type[2:]}();
+        ${var_type}.Builder builder = factory.${builder_method}();
         ${test_data["java"]};
         ${var_type} ${var_name}Built = builder.build();
 
diff --git a/test_data/of13/oxm_bsn_in_ports_masked_128.data b/test_data/of13/oxm_bsn_in_ports_masked_128.data
index 0a8e70b..8d5ec31 100644
--- a/test_data/of13/oxm_bsn_in_ports_masked_128.data
+++ b/test_data/of13/oxm_bsn_in_ports_masked_128.data
@@ -18,3 +18,7 @@
     of_bitmap_128_t bmap = { 0x8000000100000000, 0x00000000020001 };
     of_oxm_bsn_in_ports_128_masked_value_mask_set(obj, bmap);
 }
+-- java
+OFPortMap portmap = OFPortMap.ofPorts(OFPort.of(0), OFPort.of(17), OFPort.of(96), OFPort.of(127));
+builder.setValue(portmap.getValue());
+builder.setMask(portmap.getMask());