Merge into master from pull request #81:
a bunch of smaller improvements (https://github.com/floodlight/loxigen/pull/81)
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index f631483..81ce8fe 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -671,29 +671,30 @@
 
     @property
     def virtual_members(self):
+        virtual_members = []
         if self.name == "OFOxm":
-            return (
+            virtual_members += [
                     JavaVirtualMember(self, "value", java_type.generic_t),
                     JavaVirtualMember(self, "mask", java_type.generic_t),
                     JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype("T")),
                     JavaVirtualMember(self, "masked", java_type.boolean),
-                   )
+                   ]
         elif self.parent_interface and self.parent_interface.startswith("OFOxm"):
             field_type = java_type.make_match_field_jtype(model.oxm_map[self.name].type_name) \
                 if self.name in model.oxm_map \
                 else java_type.make_match_field_jtype()
 
-            return (
+            virtual_members += [
                     JavaVirtualMember(self, "matchField", field_type),
                     JavaVirtualMember(self, "masked", java_type.boolean),
-                   ) \
-                   + \
-                   (
-                           ( JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type), ) if not find(lambda x: x.name == "mask", self.ir_model_members) else
-                    ()
-                   )
-        else:
-            return ()
+                   ]
+            if not find(lambda x: x.name == "mask", self.ir_model_members):
+                virtual_members.append(JavaVirtualMember(self, "mask", find(lambda x: x.name == "value", self.ir_model_members).java_type))
+
+        if not find(lambda m: m.name == "version", self.ir_model_members):
+            virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version))
+
+        return tuple(virtual_members)
 
     @property
     @memoize
@@ -806,26 +807,31 @@
         return self.ir_model_members + self.virtual_members
 
     @property
+    @memoize
     def ir_model_members(self):
         members = [ JavaMember.for_of_member(self, of_member) for of_member in self.ir_class.members ]
         return tuple(members)
 
     @property
     def virtual_members(self):
+        virtual_members = []
         if self.interface.parent_interface and self.interface.parent_interface.startswith("OFOxm"):
             if self.interface.name in model.oxm_map:
                 oxm_entry = model.oxm_map[self.interface.name]
-                return (
+                virtual_members += [
                     JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(oxm_entry.type_name), "MatchField.%s" % oxm_entry.value),
                     JavaVirtualMember(self, "masked", java_type.boolean, "true" if oxm_entry.masked else "false"),
-                   )
+                   ]
             else:
-                return (
+                virtual_members += [
                     JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(), "null"),
                     JavaVirtualMember(self, "masked", java_type.boolean, "false"),
-                   )
-        else:
-            return ()
+                   ]
+
+        if not find(lambda m: m.name == "version", self.ir_model_members):
+            virtual_members.append(JavaVirtualMember(self, "version", java_type.of_version, "OFVersion.%s" % self.version.constant_version))
+
+        return tuple(virtual_members)
 
     def all_versions(self):
         return [ JavaOFVersion(int_version)
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index f50d29a..698d869 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -251,6 +251,9 @@
 of_port = JType("OFPort") \
          .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ANY") \
          .op(version=ANY, read="OFPort.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFPort.ANY")
+# the same OFPort, but with a default value of ZERO, only for OF10 match
+of_port_match_v1 = JType("OFPort") \
+         .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ZERO")
 actions_list = JType('List<OFAction>') \
         .op(read='ChannelUtils.readList(bb, $length, OFActionVer$version.READER)',
             write='ChannelUtils.writeList(bb, $name);',
@@ -280,7 +283,8 @@
             default="new byte[0]");
 of_match = JType('Match') \
         .op(read='ChannelUtilsVer$version.readOFMatch(bb)', \
-            write='$name.writeTo(bb)');
+            write='$name.writeTo(bb)',
+            default="OFFactoryVer$version.MATCH_WILDCARD_ALL");
 flow_mod_cmd = JType('OFFlowModCommand', 'short') \
         .op(version=1, read="bb.readShort()", write="bb.writeShort($name)") \
         .op(version=ANY, read="bb.readByte()", write="bb.writeByte($name)")
@@ -389,6 +393,8 @@
         .op(read='TableId.readByte(bb)',
             write='$name.writeByte(bb)',
             default='TableId.ALL')
+of_version = JType("OFVersion", 'byte') \
+            .op(read='bb.readByte()', write='bb.writeByte($name)')
 
 port_speed = JType("PortSpeed")
 error_type = JType("OFErrorType")
@@ -486,7 +492,8 @@
         'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
         'of_match_v1': { 'vlan_vid' : vlan_vid, 'vlan_pcp': vlan_pcp,
                 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
-                'tcp_src': transport_port, 'tcp_dst': transport_port
+                'tcp_src': transport_port, 'tcp_dst': transport_port,
+                'in_port': of_port_match_v1
                 }
 }
 
@@ -557,8 +564,7 @@
     elif field_name == "table_id" and c_type == "uint8_t":
         return table_id
     elif field_name == "version" and c_type == "uint8_t":
-        return JType("OFVersion", 'byte') \
-            .op(read='bb.readByte()', write='bb.writeByte($name)')
+        return of_version
     elif field_name == "buffer_id" and c_type == "uint32_t":
         return JType("OFBufferId") \
             .op(read="OFBufferId.of(bb.readInt())", write="bb.writeInt($name.getInt())", default="OFBufferId.NO_BUFFER")
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFObject.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFObject.java
index 07759d7..852b803 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFObject.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFObject.java
@@ -5,4 +5,5 @@
  * Base interface of all OpenFlow objects (e.g., messages, actions, stats, etc.)
  */
 public interface OFObject extends Writeable {
+    OFVersion getVersion();
 }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
index cb36d0c..0028cd8 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPort.java
@@ -87,12 +87,17 @@
      * output port). NOTE: OpenFlow 1.0 calls this 'NONE'
      */
     public final static OFPort ANY = new NamedPort(OFPP_ANY_INT, "any");
+    /** the wildcarded default for OpenFlow 1.0 (value: 0). Elsewhere in OpenFlow
+     *  we need "ANY" as the default
+     */
+    public static final OFPort ZERO = OFPort.of(0);
 
     public static final OFPort NO_MASK = OFPort.of(0xFFFFFFFF);
-    public static final OFPort FULL_MASK = OFPort.of(0x0);
+    public static final OFPort FULL_MASK = ZERO;
 
     /** cache of frequently used ports */
     private static class PrecachedPort {
+        private final static OFPort p0 = new OFPort(0);
         private final static OFPort p1 = new OFPort(1);
         private final static OFPort p2 = new OFPort(2);
         private final static OFPort p3 = new OFPort(3);
@@ -160,6 +165,8 @@
      */
     public static OFPort ofInt(final int portNumber) {
         switch (portNumber) {
+            case 0:
+                return PrecachedPort.p0;
             case 1:
                 return PrecachedPort.p1;
             case 2:
@@ -302,6 +309,8 @@
      */
     public static OFPort ofShort(final short portNumber) {
         switch (portNumber) {
+            case 0:
+                return PrecachedPort.p0;
             case 1:
                 return PrecachedPort.p1;
             case 2:
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 8a8d09d..829d257 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -56,6 +56,13 @@
 //:: for prop in msg.data_members:
     private final ${prop.java_type.public_type} ${prop.name};
 //:: #endfor
+//
+//:: if all(prop.default_value for prop in msg.data_members):
+    // Immutable default instance
+    final static ${impl_class} DEFAULT = new ${impl_class}(
+        ${", ".join(prop.default_name for prop in msg.data_members)}
+    );
+//:: #endif
 
     //:: if msg.data_members:
     // package private constructor - used by readers, builders, and factory
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
index 5263226..395b524 100644
--- a/java_gen/templates/of_factory_class.java
+++ b/java_gen/templates/of_factory_class.java
@@ -72,6 +72,12 @@
     public Match.Builder buildMatch() {
         return new ${i.versioned_class(factory.version).name}.Builder();
     }
+
+    final static Match MATCH_WILDCARD_ALL = ${i.versioned_class(factory.version).name}.DEFAULT;
+
+    public Match matchWildcardAll() {
+        return MATCH_WILDCARD_ALL;
+    }
     //::     general_get_match_func_written = True
     //:: #endif
     //:: if len(i.writeable_members) <= 2:
diff --git a/java_gen/templates/of_factory_interface.java b/java_gen/templates/of_factory_interface.java
index 48ea34a..6a92e96 100644
--- a/java_gen/templates/of_factory_interface.java
+++ b/java_gen/templates/of_factory_interface.java
@@ -55,6 +55,7 @@
 //:: #endfor
 //:: if factory.name == 'OFFactory':
     Match.Builder buildMatch();
+    Match matchWildcardAll();
 //:: #endif
 
     OFMessageReader<${factory.base_class}> getReader();