Merge branch 'master' of https://github.com/floodlight/loxigen
diff --git a/.abat-automerge b/.abat-automerge
index 36e8739..772134b 100755
--- a/.abat-automerge
+++ b/.abat-automerge
@@ -4,3 +4,7 @@
 
 ln -sf ../../.hooks/pre-commit .git/hooks/pre-commit
 make all check-all
+
+if [[ ${ARTIFACT_REPO_URL-} ]]; then
+    ./.build/push-artifacts.sh ${ARTIFACT_REPO_URL}
+fi
diff --git a/.build/push-artifacts.sh b/.build/push-artifacts.sh
new file mode 100755
index 0000000..fd607eb
--- /dev/null
+++ b/.build/push-artifacts.sh
@@ -0,0 +1,60 @@
+#!/bin/bash -eu
+
+# Push the loxigen artifacts to a dedicated git repository,
+# along with a nice commit message and a tag
+
+ARTIFACT_REPO_URL="$1"
+if [[ ! $ARTIFACT_REPO_URL ]]; then
+    echo "Call syntax: $0 <artifact_repo_url>" >&2
+    exit 1
+fi
+
+ARTIFACT_REPO=$(mktemp -d --tmpdir "push-artifacts-repo.XXXXXXX")
+
+git clone ${ARTIFACT_REPO_URL} ${ARTIFACT_REPO}
+find ${ARTIFACT_REPO} -mindepth 1 -maxdepth 1 -type d \! -name '.*' -print0 | xargs -0 rm -r
+make LOXI_OUTPUT_DIR=${ARTIFACT_REPO} clean all
+
+loxi_head=$(git rev-parse HEAD)
+last_loxi_log=$(git log --format=oneline -1)
+git_log_file=$(mktemp --tmpdir "git-log-file.XXXXXXX")
+
+last_loxi_revision=""
+
+if [[ -e "${ARTIFACT_REPO}/loxi-revision" ]]; then
+    last_loxi_revision=$(cat "${ARTIFACT_REPO}/loxi-revision" |  cut -d ' ' -f 1)
+    if [[ $(git cat-file -t "$last_loxi_revision" 2>/dev/null) != "commit" ]]; then
+        echo "Last loxi revision ${last_loxi_revision} specified in ${ARTIFACT_REPO_URL}/loxi-revision not found in loxigen repo"
+        last_loxi_revision=""
+    fi
+fi
+
+if [[ $last_loxi_revision ]]; then
+    echo "Last loxi revision committed: $last_loxi_revision"
+    git log $last_loxi_revision..${loxi_head} >>$git_log_file
+    loxi_github_url="https://github.com/floodlight/loxigen/compare/${last_loxi_revision}...${loxi_head}"
+else
+    echo "No Previous loxi revision info found"
+    git log -1 HEAD >>$git_log_file
+    loxi_github_url="https://github.com/floodlight/loxigen/commit/${loxi_head}"
+fi
+
+
+(
+    set -xe
+    cd $ARTIFACT_REPO
+    echo $last_loxi_log >loxi-revision
+    git add -A
+
+    (
+       echo "Artifacts from ${loxi_github_url}"
+       echo
+       echo "Loxigen Head commit floodlight/loxigen@${loxi_head}"
+       cat $git_log_file
+    ) | git commit --file=-
+
+    git tag -a -f "loxi/${loxi_head}" -m "Tag Loxigen Revision ${loxi_head}"
+    git push
+)
+
+rm -rf ${ARTIFACT_REPO}
diff --git a/Makefile b/Makefile
index 4712a04..fc9c6e4 100644
--- a/Makefile
+++ b/Makefile
@@ -43,9 +43,10 @@
                                  \! \( -name '*.cache' -o -name '.*' \))
 INPUT_FILES = $(wildcard openflow_input/*)
 TEST_DATA = $(shell find test_data -name '*.data')
-OPENFLOWJ_WORKSPACE = openflowj-loxi
+OPENFLOWJ_OUTPUT_DIR = ${LOXI_OUTPUT_DIR}/openflowj
+OPENFLOWJ_ECLIPSE_WORKSPACE = openflowj-loxi
 
-all: c python java
+all: c python java wireshark
 
 c: .loxi_ts.c
 
@@ -69,20 +70,35 @@
 	@echo "HTML documentation output to ${LOXI_OUTPUT_DIR}/pyloxi-doc"
 
 java: .loxi_ts.java
-	mkdir -p ${OPENFLOWJ_WORKSPACE}
-	ln -sf ../java_gen/pre-written/pom.xml ${OPENFLOWJ_WORKSPACE}/pom.xml
-	ln -sf ../java_gen/pre-written/LICENSE.txt ${OPENFLOWJ_WORKSPACE}/LICENSE.txt
-	ln -sf ../java_gen/pre-written/src ${OPENFLOWJ_WORKSPACE}/src
-	rsync --checksum --delete -rv ${LOXI_OUTPUT_DIR}/openflowj/src/ ${OPENFLOWJ_WORKSPACE}/gen-src
+	@rsync -rt java_gen/pre-written/ ${LOXI_OUTPUT_DIR}/openflowj/
+	@if [ -e ${OPENFLOWJ_ECLIPSE_WORKSPACE} ]; then \
+		rsync --checksum --delete -rv ${LOXI_OUTPUT_DIR}/openflowj/gen-src/ ${OPENFLOWJ_ECLIPSE_WORKSPACE}/gen-src; \
+	fi
 
 .loxi_ts.java: ${LOXI_PY_FILES} ${LOXI_TEMPLATE_FILES} ${INPUT_FILES} ${TEST_DATA}
 	./loxigen.py --install-dir=${LOXI_OUTPUT_DIR} --lang=java
 	touch $@
 
-java-eclipse: java
-	cd ${OPENFLOWJ_WORKSPACE} && mvn eclipse:eclipse
+eclipse-workspace:
+	mkdir -p ${OPENFLOWJ_ECLIPSE_WORKSPACE}
+	ln -sf ../java_gen/pre-written/pom.xml ${OPENFLOWJ_ECLIPSE_WORKSPACE}/pom.xml
+	ln -sf ../java_gen/pre-written/LICENSE.txt ${OPENFLOWJ_ECLIPSE_WORKSPACE}/LICENSE.txt
+	ln -sf ../java_gen/pre-written/src ${OPENFLOWJ_ECLIPSE_WORKSPACE}
+	cd ${OPENFLOWJ_ECLIPSE_WORKSPACE} && mvn eclipse:eclipse
 	# Unfortunately, mvn eclipse:eclipse resolves the symlink, which doesn't work with eclipse
-	cd ${OPENFLOWJ_WORKSPACE} && perl -pi -e 's{<classpathentry kind="src" path="[^"]*/java_gen/pre-written/src/}{<classpathentry kind="src" path="src/}' .classpath
+	cd ${OPENFLOWJ_ECLIPSE_WORKSPACE} && perl -pi -e 's{<classpathentry kind="src" path="[^"]*/java_gen/pre-written/src/}{<classpathentry kind="src" path="src/}' .classpath
+
+check-java: java
+	cd ${OPENFLOWJ_OUTPUT_DIR} && mvn compile test-compile test
+
+package-java: java
+	cd ${OPENFLOWJ_OUTPUT_DIR} && mvn package
+
+deploy-java: java
+	cd ${OPENFLOWJ_OUTPUT_DIR} && mvn deploy
+
+install-java: java
+	cd ${OPENFLOWJ_OUTPUT_DIR} && mvn install
 
 wireshark: .loxi_ts.wireshark
 
@@ -119,18 +135,6 @@
 	make -C ${LOXI_OUTPUT_DIR}/locitest
 	${LOXI_OUTPUT_DIR}/locitest/locitest
 
-check-java: java
-	cd ${OPENFLOWJ_WORKSPACE} && mvn compile test-compile test
-
-package-java: java
-	cd ${OPENFLOWJ_WORKSPACE} && mvn package
-
-deploy-java: java
-	cd ${OPENFLOWJ_WORKSPACE} && mvn deploy
-
-install-java: java
-	cd ${OPENFLOWJ_WORKSPACE} && mvn install
-
 pylint:
 	pylint -E ${LOXI_PY_FILES}
 
diff --git a/c_gen/templates/loci_show.h b/c_gen/templates/loci_show.h
index 04d863f..c61866c 100644
--- a/c_gen/templates/loci_show.h
+++ b/c_gen/templates/loci_show.h
@@ -362,5 +362,6 @@
 #define LOCI_SHOW_u16_partner_port_priority(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
 #define LOCI_SHOW_u16_partner_port_num(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
 #define LOCI_SHOW_u16_partner_key(writer, cookie, val) LOCI_SHOW_u16(writer, cookie, val)
+#define LOCI_SHOW_u64_time_ms(writer, cookie, val) LOCI_SHOW_u64(writer, cookie, val)
 
 #endif /* _LOCI_SHOW_H_ */
diff --git a/java_gen/codegen.py b/java_gen/codegen.py
index c01ba68..9a10bdf 100644
--- a/java_gen/codegen.py
+++ b/java_gen/codegen.py
@@ -73,7 +73,7 @@
 
     def render_class(self, clazz, template, src_dir=None, **context):
         if not src_dir:
-            src_dir = "src/main/java/"
+            src_dir = "gen-src/main/java/"
 
         context['class_name'] = clazz.name
         context['package'] = clazz.package
@@ -147,7 +147,7 @@
                 unit_test = unit_tests.get_test_unit(i)
                 if unit_test.has_test_data:
                     self.render_class(clazz=unit_test,
-                            template='unit_test.java', src_dir="src/test/java",
+                            template='unit_test.java', src_dir="gen-src/test/java",
                             version=unit_test.java_class.version,
                             test=unit_test, msg=unit_test.java_class,
                             test_data=unit_test.test_data)
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 824a320..f90c1f2 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -71,95 +71,6 @@
     # interfaces that are virtual
     virtual_interfaces = set(['OFOxm', 'OFInstruction', 'OFFlowMod', 'OFBsnVport' ])
 
-    OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
-    oxm_map = { "OFOxmInPort":              OxmMapEntry("OFPort", "IN_PORT", False),
-                "OFOxmInPortMasked":        OxmMapEntry("OFPort", "IN_PORT", True),
-                "OFOxmInPhyPort":           OxmMapEntry("OFPort", "IN_PHY_PORT", False),
-                "OFOxmInPhyPortMasked":     OxmMapEntry("OFPort", "IN_PHY_PORT", True),
-                "OFOxmMetadata":            OxmMapEntry("OFMetadata", "METADATA", False),
-                "OFOxmMetadataMasked":      OxmMapEntry("OFMetadata", "METADATA", True),
-                "OFOxmEthDst":              OxmMapEntry("MacAddress", "ETH_DST", False),
-                "OFOxmEthDstMasked":        OxmMapEntry("MacAddress", "ETH_DST", True),
-                "OFOxmEthSrc":              OxmMapEntry("MacAddress", "ETH_SRC", False),
-                "OFOxmEthSrcMasked":        OxmMapEntry("MacAddress", "ETH_SRC", True),
-                "OFOxmEthType":             OxmMapEntry("EthType", "ETH_TYPE", False),
-                "OFOxmEthTypeMasked":       OxmMapEntry("EthType", "ETH_TYPE", True),
-                "OFOxmVlanVid":             OxmMapEntry("OFVlanVidMatch", "VLAN_VID", False),
-                "OFOxmVlanVidMasked":       OxmMapEntry("OFVlanVidMatch", "VLAN_VID", True),
-                "OFOxmVlanPcp":             OxmMapEntry("VlanPcp", "VLAN_PCP", False),
-                "OFOxmVlanPcpMasked":       OxmMapEntry("VlanPcp", "VLAN_PCP", True),
-                "OFOxmIpDscp":              OxmMapEntry("IpDscp", "IP_DSCP", False),
-                "OFOxmIpDscpMasked":        OxmMapEntry("IpDscp", "IP_DSCP", True),
-                "OFOxmIpEcn":               OxmMapEntry("IpEcn", "IP_ECN", False),
-                "OFOxmIpEcnMasked":         OxmMapEntry("IpEcn", "IP_ECN", True),
-                "OFOxmIpProto":             OxmMapEntry("IpProtocol", "IP_PROTO", False),
-                "OFOxmIpProtoMasked":       OxmMapEntry("IpProtocol", "IP_PROTO", True),
-                "OFOxmIpv4Src":             OxmMapEntry("IPv4Address", "IPV4_SRC", False),
-                "OFOxmIpv4SrcMasked":       OxmMapEntry("IPv4Address", "IPV4_SRC", True),
-                "OFOxmIpv4Dst":             OxmMapEntry("IPv4Address", "IPV4_DST", False),
-                "OFOxmIpv4DstMasked":       OxmMapEntry("IPv4Address", "IPV4_DST", True),
-                "OFOxmTcpSrc":              OxmMapEntry("TransportPort", "TCP_SRC", False),
-                "OFOxmTcpSrcMasked":        OxmMapEntry("TransportPort", "TCP_SRC", True),
-                "OFOxmTcpDst":              OxmMapEntry("TransportPort", "TCP_DST", False),
-                "OFOxmTcpDstMasked":        OxmMapEntry("TransportPort", "TCP_DST", True),
-                "OFOxmUdpSrc":              OxmMapEntry("TransportPort", "UDP_SRC", False),
-                "OFOxmUdpSrcMasked":        OxmMapEntry("TransportPort", "UDP_SRC", True),
-                "OFOxmUdpDst":              OxmMapEntry("TransportPort", "UDP_DST", False),
-                "OFOxmUdpDstMasked":        OxmMapEntry("TransportPort", "UDP_DST", True),
-                "OFOxmSctpSrc":             OxmMapEntry("TransportPort", "SCTP_SRC", False),
-                "OFOxmSctpSrcMasked":       OxmMapEntry("TransportPort", "SCTP_SRC", True),
-                "OFOxmSctpDst":             OxmMapEntry("TransportPort", "SCTP_DST", False),
-                "OFOxmSctpDstMasked":       OxmMapEntry("TransportPort", "SCTP_DST", True),
-                "OFOxmIcmpv4Type":          OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", False),
-                "OFOxmIcmpv4TypeMasked":    OxmMapEntry("ICMPv4Type", "ICMPV4_TYPE", True),
-                "OFOxmIcmpv4Code":          OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", False),
-                "OFOxmIcmpv4CodeMasked":    OxmMapEntry("ICMPv4Code", "ICMPV4_CODE", True),
-                "OFOxmArpOp":               OxmMapEntry("ArpOpcode", "ARP_OP", False),
-                "OFOxmArpOpMasked":         OxmMapEntry("ArpOpcode", "ARP_OP", True),
-                "OFOxmArpSpa":              OxmMapEntry("IPv4Address", "ARP_SPA", False),
-                "OFOxmArpSpaMasked":        OxmMapEntry("IPv4Address", "ARP_SPA", True),
-                "OFOxmArpTpa":              OxmMapEntry("IPv4Address", "ARP_TPA", False),
-                "OFOxmArpTpaMasked":        OxmMapEntry("IPv4Address", "ARP_TPA", True),
-                "OFOxmArpSha":              OxmMapEntry("MacAddress", "ARP_SHA", False),
-                "OFOxmArpShaMasked":        OxmMapEntry("MacAddress", "ARP_SHA", True),
-                "OFOxmArpTha":              OxmMapEntry("MacAddress", "ARP_THA", False),
-                "OFOxmArpThaMasked":        OxmMapEntry("MacAddress", "ARP_THA", True),
-                "OFOxmIpv6Src":             OxmMapEntry("IPv6Address", "IPV6_SRC", False),
-                "OFOxmIpv6SrcMasked":       OxmMapEntry("IPv6Address", "IPV6_SRC", True),
-                "OFOxmIpv6Dst":             OxmMapEntry("IPv6Address", "IPV6_DST", False),
-                "OFOxmIpv6DstMasked":       OxmMapEntry("IPv6Address", "IPV6_DST", True),
-                "OFOxmIpv6Flabel":          OxmMapEntry("IPv6FlowLabel", "IPV6_FLABEL", False),
-                "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("IPv6Address", "IPV6_ND_TARGET", False),
-                "OFOxmIpv6NdTargetMasked":  OxmMapEntry("IPv6Address", "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),
-                "OFOxmBsnInPorts128":       OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", False),
-                "OFOxmBsnInPorts128Masked": OxmMapEntry("OFBitMask128", "BSN_IN_PORTS_128", True),
-                "OFOxmBsnLagId":            OxmMapEntry("LagId", "BSN_LAG_ID", False),
-                "OFOxmBsnLagIdMasked":      OxmMapEntry("LagId", "BSN_LAG_ID", True),
-                "OFOxmBsnVrf":              OxmMapEntry("VRF", "BSN_VRF", False),
-                "OFOxmBsnVrfMasked":        OxmMapEntry("VRF", "BSN_VRF", True),
-                "OFOxmBsnGlobalVrfAllowed":          OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", False),
-                "OFOxmBsnGlobalVrfAllowedMasked":    OxmMapEntry("OFBooleanValue", "BSN_GLOBAL_VRF_ALLOWED", True),
-                "OFOxmBsnL3InterfaceClassId":        OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", False),
-                "OFOxmBsnL3InterfaceClassIdMasked":  OxmMapEntry("ClassId", "BSN_L3_INTERFACE_CLASS_ID", True),
-                "OFOxmBsnL3SrcClassId":              OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", False),
-                "OFOxmBsnL3SrcClassIdMasked":        OxmMapEntry("ClassId", "BSN_L3_SRC_CLASS_ID", True),
-                "OFOxmBsnL3DstClassId":              OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", False),
-                "OFOxmBsnL3DstClassIdMasked":        OxmMapEntry("ClassId", "BSN_L3_DST_CLASS_ID", True),
-                }
-
     # Registry of nullable properties:
     # ${java_class_name} -> set(${java_property_name})
     nullable_map = defaultdict(lambda: set(),
@@ -182,6 +93,12 @@
             OFTableConfig = (
                 MaskedEnumGroup("table_miss_flags", mask="TABLE_MISS_MASK", members=set(("TABLE_MISS_CONTROLLER", "TABLE_MISS_CONTINUE", "TABLE_MISS_DROP"))),
             ),
+            OFGetConfigReply = (
+                MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
+            ),
+            OFSetConfig = (
+                MaskedEnumGroup("flags", mask="OFP_FRAG_MASK", members=set(("FRAG_NORMAL", "FRAG_DROP", "FRAG_REASM"))),
+            ),
     )
 
     # represents a metadata property associated with an EnumClass
@@ -342,6 +259,14 @@
         else:
             return True
 
+    @property
+    @memoize
+    def oxm_map(self):
+        OxmMapEntry = namedtuple("OxmMapEntry", ["type_name", "value", "masked" ])
+        return OrderedDict( (oxm.name, OxmMapEntry(type_name=oxm.member_by_name("value").java_type.public_type,
+                                       value=re.sub(r'^of_oxm_', r'', re.sub(r'_masked$', r'', oxm.ir_class.name)).upper(),
+                                       masked=oxm.ir_class.name.endswith("_masked")))
+                  for oxm in self.interfaces if oxm.ir_class.is_subclassof("of_oxm") )
 
 class OFFactory(namedtuple("OFFactory", ("package", "name", "members", "remove_prefix", "base_class", "sub_factories", "xid_generator"))):
     @property
@@ -549,8 +474,8 @@
         elif self.name == "OFOxm":
             return ("oxm", None, "T extends OFValueType<T>")
         elif loxi_utils.class_is_oxm(self.c_name):
-            if self.name in model.oxm_map:
-                return ("oxm", "OFOxm<%s>" % model.oxm_map[self.name].type_name, None)
+            if self.member_by_name("value") is not None:
+                return ("oxm", "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None)
             else:
                 return ("oxm", "OFOxm", None)
         elif loxi_utils.class_is_instruction(self.c_name):
@@ -629,14 +554,16 @@
                     JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype("T"))
                    ]
         elif self.ir_class.is_subclassof("of_oxm"):
-            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()
+            value = find(lambda m: m.name=="value", self.ir_model_members)
+            if value:
+                field_type = java_type.make_match_field_jtype(value.java_type.public_type)
+            else:
+                field_type = java_type.make_match_field_jtype()
 
             virtual_members += [
                     JavaVirtualMember(self, "matchField", field_type),
                     JavaVirtualMember(self, "masked", java_type.boolean),
-                    JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype(model.oxm_map[self.name].type_name),
+                    JavaVirtualMember(self, "canonical", java_type.make_oxm_jtype(value.java_type.public_type),
                             custom_template=lambda builder: "OFOxm{}_getCanonical.java".format(".Builder" if builder else "")),
                    ]
             if not find(lambda x: x.name == "mask", self.ir_model_members):
@@ -760,11 +687,12 @@
     @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:
+        if self.ir_class.is_subclassof("of_oxm"):
+            value_member = find(lambda m: m.name, self.ir_model_members)
+            if value_member:
                 oxm_entry = model.oxm_map[self.interface.name]
                 virtual_members += [
-                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(oxm_entry.type_name), "MatchField.%s" % oxm_entry.value),
+                    JavaVirtualMember(self, "matchField", java_type.make_match_field_jtype(value_member.java_type.public_type), "MatchField.%s" % oxm_entry.value),
                     JavaVirtualMember(self, "masked", java_type.boolean, "true" if oxm_entry.masked else "false"),
                     ]
             else:
@@ -883,7 +811,7 @@
             entry = enum.entry_by_version_value(self.msg.version, self.value)
             return "%s.%s" % ( enum.name, entry.name)
         except KeyError, e:
-            print e.message
+            logger.debug("No enum found", e)
             return self.value
 
     @property
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
index 29d6e02..fddaa5d 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFVlanVidMatch.java
@@ -4,6 +4,8 @@
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.Shorts;
@@ -21,6 +23,7 @@
  *
  */
 public class OFVlanVidMatch implements OFValueType<OFVlanVidMatch> {
+    private static final Logger logger = LoggerFactory.getLogger(OFVlanVidMatch.class);
 
     private static final short VALIDATION_MASK = 0x1FFF;
     private static final short PRESENT_VAL = 0x1000;
@@ -59,7 +62,11 @@
             return UNTAGGED;
         else if(vid == PRESENT_VAL)
             return PRESENT;
-        else if ((vid & VALIDATION_MASK) != vid)
+        else if(vid == UNTAGGED_VAL_OF10) {
+            // workaround for IVS sometimes sending 0F1.0 untagged (0xFFFF) values
+            logger.warn("Warning: received OF1.0 untagged vlan value (0xFFFF) in OF1.3 VlanVid. Treating as UNTAGGED");
+            return UNTAGGED;
+        } else if ((vid & VALIDATION_MASK) != vid)
             throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
         return new OFVlanVidMatch(vid);
     }
diff --git a/java_gen/templates/custom/OFMatchV3Ver13.java b/java_gen/templates/custom/OFMatchV3Ver13.java
index 9bfb234..24cab5b 100644
--- a/java_gen/templates/custom/OFMatchV3Ver13.java
+++ b/java_gen/templates/custom/OFMatchV3Ver13.java
@@ -1,4 +1,5 @@
-
+//:: from generic_utils import OrderedSet
+//:: from java_gen.java_model import model
     @Override
     public <F extends OFValueType<F>> F get(MatchField<F> field)
             throws UnsupportedOperationException {
@@ -33,36 +34,9 @@
 
     private static boolean supportsField(MatchField<?> field) {
         switch (field.id) {
-            case IN_PORT:
-            case IN_PHY_PORT:
-            case METADATA:
-            case ETH_DST:
-            case ETH_SRC:
-            case ETH_TYPE:
-            case VLAN_VID:
-            case VLAN_PCP:
-            case IP_DSCP:
-            case IP_ECN:
-            case IP_PROTO:
-            case IPV4_SRC:
-            case IPV4_DST:
-            case TCP_SRC:
-            case TCP_DST:
-            case UDP_SRC:
-            case UDP_DST:
-            case SCTP_SRC:
-            case SCTP_DST:
-            case ICMPV4_TYPE:
-            case ICMPV4_CODE:
-            case ARP_OP:
-            case ARP_SPA:
-            case ARP_TPA:
-            case ARP_SHA:
-            case ARP_THA:
-            case IPV6_SRC:
-            case IPV6_DST:
-            case IPV6_FLABEL:
-            case BSN_IN_PORTS_128:
+            //:: for id_constant in sorted(set(id_constant for _, id_constant, _ in model.oxm_map.values())):
+            case ${id_constant}:
+            //:: #endfor
                 return true;
             default:
                 return false;
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 4057b3d..b35df1c 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -430,5 +430,4 @@
         return result;
     }
 
-
 }
diff --git a/java_gen/templates/of_factory_class.java b/java_gen/templates/of_factory_class.java
index deb6e53..ef26ca0 100644
--- a/java_gen/templates/of_factory_class.java
+++ b/java_gen/templates/of_factory_class.java
@@ -121,7 +121,7 @@
                 return (OFOxm<F>)((Object)${method_name}((${type_name})((Object)value)));
             //:: #endfor
             default:
-                return null;
+                throw new IllegalArgumentException("No OXM known for match field " + field);
         }
     }
 
@@ -140,7 +140,7 @@
                 return (OFOxm<F>)((Object)${method_name}((${type_name})((Object)value), (${type_name})((Object)mask)));
             //:: #endfor
             default:
-                return null;
+                throw new IllegalArgumentException("No OXM known for match field " + field);
         }
     }
 
diff --git a/java_gen/test.sh b/java_gen/test.sh
deleted file mode 100755
index 7b71ffd..0000000
--- a/java_gen/test.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-rm -rf target_code/
-cd ..
-./loxigen.py -ljava #&& ( cd target_code/Modules/openflowj/ && ant  )
diff --git a/loxi_ir/ir.py b/loxi_ir/ir.py
index e2c4a34..8553f62 100644
--- a/loxi_ir/ir.py
+++ b/loxi_ir/ir.py
@@ -360,7 +360,7 @@
         member = ir_class(offset = length_info.offset,
                         base_length = length_info.base_length,
                         is_fixed_length=length_info.is_fixed_length,
-                        **convert_member_properties(vars(fe_member)))
+                        **convert_member_properties(fe_member._asdict()))
         member.of_class = of_class
         return member
 
diff --git a/openflow_input/bsn_time b/openflow_input/bsn_time
new file mode 100644
index 0000000..0a955be
--- /dev/null
+++ b/openflow_input/bsn_time
@@ -0,0 +1,54 @@
+// Copyright 2013, Big Switch Networks, Inc.
+//
+// LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+// the following special exception:
+//
+// LOXI Exception
+//
+// As a special exception to the terms of the EPL, you may distribute libraries
+// generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+// that copyright and licensing notices generated by LoxiGen are not altered or removed
+// from the LoxiGen Libraries and the notice provided below is (i) included in
+// the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+// documentation for the LoxiGen Libraries, if distributed in binary form.
+//
+// Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+//
+// You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+// a copy of the EPL at:
+//
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// EPL for the specific language governing permissions and limitations
+// under the EPL.
+
+// Request a timestamp during message processing.
+//
+// The timestamp is relative to when the switch sent the initial HELLO.
+// The intended use is in conjunction with barriers to approximately determine
+// time elapsed between processing two messages (such as stats requests).
+// The timestamp must be monotonic (not affected by system time updates).
+
+#version 4
+
+struct of_bsn_time_request : of_bsn_header {
+    uint8_t version;
+    uint8_t type == 4;
+    uint16_t length;
+    uint32_t xid;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 44;
+};
+
+struct of_bsn_time_reply : of_bsn_header {
+    uint8_t version;
+    uint8_t type == 4;
+    uint16_t length;
+    uint32_t xid;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 45;
+    uint64_t time_ms; /* Milliseconds since HELLO */
+};
diff --git a/openflow_input/standard-1.0 b/openflow_input/standard-1.0
index ad2e76f..1df03bb 100644
--- a/openflow_input/standard-1.0
+++ b/openflow_input/standard-1.0
@@ -190,7 +190,7 @@
     OFPC_ARP_MATCH_IP = 0x80,
 };
 
-enum ofp_config_flags(wire_type=uint32_t, bitmask=True) {
+enum ofp_config_flags(wire_type=uint16_t, bitmask=True) {
     OFPC_FRAG_NORMAL = 0x0,
     OFPC_FRAG_DROP = 0x1,
     OFPC_FRAG_REASM = 0x2,
@@ -371,7 +371,7 @@
     uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -380,7 +380,7 @@
     uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
diff --git a/openflow_input/standard-1.1 b/openflow_input/standard-1.1
index 906519c..a9aac6b 100644
--- a/openflow_input/standard-1.1
+++ b/openflow_input/standard-1.1
@@ -477,7 +477,7 @@
     uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -486,7 +486,7 @@
     uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -1241,7 +1241,7 @@
 
 struct of_group_desc_stats_entry {
     uint16_t length;
-    uint8_t group_type;
+    enum ofp_group_type group_type;
     pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
diff --git a/openflow_input/standard-1.2 b/openflow_input/standard-1.2
index 90447f5..c1e8a2b 100644
--- a/openflow_input/standard-1.2
+++ b/openflow_input/standard-1.2
@@ -515,7 +515,7 @@
     uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -524,7 +524,7 @@
     uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -1208,7 +1208,7 @@
 
 struct of_group_desc_stats_entry {
     uint16_t length;
-    uint8_t group_type;
+    enum ofp_group_type group_type;
     pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index 4d0ca7e..87adcc4 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -648,7 +648,7 @@
     uint8_t type == 8;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -657,7 +657,7 @@
     uint8_t type == 9;
     uint16_t length;
     uint32_t xid;
-    uint16_t flags;
+    enum ofp_config_flags flags;
     uint16_t miss_send_len;
 };
 
@@ -1427,7 +1427,7 @@
 
 struct of_group_desc_stats_entry {
     uint16_t length;
-    uint8_t group_type;
+    enum ofp_group_type group_type;
     pad(1);
     uint32_t group_id;
     list(of_bucket_t) buckets;
diff --git a/test_data/of13/get_config_reply.data b/test_data/of13/get_config_reply.data
index 111ac61..66ea834 100644
--- a/test_data/of13/get_config_reply.data
+++ b/test_data/of13/get_config_reply.data
@@ -9,3 +9,8 @@
     xid=0x12345678,
     flags=ofp.OFPC_FRAG_REASM,
     miss_send_len=0xffff)
+-- java
+builder.setXid(0x12345678)
+    .setFlags(Sets.immutableEnumSet(OFConfigFlags.FRAG_REASM))
+    .setMissSendLen(0xffff)
+    .build()
diff --git a/wireshark_gen/templates/openflow.lua b/wireshark_gen/templates/openflow.lua
index 7113281..d9eb76a 100644
--- a/wireshark_gen/templates/openflow.lua
+++ b/wireshark_gen/templates/openflow.lua
@@ -29,6 +29,14 @@
 :: ir = loxi_globals.ir
 :: include('_copyright.lua')
 
+-- Copy this file to your wireshark plugin directory:
+--   Linux / OS X: ~/.wireshark/plugins/
+--   Windows: C:\Documents and Settings\<username>\Application Data\Wireshark\plugins\
+-- You may need to create the directory.
+
+-- The latest version of this dissector is always available at:
+-- http://www.projectfloodlight.org/openflow.lua
+
 :: include('_ofreader.lua')
 
 :: include('_oftype_readers.lua')