java_gen: OFOxmList: canonicalize OFOxms on build()
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFOxmList.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFOxmList.java
index c6ba116..7f66110 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFOxmList.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/OFOxmList.java
@@ -2,7 +2,6 @@
 
 import java.util.EnumMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import org.jboss.netty.buffer.ChannelBuffer;
@@ -13,11 +12,16 @@
 import org.projectfloodlight.openflow.types.OFValueType;
 import org.projectfloodlight.openflow.types.PrimitiveSinkable;
 import org.projectfloodlight.openflow.util.ChannelUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.hash.PrimitiveSink;
 
 public class OFOxmList implements Iterable<OFOxm<?>>, Writeable, PrimitiveSinkable {
+    private static final Logger logger = LoggerFactory.getLogger(OFOxmList.class);
+
     private final Map<MatchFields, OFOxm<?>> oxmMap;
 
     public final static OFOxmList EMPTY = new OFOxmList(ImmutableMap.<MatchFields, OFOxm<?>>of());
@@ -51,7 +55,7 @@
         }
 
         public OFOxmList build() {
-            return new OFOxmList(oxmMap);
+            return OFOxmList.ofList(oxmMap.values());
         }
     }
 
@@ -60,12 +64,19 @@
         return oxmMap.values().iterator();
     }
 
-    public static OFOxmList ofList(List<OFOxm<?>> oxmList) {
+    public static OFOxmList ofList(Iterable<OFOxm<?>> oxmList) {
         Map<MatchFields, OFOxm<?>> map = new EnumMap<MatchFields, OFOxm<?>>(
                 MatchFields.class);
         for (OFOxm<?> o : oxmList) {
-            // TODO: if fully masked, ignore oxm.
-            map.put(o.getMatchField().id, o);
+            OFOxm<?> canonical = o.getCanonical();
+
+            if(logger.isDebugEnabled() && !Objects.equal(o, canonical)) {
+                logger.debug("OFOxmList: normalized non-canonical OXM {} to {}", o, canonical);
+            }
+
+            if(canonical != null)
+                map.put(canonical.getMatchField().id, canonical);
+
         }
         return new OFOxmList(map);
     }
@@ -74,8 +85,14 @@
         Map<MatchFields, OFOxm<?>> map = new EnumMap<MatchFields, OFOxm<?>>(
                 MatchFields.class);
         for (OFOxm<?> o : oxms) {
-            // TODO: if fully masked, ignore oxm.
-            map.put(o.getMatchField().id, o);
+            OFOxm<?> canonical = o.getCanonical();
+
+            if(logger.isDebugEnabled() && !Objects.equal(o, canonical)) {
+                logger.debug("OFOxmList: normalized non-canonical OXM {} to {}", o, canonical);
+            }
+
+            if(canonical != null)
+                map.put(canonical.getMatchField().id, canonical);
         }
         return new OFOxmList(map);
     }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFOxmListTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFOxmListTest.java
new file mode 100644
index 0000000..39e8c0c
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFOxmListTest.java
@@ -0,0 +1,41 @@
+package org.projectfloodlight.protocol;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6DstMasked;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6SrcMasked;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxms;
+import org.projectfloodlight.openflow.types.IPv6AddressWithMask;
+
+public class OFOxmListTest {
+    private OFOxms oxms;
+
+    @Before
+    public void setup() {
+        oxms = OFFactories.getFactory(OFVersion.OF_13).oxms();
+    }
+
+    @Test
+    public void testCanonicalize() {
+        OFOxmList.Builder builder = new OFOxmList.Builder();
+        IPv6AddressWithMask fullMasked = IPv6AddressWithMask.of("::/0");
+        OFOxmIpv6DstMasked  fullMaskedOxm = oxms.ipv6DstMasked(fullMasked.getValue(), fullMasked.getMask());
+        builder.set(fullMaskedOxm);
+
+        IPv6AddressWithMask address= IPv6AddressWithMask.of("1:2:3:4:5:6::8");
+        OFOxmIpv6SrcMasked  addressSrcOxm = oxms.ipv6SrcMasked(address.getValue(), address.getMask());
+        builder.set(addressSrcOxm);
+
+        OFOxmList list = builder.build();
+        assertThat(list.get(MatchField.IPV6_DST), CoreMatchers.nullValue());
+        assertFalse(list.get(MatchField.IPV6_SRC).isMasked());
+    }
+}