1. Added more match fields for ICMPv6 and MPLS
2. Fixes to avoid unnecessary warnings in generated code
3. Added the general method Match getMatch() to factories and made unit tests use it
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 65dac74..0225af5 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -112,7 +112,22 @@
                 "OFOxmIpv6Dst":             OxmMapEntry("IPv6", "IPV6_DST", False),
                 "OFOxmIpv6DstMasked":       OxmMapEntry("IPv6", "IPV6_DST", True),
                 "OFOxmIpv6Flabel":          OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", False),
-                "OFOxmIpv6FlabelMasked":    OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True) }
+                "OFOxmIpv6FlabelMasked":    OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", True),
+                "OFOxmIcmpv6Type":          OxmMapEntry("U8", "ICMPV6_TYPE", False),
+                "OFOxmIcmpv6TypeMasked":    OxmMapEntry("U8", "ICMPV6_TYPE", True),
+                "OFOxmIcmpv6Code":          OxmMapEntry("U8", "ICMPV6_CODE", False),
+                "OFOxmIcmpv6CodeMasked":    OxmMapEntry("U8", "ICMPV6_CODE", True),
+                "OFOxmIpv6NdTarget":        OxmMapEntry("IPv6", "IPV6_ND_TARGET", False),
+                "OFOxmIpv6NdTargetMasked":  OxmMapEntry("IPv6", "IPV6_ND_TARGET", True),
+                "OFOxmIpv6NdSll":           OxmMapEntry("MacAddress", "IPV6_ND_SLL", False),
+                "OFOxmIpv6NdSllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_SLL", True),
+                "OFOxmIpv6NdTll":           OxmMapEntry("MacAddress", "IPV6_ND_TLL", False),
+                "OFOxmIpv6NdTllMasked":     OxmMapEntry("MacAddress", "IPV6_ND_TLL", True),
+                "OFOxmMplsLabel":           OxmMapEntry("U32", "MPLS_LABEL", False),
+                "OFOxmMplsLabelMasked":     OxmMapEntry("U32", "MPLS_LABEL", True),
+                "OFOxmMplsTc":              OxmMapEntry("U8", "MPLS_TC", False),
+                "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True)
+                }
 
     @property
     @memoize
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 333d25d..3e217e6 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
@@ -15,6 +15,8 @@
 import org.projectfloodlight.openflow.types.OFPort;
 import org.projectfloodlight.openflow.types.OFValueType;
 import org.projectfloodlight.openflow.types.TransportPort;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U8;
 import org.projectfloodlight.openflow.types.VlanPcp;
 import org.projectfloodlight.openflow.types.VlanVid;
 
@@ -140,6 +142,34 @@
             new MatchField<IPv6FlowLabel>("ipv6_flabel", MatchFields.IPV6_FLABEL,
                     new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6));
 
+    public final static MatchField<U8> ICMPV6_TYPE =
+            new MatchField<U8>("icmpv6_type", MatchFields.ICMPV6_TYPE,
+                    new Prerequisite<IpProtocol>(MatchField.IP_PROTO, IpProtocol.IP_PROTO_IPv6_ICMP));
+
+    public final static MatchField<U8> ICMPV6_CODE =
+            new MatchField<U8>("icmpv6_code", MatchFields.ICMPV6_CODE,
+                    new Prerequisite<IpProtocol>(MatchField.IP_PROTO, IpProtocol.IP_PROTO_IPv6_ICMP));
+
+    public final static MatchField<IPv6> IPV6_ND_TARGET =
+            new MatchField<IPv6>("ipv6_nd_target", MatchFields.IPV6_ND_TARGET,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)135), U8.of((short)136)));
+
+    public final static MatchField<MacAddress> IPV6_ND_SLL =
+            new MatchField<MacAddress>("ipv6_nd_sll", MatchFields.IPV6_ND_SLL,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)135)));
+
+    public final static MatchField<MacAddress> IPV6_ND_TLL =
+            new MatchField<MacAddress>("ipv6_nd_tll", MatchFields.IPV6_ND_TLL,
+                    new Prerequisite<U8>(MatchField.ICMPV6_TYPE, U8.of((short)136)));
+
+    public final static MatchField<U32> MPLS_LABEL =
+            new MatchField<U32>("mpls_label", MatchFields.MPLS_LABEL,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_MPLS_UNICAST, EthType.ETH_TYPE_MPLS_MULTICAST));
+
+    public final static MatchField<U8> MPLS_TC =
+            new MatchField<U8>("mpls_tc", MatchFields.MPLS_TC,
+                    new Prerequisite<EthType>(MatchField.ETH_TYPE, EthType.ETH_TYPE_MPLS_UNICAST, EthType.ETH_TYPE_MPLS_MULTICAST));
+
     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 2fc10ae..7deb9af 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
@@ -31,4 +31,11 @@
     IPV6_SRC,
     IPV6_DST,
     IPV6_FLABEL,
+    ICMPV6_TYPE,
+    ICMPV6_CODE,
+    IPV6_ND_TARGET,
+    IPV6_ND_SLL,
+    IPV6_ND_TLL,
+    MPLS_LABEL,
+    MPLS_TC
 }
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 2dc88fb..93ab558 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -145,7 +145,12 @@
     static class Reader implements OFMessageReader<${msg.interface.name}> {
         @Override
         public ${msg.interface.name} readFrom(ChannelBuffer bb) throws OFParseError {
+//:: for prop in msg.members:
+//:: if not prop.is_virtual and (prop.is_length_value or prop.is_field_length_value):
             int start = bb.readerIndex();
+//::     break
+//:: #endif
+//:: #endfor
 //:: fields_with_length_member = {}
 //:: for prop in msg.members:
 //:: if prop.is_virtual:
@@ -203,7 +208,9 @@
     static class Writer implements OFMessageWriter<${impl_class}> {
         @Override
         public void write(ChannelBuffer bb, ${impl_class} message) {
+//:: if not msg.is_fixed_length:
             int startIndex = bb.writerIndex();
+//:: #endif
 //:: fields_with_length_member = {}
 //:: for prop in msg.members:
 //:: if prop.c_name in fields_with_length_member:
@@ -278,7 +285,9 @@
             return false;
         if (getClass() != obj.getClass())
             return false;
+        //:: if len(msg.data_members) > 0:
         ${msg.name} other = (${msg.name}) obj;
+        //:: #endif
 
         //:: for prop in msg.data_members:
         //:: if prop.java_type.is_primitive:
@@ -300,7 +309,9 @@
 
     @Override
     public int hashCode() {
+        //:: if len(msg.data_members) > 0:
         final int prime = 31;
+        //:: #endif
         int result = 1;
 
         //:: for prop in msg.data_members:
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
index adf5df1..86b092a 100644
--- a/java_gen/templates/of_factory_class.java
+++ b/java_gen/templates/of_factory_class.java
@@ -27,12 +27,15 @@
 //::
 //:: import itertools
 //:: import of_g
+//:: import re
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
 
 package ${factory.package};
 
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+
 //:: include("_imports.java")
 
 public class ${factory.name} implements ${factory.interface.name} {
@@ -45,10 +48,13 @@
     }
     //:: #endfor
 
+//:: general_get_match_func_written = False
 //:: for i in factory.interface.members:
     //:: if i.is_virtual:
     //::    continue
     //:: #endif
+    //:: is_match_object = re.match('OFMatch.*', i.name) # i.has_version(factory.version) and model.generate_class(i.versioned_class(factory.version)) and i.versioned_class(factory.version).interface.parent_interface == 'Match'
+    //:: unsupported_match_object = is_match_object and not i.has_version(factory.version)
 
     //:: if len(i.writeable_members) > 0:
     public ${i.name}.Builder ${factory.interface.method_name(i, builder=True)}() {
@@ -59,6 +65,12 @@
         //:: #endif
     }
     //:: #endif
+    //:: if not general_get_match_func_written and is_match_object and not unsupported_match_object:
+    public Match.Builder buildMatch() {
+        return new ${i.versioned_class(factory.version).name}.Builder();
+    }
+    //::     general_get_match_func_written = True
+    //:: #endif
     //:: if len(i.writeable_members) <= 2:
     public ${i.name} ${factory.interface.method_name(i, builder=False)}(${", ".join("%s %s" % (p.java_type.public_type, p.name) for p in i.writeable_members)}) {
         //::   if i.has_version(factory.version) and model.generate_class(i.versioned_class(factory.version)):
diff --git a/java_gen/templates/of_factory_interface.java b/java_gen/templates/of_factory_interface.java
index 329539f..634362d 100644
--- a/java_gen/templates/of_factory_interface.java
+++ b/java_gen/templates/of_factory_interface.java
@@ -27,6 +27,7 @@
 //::
 //:: import itertools
 //:: import of_g
+//:: import re
 //:: include('_copyright.java')
 
 //:: include('_autogen.java')
@@ -52,6 +53,9 @@
     ${i.name} ${factory.method_name(i, builder=False )}(${", ".join("%s %s" % (p.java_type.public_type, p.name) for p in i.writeable_members)});
     //:: #endif
 //:: #endfor
+//:: if factory.name == 'OFFactory':
+    Match.Builder buildMatch();
+//:: #endif
 
     OFMessageReader<${factory.base_class}> getReader();
 
diff --git a/java_gen/templates/of_virtual_class.java b/java_gen/templates/of_virtual_class.java
index 6237b8c..fc6a6c0 100644
--- a/java_gen/templates/of_virtual_class.java
+++ b/java_gen/templates/of_virtual_class.java
@@ -51,7 +51,7 @@
 
     static class Reader implements OFMessageReader<${msg.interface.inherited_declaration()}> {
         @Override
-        public ${msg.interface.name} readFrom(ChannelBuffer bb) throws OFParseError {
+        public ${msg.interface.inherited_declaration()} readFrom(ChannelBuffer bb) throws OFParseError {
 //:: if msg.is_fixed_length:
             if(bb.readableBytes() < LENGTH)
 //:: else:
diff --git a/test_data/of13/flow_add.data b/test_data/of13/flow_add.data
index 666da50..ba6e84f 100644
--- a/test_data/of13/flow_add.data
+++ b/test_data/of13/flow_add.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_delete.data b/test_data/of13/flow_delete.data
index 22f07c2..6ae6ad4 100644
--- a/test_data/of13/flow_delete.data
+++ b/test_data/of13/flow_delete.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_delete_strict.data b/test_data/of13/flow_delete_strict.data
index ab21088..b5a96ce 100644
--- a/test_data/of13/flow_delete_strict.data
+++ b/test_data/of13/flow_delete_strict.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_modify.data b/test_data/of13/flow_modify.data
index 8218b96..06ac626 100644
--- a/test_data/of13/flow_modify.data
+++ b/test_data/of13/flow_modify.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)
diff --git a/test_data/of13/flow_modify_strict.data b/test_data/of13/flow_modify_strict.data
index 3f0a074..ebdf2f0 100644
--- a/test_data/of13/flow_modify_strict.data
+++ b/test_data/of13/flow_modify_strict.data
@@ -85,7 +85,7 @@
     .setOutGroup(8)
     .setFlags(0)
     .setMatch(
-        factory.buildMatchV3()
+        factory.buildMatch()
             .setMasked(MatchField.IN_PORT, OFPort.of(4), OFPort.of(5))
             .setExact(MatchField.ETH_TYPE, EthType.ETH_TYPE_IPv6)
             .setExact(MatchField.IP_PROTO, IpProtocol.IP_PROTO_TCP)