Merge remote-tracking branch 'upstream/master' into HEAD

Change-Id: I98c5244ab0c96dcb174d0263d39f5cfbf478907a
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index e1fa563..24df9b6 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -732,6 +732,9 @@
         'of_oxm_bsn_inner_eth_src' : { 'value' : mac_addr },
         'of_oxm_bsn_inner_eth_src_masked' : { 'value' : mac_addr, 'value_mask' : mac_addr },
 
+        'of_oxm_bsn_inner_vlan_vid' : { 'value' : vlan_vid_match },
+        'of_oxm_bsn_inner_vlan_vid_masked' : { 'value' : vlan_vid_match, 'value_mask' : vlan_vid_match },
+
         'of_table_stats_entry': { 'wildcards': table_stats_wildcards },
         'of_match_v1': { 'vlan_vid' : vlan_vid_match, 'vlan_pcp': vlan_pcp,
                 'eth_type': eth_type, 'ip_dscp': ip_dscp, 'ip_proto': ip_proto,
diff --git a/java_gen/pre-written/pom.xml b/java_gen/pre-written/pom.xml
index 91b7e8e..4063b0c 100644
--- a/java_gen/pre-written/pom.xml
+++ b/java_gen/pre-written/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>org.onosproject</groupId>
     <artifactId>openflowj</artifactId>
-    <version>0.4.1.onos-SNAPSHOT</version>
+    <version>0.9.0.onos-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <name>OpenFlowJ-Loxi</name>
@@ -44,12 +44,12 @@
         <dependency>
             <groupId>com.google.code.findbugs</groupId>
             <artifactId>annotations</artifactId>
-            <version>2.0.2</version>
+            <version>3.0.0</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
-            <version>4.11</version>
+            <version>4.12</version>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -61,27 +61,27 @@
         <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty</artifactId>
-            <version>3.9.0.Final</version>
+            <version>3.10.4.Final</version>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
-            <version>17.0</version>
+            <version>18.0</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
-            <version>1.7.5</version>
+            <version>1.7.12</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-core</artifactId>
-            <version>1.0.13</version>
+            <version>1.1.3</version>
         </dependency>
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
-            <version>1.0.13</version>
+            <version>1.1.3</version>
         </dependency>
     </dependencies>
     <build>
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 55cd59f..2250832 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
@@ -22,8 +22,8 @@
 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
 import org.projectfloodlight.openflow.types.TransportPort;
 import org.projectfloodlight.openflow.types.U16;
-import org.projectfloodlight.openflow.types.U64;
 import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
 import org.projectfloodlight.openflow.types.U8;
 import org.projectfloodlight.openflow.types.UDF;
 import org.projectfloodlight.openflow.types.VRF;
@@ -31,7 +31,6 @@
 import org.projectfloodlight.openflow.types.CircuitSignalID;
 import org.projectfloodlight.openflow.types.OduSignalID;
 
-@SuppressWarnings("unchecked")
 public class MatchField<F extends OFValueType<F>> {
     private final String name;
     public final MatchFields id;
@@ -290,6 +289,9 @@
     public final static MatchField<MacAddress> BSN_INNER_ETH_SRC =
             new MatchField<MacAddress>("bsn_inner_eth_src", MatchFields.BSN_INNER_ETH_SRC);
 
+    public final static MatchField<OFVlanVidMatch> BSN_INNER_VLAN_VID =
+            new MatchField<OFVlanVidMatch>("bsn_inner_vlan_vid", MatchFields.BSN_INNER_VLAN_VID);
+
     public final static MatchField<OduSignalID> EXP_ODU_SIG_ID =
             new MatchField<OduSignalID>("exp_odu_sig_id", MatchFields.EXP_ODU_SIG_ID);
     
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 abfa786..4c80d7f 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
@@ -68,6 +68,7 @@
     BSN_VXLAN_NETWORK_ID,
     BSN_INNER_ETH_DST,
     BSN_INNER_ETH_SRC,
+    BSN_INNER_VLAN_VID,
     OCH_SIGTYPE,
     OCH_SIGTYPE_BASIC,
     OCH_SIGID,
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
index fe52fc3..708eaa9 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/DatapathId.java
@@ -1,5 +1,7 @@
 package org.projectfloodlight.openflow.types;
 
+import javax.annotation.Nonnull;
+
 import org.projectfloodlight.openflow.annotations.Immutable;
 import org.projectfloodlight.openflow.util.HexString;
 
@@ -36,6 +38,15 @@
         return new DatapathId(Longs.fromByteArray(bytes));
     }
 
+    /**
+     * Creates a {@link DatapathId} from a {@link MacAddress}.
+     * @param mac the {@link MacAddress} to create the {@link DatapathId} from
+     * @return a {@link DatapathId} derived from the supplied {@link MacAddress}
+     */
+    public static DatapathId of(@Nonnull MacAddress mac) {
+        return DatapathId.of(mac.getLong());
+    }
+
     public long getLong() {
         return rawValue;
     }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
index 89debf0..b73db43 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/MacAddress.java
@@ -8,6 +8,7 @@
 import org.projectfloodlight.openflow.exceptions.OFParseError;
 import org.projectfloodlight.openflow.util.HexString;
 
+import com.google.common.base.Preconditions;
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.Longs;
 
@@ -33,6 +34,10 @@
     private static final long LLDP_MAC_ADDRESS_MASK = 0xfffffffffff0L;
     private static final long LLDP_MAC_ADDRESS_VALUE = 0x0180c2000000L;
 
+    private static final String FORMAT_ERROR = "Mac address is not well-formed. " +
+            "It must consist of 6 hex digit pairs separated by colons: ";
+    private static final int MAC_STRING_LENGTH = 6 * 2 + 5;
+
     private MacAddress(final long rawValue) {
         this.rawValue = rawValue;
     }
@@ -69,14 +74,14 @@
         if (macString == null) {
             throw new NullPointerException("macString must not be null");
         }
+
         int index = 0;
         int shift = 40;
-        final String FORMAT_ERROR = "Mac address is not well-formed. " +
-                "It must consist of 6 hex digit pairs separated by colons: ";
-
         long raw = 0;
-        if (macString.length() != 6 * 2 + 5)
+
+        if (macString.length() != MAC_STRING_LENGTH) {
             throw new IllegalArgumentException(FORMAT_ERROR + macString);
+        }
 
         while (shift >= 0) {
             int digit1 = Character.digit(macString.charAt(index++), 16);
@@ -94,6 +99,25 @@
         return MacAddress.of(raw);
     }
 
+    /**
+     * Creates a {@link MacAddress} from a {@link DatapathId}. This factory
+     * method assumes that the first two bytes of the {@link DatapathId} are 0 bytes.
+     * @param dpid the {@link DatapathId} to create the {@link MacAddress} from
+     * @return a {@link MacAddress} derived from the supplied {@link DatapathId}
+     */
+    public static MacAddress of(@Nonnull DatapathId dpid) {
+        Preconditions.checkNotNull(dpid, "dpid must not be null");
+
+        long raw = dpid.getLong();
+
+        // Mask out valid bytes
+        if( (raw & ~BROADCAST_VAL) != 0L) {
+            throw new IllegalArgumentException("First two bytes of supplied "
+                 + "Datapathid must be 0");
+        }
+        return of(raw);
+    }
+
     private volatile byte[] bytesCache = null;
 
     public byte[] getBytes() {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBooleanValue.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBooleanValue.java
index e276092..99416a3 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBooleanValue.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFBooleanValue.java
@@ -31,6 +31,8 @@
     public final static OFBooleanValue NO_MASK = TRUE;
     public final static OFBooleanValue FULL_MASK = FALSE;
 
+    public final static Reader READER_INSTANCE = new Reader();
+
     private final boolean value;
 
     private OFBooleanValue(boolean value) {
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap512.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap512.java
new file mode 100644
index 0000000..c85c750
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFPortBitMap512.java
@@ -0,0 +1,192 @@
+package org.projectfloodlight.openflow.types;
+
+import java.util.ArrayList;
+
+import javax.annotation.concurrent.Immutable;
+
+
+/** User-facing object representing a bitmap of ports that can be matched on.
+ *  This is implemented by the custom BSN OXM type of_oxm_bsn_in_ports_512.
+ *
+ *  You can call set() on the builder for all the Ports you want to match on
+ *  and unset to exclude the port.
+ *
+ *  <b>Implementation note:</b> to comply with the matching semantics of OXM (which is a logical "AND" not "OR")
+ *  the underlying match uses a data format which is very unintuitive. The value is always
+ *  0, and the mask has the bits set for the ports that should <b>NOT</b> be included in the
+ *  range.
+ *
+ *  For the curious: We transformed the bitmap (a logical OR) problem into a logical
+ *  AND NOT problem.
+ *
+ *  We logically mean:   Inport is 1 OR 3
+ *  We technically say:  Inport IS NOT 2 AND IS NOT 4 AND IS NOT 5 AND IS NOT ....
+ *  The second term cannot be represented in OXM, the second can.
+ *
+ *  That said, all that craziness is hidden from the user of this object.
+ *
+ *  <h2>Usage</h2>
+ *  OFPortBitmap is meant to be used with MatchField <tt>BSN_IN_PORTS_512</tt> in place
+ *  of the raw type Masked&lt;OFBitMask512&gt;.
+ *
+ *  <h3>Example:</h3>:
+ *  <pre>
+ *  OFPortBitMap portBitMap;
+ *  Match.Builder matchBuilder;
+ *  // initialize
+ *  matchBuilder.setMasked(MatchField.BSN_IN_PORTS_512, portBitmap);
+ *  </pre>
+ *
+ * @author Andreas Wundsam {@literal <}andreas.wundsam@bigswitch.com{@literal >}
+ */
+@Immutable
+public class OFPortBitMap512 extends Masked<OFBitMask512> {
+
+    private OFPortBitMap512(OFBitMask512 mask) {
+        super(OFBitMask512.NONE, mask);
+    }
+
+    /** @return whether or not the given port is logically included in the
+     *  match, i.e., whether a packet from in-port <em>port</em> be matched by
+     *  this OXM.
+     */
+    public boolean isOn(OFPort port) {
+        // see the implementation note above about the logical inversion of the mask
+        return !(this.mask.isOn(port.getPortNumber()));
+    }
+
+    public static OFPortBitMap512 ofPorts(OFPort... ports) {
+        Builder builder = new Builder();
+        for (OFPort port: ports) {
+            builder.set(port);
+        }
+        return builder.build();
+    }
+
+    /** @return an OFPortBitmap based on the 'mask' part of an OFBitMask512, as, e.g., returned
+     *  by the switch.
+     **/
+    public static OFPortBitMap512 of(OFBitMask512 mask) {
+        return new OFPortBitMap512(mask);
+    }
+
+    /** @return iterating over all ports that are logically included in the
+     *  match, i.e., whether a packet from in-port <em>port</em> be matched by
+     *  this OXM.
+     */
+    public Iterable<OFPort> getOnPorts() {
+        ArrayList<OFPort> ports = new ArrayList<>();
+        for(int i=0; i < 511; i++) {
+            if(!(this.mask.isOn(i))) {
+                ports.add(OFPort.of(i));
+            }
+        }
+        return ports;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof OFPortBitMap512))
+            return false;
+        OFPortBitMap512 other = (OFPortBitMap512)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 {
+        private long raw1 = -1, raw2 = -1, raw3 = -1, raw4 = -1,
+                raw5 = -1, raw6 = -1, raw7 = -1, raw8 = -1;
+
+        public Builder() {
+
+        }
+
+        /** @return whether or not the given port is logically included in the
+         *  match, i.e., whether a packet from in-port <em>port</em> be matched by
+         *  this OXM.
+         */
+        public boolean isOn(OFPort port) {
+            // see the implementation note above about the logical inversion of the mask
+            return !(OFBitMask512.isBitOn(raw1, raw2, raw3, raw4,
+                    raw5, raw6, raw7, raw8, port.getPortNumber()));
+        }
+
+        /** remove this port from the match, i.e., packets from this in-port
+         *  will NOT be matched.
+         */
+        public Builder unset(OFPort port) {
+            // see the implementation note above about the logical inversion of the mask
+            int bit = port.getPortNumber();
+            if (bit < 0 || bit > 511)
+                throw new IndexOutOfBoundsException("Port number is out of bounds");
+            else if (bit == 511)
+                // the highest order bit in the bitmask is reserved. The switch will
+                // set that bit for all ports >= 511. The reason is that we don't want
+                // the OFPortMap to match all ports out of its range (i.e., a packet
+                // coming in on port 581 would match *any* OFPortMap).
+                throw new IndexOutOfBoundsException("The highest order bit in the bitmask is reserved.");
+            else if (bit < 64) {
+                raw8 |= ((long)1 << bit);
+            } else if (bit < 128) {
+                raw7 |= ((long)1 << bit - 64);
+            } else if (bit < 192) {
+                raw6 |= ((long)1 << bit - 128);
+            } else if (bit < 256) {
+                raw5 |= ((long)1 << bit - 192);
+            } else if (bit < 320) {
+                raw4 |= ((long)1 << bit - 256);
+            } else if (bit < 384) {
+                raw3 |= ((long)1 << bit - 320);
+            } else if (bit < 448) {
+                raw2 |= ((long)1 << bit - 384);
+            } else {
+                raw1 |= ((long)1 << (bit - 448));
+            }
+            return this;
+        }
+
+        /** add this port from the match, i.e., packets from this in-port
+         *  will NOT be matched.
+         */
+        public Builder set(OFPort port) {
+            // see the implementation note above about the logical inversion of the mask
+            int bit = port.getPortNumber();
+            if (bit < 0 || bit > 511)
+                throw new IndexOutOfBoundsException("Port number is out of bounds");
+            else if (bit == 511)
+                // the highest order bit in the bitmask is reserved. The switch will
+                // set that bit for all ports >= 511. The reason is that we don't want
+                // the OFPortMap to match all ports out of its range (i.e., a packet
+                // coming in on port 581 would match *any* OFPortMap).
+                throw new IndexOutOfBoundsException("The highest order bit in the bitmask is reserved.");
+            else if (bit < 64) {
+                raw8 &= ~((long)1 << bit);
+            } else if (bit < 128) {
+                raw7 &= ~((long)1 << bit - 64);
+            } else if (bit < 192) {
+                raw6 &= ~((long)1 << bit - 128);
+            } else if (bit < 256) {
+                raw5 &= ~((long)1 << bit - 192);
+            } else if (bit < 320) {
+                raw4 &= ~((long)1 << bit - 256);
+            } else if (bit < 384) {
+                raw3 &= ~((long)1 << bit - 320);
+            } else if (bit < 448) {
+                raw2 &= ~((long)1 << bit - 384);
+            } else {
+                raw1 &= ~((long)1 << (bit - 448));
+            }
+            return this;
+        }
+
+        public OFPortBitMap512 build() {
+            return new OFPortBitMap512(OFBitMask512.of(raw1, raw2, raw3, raw4,
+                    raw5, raw6, raw7, raw8));
+        }
+    }
+
+}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/LengthCountingPseudoChannelBuffer.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/LengthCountingPseudoChannelBuffer.java
deleted file mode 100644
index 48362da..0000000
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/util/LengthCountingPseudoChannelBuffer.java
+++ /dev/null
@@ -1,673 +0,0 @@
-package org.projectfloodlight.openflow.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.GatheringByteChannel;
-import java.nio.channels.ScatteringByteChannel;
-import java.nio.charset.Charset;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferFactory;
-import org.jboss.netty.buffer.ChannelBufferIndexFinder;
-
-public class LengthCountingPseudoChannelBuffer implements ChannelBuffer {
-
-    int writerIndex = 0;
-    private int markedWriterIndex;
-
-    @Override
-    public ChannelBufferFactory factory() {
-        return null;
-    }
-
-    @Override
-    public int capacity() {
-        return Integer.MAX_VALUE;
-    }
-
-    @Override
-    public ByteOrder order() {
-        return ByteOrder.BIG_ENDIAN;
-    }
-
-    @Override
-    public boolean isDirect() {
-        return true;
-    }
-
-    @Override
-    public int readerIndex() {
-        return 0;
-    }
-
-    @Override
-    public void readerIndex(int readerIndex) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int writerIndex() {
-        return writerIndex;
-    }
-
-    @Override
-    public void writerIndex(int writerIndex) {
-        this.writerIndex = writerIndex;
-    }
-
-    @Override
-    public void setIndex(int readerIndex, int writerIndex) {
-        if(readerIndex != 0)
-            throw new UnsupportedOperationException();
-        this.writerIndex = writerIndex;
-    }
-
-    @Override
-    public int readableBytes() {
-        return writerIndex;
-    }
-
-    @Override
-    public int writableBytes() {
-        return Integer.MAX_VALUE - writerIndex;
-    }
-
-    @Override
-    public boolean readable() {
-        return writerIndex > 0;
-    }
-
-    @Override
-    public boolean writable() {
-        return writerIndex < Integer.MAX_VALUE;
-    }
-
-    @Override
-    public void clear() {
-        writerIndex = 0;
-
-    }
-
-    @Override
-    public void markReaderIndex() {
-    }
-
-    @Override
-    public void resetReaderIndex() {
-    }
-
-    @Override
-    public void markWriterIndex() {
-        markedWriterIndex = writerIndex;
-    }
-
-    @Override
-    public void resetWriterIndex() {
-        writerIndex = markedWriterIndex;
-    }
-
-    @Override
-    public void discardReadBytes() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void ensureWritableBytes(int writableBytes) {
-        if(!((Integer.MAX_VALUE - writableBytes) > writerIndex))
-            throw new IllegalStateException();
-    }
-
-    @Override
-    public byte getByte(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public short getUnsignedByte(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public short getShort(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getUnsignedShort(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getMedium(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getUnsignedMedium(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getInt(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getUnsignedInt(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long getLong(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public char getChar(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float getFloat(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public double getDouble(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, ChannelBuffer dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, ChannelBuffer dst, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, ChannelBuffer dst, int dstIndex, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, byte[] dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, byte[] dst, int dstIndex, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, ByteBuffer dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void getBytes(int index, OutputStream out, int length)
-            throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int getBytes(int index, GatheringByteChannel out, int length)
-            throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setByte(int index, int value) {
-    }
-
-    @Override
-    public void setShort(int index, int value) {
-    }
-
-    @Override
-    public void setMedium(int index, int value) {
-    }
-
-    @Override
-    public void setInt(int index, int value) {
-    }
-
-    @Override
-    public void setLong(int index, long value) {
-    }
-
-    @Override
-    public void setChar(int index, int value) {
-    }
-
-    @Override
-    public void setFloat(int index, float value) {
-    }
-
-    @Override
-    public void setDouble(int index, double value) {
-    }
-
-    @Override
-    public void setBytes(int index, ChannelBuffer src) {
-    }
-
-    @Override
-    public void setBytes(int index, ChannelBuffer src, int length) {
-    }
-
-    @Override
-    public void setBytes(int index, ChannelBuffer src, int srcIndex, int length) {
-    }
-
-    @Override
-    public void setBytes(int index, byte[] src) {
-    }
-
-    @Override
-    public void setBytes(int index, byte[] src, int srcIndex, int length) {
-    }
-
-    @Override
-    public void setBytes(int index, ByteBuffer src) {
-
-    }
-
-    @Override
-    public int setBytes(int index, InputStream in, int length)
-            throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int setBytes(int index, ScatteringByteChannel in, int length)
-            throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setZero(int index, int length) {
-    }
-
-    @Override
-    public byte readByte() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public short readUnsignedByte() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public short readShort() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int readUnsignedShort() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int readMedium() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int readUnsignedMedium() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int readInt() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long readUnsignedInt() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public long readLong() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public char readChar() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public float readFloat() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public double readDouble() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer readBytes(int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    @Deprecated
-    public ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer readSlice(int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    @Deprecated
-    public
-    ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(ChannelBuffer dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(ChannelBuffer dst, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(ChannelBuffer dst, int dstIndex, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(byte[] dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(byte[] dst, int dstIndex, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(ByteBuffer dst) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void readBytes(OutputStream out, int length) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int readBytes(GatheringByteChannel out, int length)
-            throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void skipBytes(int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    @Deprecated
-    public int skipBytes(ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void writeByte(int value) {
-        writerIndex++;
-    }
-
-    @Override
-    public void writeShort(int value) {
-    writerIndex += 2;
-}
-
-@Override
-public void writeMedium(int value) {
-    writerIndex += 3;
-}
-
-@Override
-public void writeInt(int value) {
-    writerIndex += 4;
-}
-
-@Override
-public void writeLong(long value) {
-    writerIndex += 8;
-}
-
-
-    @Override
-    public void writeChar(int value) {
-        writeShort(value);
-    }
-
-    @Override
-    public void writeFloat(float value) {
-        writeInt(Float.floatToIntBits(value));
-    }
-
-    @Override
-    public void writeDouble(double value) {
-        writeLong(Double.doubleToLongBits(value));
-
-    }
-
-    @Override
-    public void writeBytes(ChannelBuffer src) {
-        writerIndex += src.readableBytes();
-
-    }
-
-    @Override
-    public void writeBytes(ChannelBuffer src, int length) {
-        writerIndex += src.readableBytes();
-
-    }
-
-    @Override
-    public void writeBytes(ChannelBuffer src, int srcIndex, int length) {
-        writerIndex += length;
-    }
-
-    @Override
-    public void writeBytes(byte[] src) {
-        writerIndex += src.length;
-
-    }
-
-    @Override
-    public void writeBytes(byte[] src, int srcIndex, int length) {
-        writerIndex += length;
-    }
-
-    @Override
-    public void writeBytes(ByteBuffer src) {
-        writerIndex += src.remaining();
-
-    }
-
-    @Override
-    public int writeBytes(InputStream in, int length) throws IOException {
-        writerIndex += length;
-        return length;
-    }
-
-    @Override
-    public int writeBytes(ScatteringByteChannel in, int length)
-            throws IOException {
-        writerIndex += length;
-        return length;
-    }
-
-    @Override
-    public void writeZero(int length) {
-        writerIndex += length;
-
-    }
-
-    @Override
-    public int indexOf(int fromIndex, int toIndex, byte value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int indexOf(int fromIndex, int toIndex,
-            ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(byte value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(int length, byte value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(int length, ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(int index, int length, byte value) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int bytesBefore(int index, int length,
-            ChannelBufferIndexFinder indexFinder) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer copy() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer copy(int index, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer slice() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer slice(int index, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ChannelBuffer duplicate() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ByteBuffer toByteBuffer() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ByteBuffer toByteBuffer(int index, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ByteBuffer[] toByteBuffers() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ByteBuffer[] toByteBuffers(int index, int length) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean hasArray() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public byte[] array() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public int arrayOffset() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String toString(Charset charset) {
-        return "LengthCountingPseudoChannelBuffer(length="+writerIndex+")";
-    }
-
-    @Override
-    public String toString(int index, int length, Charset charset) {
-        return toString();
-    }
-
-    @Override
-    @Deprecated
-    public String toString(String charsetName) {
-        return toString();
-    }
-
-    @Override
-    @Deprecated
-    public String toString(String charsetName,
-            ChannelBufferIndexFinder terminatorFinder) {
-        return toString();
-    }
-
-    @Override
-    @Deprecated
-    public String toString(int index, int length, String charsetName) {
-        return toString();
-    }
-
-    @Override
-    @Deprecated
-    public
-    String toString(int index, int length, String charsetName,
-            ChannelBufferIndexFinder terminatorFinder) {
-        return toString();
-    }
-
-    @Override
-    public int compareTo(ChannelBuffer buffer) {
-        throw new UnsupportedOperationException();
-
-    }
-
-}
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/DatapathIdTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/DatapathIdTest.java
new file mode 100644
index 0000000..136908b
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/DatapathIdTest.java
@@ -0,0 +1,70 @@
+package org.projectfloodlight.openflow.types;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.is;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+public class DatapathIdTest {
+
+    byte[][] testDpids = new byte[][] {
+            {0x0, 0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
+            {0x0, 0x0, (byte) 0x80, 0x0, 0x0, 0x0, 0x0, 0x01},
+            {0x0, 0x0, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 }
+    };
+
+    String[] testStrings = {
+            "00:00:01:02:03:04:05:06",
+            "00:00:80:00:00:00:00:01",
+            "00:00:ff:ff:ff:ff:ff:ff"
+    };
+
+    long[] testInts = {
+            0x000000010203040506L,
+            0x000000800000000001L,
+            0x000000ffffffffffffL
+    };
+
+    @Test
+    public void testOfString() {
+        for(int i=0; i < testDpids.length; i++ ) {
+            DatapathId dpid = DatapathId.of(testStrings[i]);
+            assertEquals(testInts[i], dpid.getLong());
+            assertArrayEquals(testDpids[i], dpid.getBytes());
+            assertEquals(testStrings[i], dpid.toString());
+        }
+    }
+
+    @Test
+    public void testOfByteArray() {
+        for(int i=0; i < testDpids.length; i++ ) {
+            DatapathId dpid = DatapathId.of(testDpids[i]);
+            assertEquals("error checking long representation of "+Arrays.toString(testDpids[i]) + "(should be "+Long.toHexString(testInts[i]) +")", testInts[i],  dpid.getLong());
+            assertArrayEquals(testDpids[i], dpid.getBytes());
+            assertEquals(testStrings[i], dpid.toString());
+        }
+    }
+
+    @Test
+    public void testOfMacAddress() {
+
+        for (String s : testStrings) {
+
+            // Generate mac addresses by stripping off the front two bytes
+            MacAddress mac = MacAddress.of(s.replaceFirst("00:00:", ""));
+
+            // Create dpid from mac address
+            DatapathId candidateDpid = DatapathId.of(mac);
+
+            // Create dpid from string
+            DatapathId actualDpid = DatapathId.of(s);
+
+            assertThat(candidateDpid.equals(actualDpid), is(true));
+        }
+    }
+}
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/MacAddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/MacAddressTest.java
index a13fdd4..e1c7721 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/MacAddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/MacAddressTest.java
@@ -1,17 +1,20 @@
 package org.projectfloodlight.openflow.types;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 import java.util.Arrays;
 
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.projectfloodlight.openflow.exceptions.OFParseError;
 
+import static org.hamcrest.Matchers.is;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 public class MacAddressTest {
     byte[][] testAddresses = new byte[][] {
             {0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
@@ -151,4 +154,16 @@
         assertFalse(MacAddress.of("00:80:C2:f0:00:00").isLLDPAddress());
         assertFalse(MacAddress.of("FE:80:C2:00:00:00").isLLDPAddress());
     }
+
+    @Test
+    public void testOfDatapathid() {
+        MacAddress mac = MacAddress.of(DatapathId.NONE);
+        assertThat(mac, is(MacAddress.NONE));
+
+        for (String s : testStrings) {
+            DatapathId dpid = DatapathId.of("00:00:" + s);
+            mac = MacAddress.of(dpid);
+            assertThat(mac, is(MacAddress.of(s)));
+        }
+    }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
index 4db84f1..f5b1a91 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/OFPortBitMapTest.java
@@ -8,6 +8,10 @@
 import org.junit.Test;
 
 public class OFPortBitMapTest extends TestCase {
+
+    /**
+     * 128 Bit variation
+     */
     @Test
     public void testCreateAndIterate() {
         OFPortBitMap map = OFPortBitMap.ofPorts(OFPort.of(1), OFPort.of(2), OFPort.of(5));
@@ -68,4 +72,70 @@
         }
         assertArrayEquals(on, actual);
     }
+
+    /**
+     * 512 Bit variation
+     */
+    @Test
+    public void testCreateAndIterate512() {
+        OFPortBitMap512 map = OFPortBitMap512.ofPorts(OFPort.of(1), OFPort.of(2), OFPort.of(5));
+
+        assertThat(map.getOnPorts(), contains(OFPort.of(1), OFPort.of(2), OFPort.of(5)));
+    }
+
+    @Test
+    public void testOFBitMap512() {
+        OFBitMask512 bitmap = OFBitMask512.of(0xFFFF_FFFF_FFFF_FFFFL, 0xFFFF_FFFF_FFFF_FFFFL,
+                0xFFFF_FFFF_FFFF_FFFFL, 0xFFFF_FFFF_FFFF_FFFFL, 0xFFFF_FFFF_FFFF_FFFFL,
+                0xFFFF_FFFF_FFFF_FFFFL, 0xFFFF_FFFF_FFFF_FFFFL, 0xFFFF_FFFF_FFFF_FFD9L);
+
+        OFPortBitMap512 map = OFPortBitMap512.of(bitmap);
+
+        assertThat(map.getOnPorts(), contains(OFPort.of(1), OFPort.of(2), OFPort.of(5)));
+    }
+
+    @Test
+    public void testOFPortBitMap512() {
+        Boolean[] on = new Boolean[511];
+        for (int i = 0; i < 511; i++) {
+            on[i] = false;
+        }
+
+        OFPortBitMap512.Builder builder = new OFPortBitMap512.Builder();
+
+        for (int i = 0; i < 511; i += 3) {
+            OFPort p = OFPort.of(i);
+            builder.set(p);
+            on[p.getPortNumber()] = true;
+        }
+
+        // Test that all ports that were added are actually on, and all other ports are off
+        OFPortBitMap512 portmap = builder.build();
+        //System.out.println(portmap);
+        Boolean[] actual = new Boolean[511];
+        for (int i = 0; i < 511; i++) {
+            actual[i] = false;
+        }
+        for (int i = 0; i < 511; i++) {
+            actual[i] = portmap.isOn(OFPort.of(i));
+        }
+        assertArrayEquals(on, actual);
+
+        // Turn some ports off
+        for (int i = 0; i < 511; i += 7) {
+            on[i] = false;
+            builder.unset(OFPort.of(i));
+        }
+
+        // Test again
+        portmap = builder.build();
+        actual = new Boolean[511];
+        for (int i = 0; i < 511; i++) {
+            actual[i] = false;
+        }
+        for (int i = 0; i < 511; i++) {
+            actual[i] = portmap.isOn(OFPort.of(i));
+        }
+        assertArrayEquals(on, actual);
+    }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
index 530f66b..e2f3a6e 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/protocol/OFPortDescTest.java
@@ -1,19 +1,24 @@
 package org.projectfloodlight.protocol;
 
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
 import java.util.Arrays;
 import java.util.HashSet;
 
+import org.hamcrest.Matchers;
 import org.junit.Test;
 import org.projectfloodlight.openflow.protocol.OFFactories;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFPortConfig;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortDescProp;
 import org.projectfloodlight.openflow.protocol.OFPortState;
 import org.projectfloodlight.openflow.protocol.OFVersion;
+import org.projectfloodlight.openflow.types.U64;
 
-import static org.hamcrest.Matchers.is;
-
-import static org.junit.Assert.assertThat;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Tests auxiliary OFPortDesc methods for all versions of OpenFlow
@@ -50,4 +55,25 @@
                 .build();
         assertThat(desc.isEnabled(), is(false));
     }
+
+    @Test
+    public void testGenerationIdZeroIfUnset() {
+       for(OFVersion v: OFVersion.values()) {
+           OFFactory factory = OFFactories.getFactory(v);
+           assertThat("For version "+v, factory.buildPortDesc().build().getBsnGenerationId(),
+                    Matchers.equalTo(U64.ZERO));
+       }
+    }
+
+    @Test
+    public void testGenerationIdSet() {
+        OFFactory factory = OFFactories.getFactory(OFVersion.OF_14);
+        OFPortDesc desc = factory.buildPortDesc()
+          .setProperties(ImmutableList.<OFPortDescProp>of(
+                  factory.portDescPropBsnGenerationId(U64.of(1234))))
+          .build();
+
+       assertThat(desc.getBsnGenerationId(), equalTo(U64.of(1234)));
+    }
+
 }
diff --git a/java_gen/templates/_imports.java b/java_gen/templates/_imports.java
index dde3ac0..f84efbe 100644
--- a/java_gen/templates/_imports.java
+++ b/java_gen/templates/_imports.java
@@ -5,6 +5,8 @@
 import java.util.List;
 import java.util.Set;
 import java.util.Map;
+import javax.annotation.Nullable;
+import javax.annotation.Nonnull;
 import org.projectfloodlight.openflow.protocol.*;
 import org.projectfloodlight.openflow.protocol.action.*;
 import org.projectfloodlight.openflow.protocol.actionid.*;
diff --git a/java_gen/templates/custom/OFPortDesc.java b/java_gen/templates/custom/OFPortDesc.java
index 3be1b70..ccfbedb 100644
--- a/java_gen/templates/custom/OFPortDesc.java
+++ b/java_gen/templates/custom/OFPortDesc.java
@@ -8,4 +8,27 @@
     public boolean isEnabled() {
         return (!state.contains(OFPortState.LINK_DOWN) && !config.contains(OFPortConfig.PORT_DOWN));
     }
-    
\ No newline at end of file
+
+    /**
+     * Returns the current generation ID of this port.
+     *
+     * The generationId is reported by the switch as a @{link OFPortDescProp} in
+     * @link{OFPortDescStatsReply} and @link{OFPortStatus} messages. If the
+     * current OFPortDesc does not contain a generation Id, returns U64.ZERO;
+     *
+     * For OpenFlow versions earlier than 1.4, always returns U64.ZERO;
+     *
+     * @return the generation ID or U64.NULL if not reported
+     * @since 1.4
+     */
+     @Nonnull
+     public U64 getBsnGenerationId() {
+         //:: if msg.member_by_name("properties"):
+         for(OFPortDescProp prop: getProperties()) {
+            if(prop instanceof OFPortDescPropBsnGenerationId) {
+                return ((OFPortDescPropBsnGenerationId) prop).getGenerationId();
+            }
+         }
+         //:: #endif
+         return U64.ZERO;
+     }
diff --git a/java_gen/templates/custom/interface/OFPortDesc.java b/java_gen/templates/custom/interface/OFPortDesc.java
index ecf39f3..247464d 100644
--- a/java_gen/templates/custom/interface/OFPortDesc.java
+++ b/java_gen/templates/custom/interface/OFPortDesc.java
@@ -1,2 +1,23 @@
-    // Additional method
-    boolean isEnabled();
\ No newline at end of file
+    // Additional methods
+
+    /**
+     * Returns true if the port is up, i.e., it's neither administratively
+     * down nor link down. It currently does NOT take STP state into
+     * consideration
+     * @return whether the port is up
+     */
+    boolean isEnabled();
+
+    /**
+     * Returns the current generation ID of this port.
+     *
+     * The generationId is reported by the switch as a @{link OFPortDescProp} in
+     * @link{OFPortDescStatsReply} and @link{OFPortStatus} messages. If the
+     * current OFPortDesc does not contain a generation Id, returns U64.ZERO;
+     *
+     * For OpenFlow versions earlier than 1.4, always returns U64.ZERO;
+     *
+     * @return the generation ID or U64.ZERO if not reported
+     * @since 1.4
+     */
+     public U64 getBsnGenerationId();
diff --git a/openflow_input/bsn_generic_async b/openflow_input/bsn_generic_async
new file mode 100644
index 0000000..7d7ee98
--- /dev/null
+++ b/openflow_input/bsn_generic_async
@@ -0,0 +1,45 @@
+// Copyright 2015, 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 2015, 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.
+
+#version 5
+
+// This extension provides flexibility for async messages like gentable
+// does for table programming.
+
+struct of_bsn_generic_async : of_bsn_header {
+    uint8_t version;
+    uint8_t type == 4;
+    uint16_t length;
+    uint32_t xid;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 68;
+    of_str64_t name;
+    list(of_bsn_tlv_t) tlvs;
+};
diff --git a/openflow_input/bsn_inner_vlan_vid b/openflow_input/bsn_inner_vlan_vid
new file mode 100644
index 0000000..68092a2
--- /dev/null
+++ b/openflow_input/bsn_inner_vlan_vid
@@ -0,0 +1,47 @@
+// Copyright 2015, 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.
+
+#version 4
+#version 5
+
+/*
+ * Inner VLAN VID
+ */
+
+struct of_oxm_bsn_inner_vlan_vid : of_oxm {
+    uint32_t type_len == 0x00033002;
+    uint16_t value;
+};
+
+struct of_oxm_bsn_inner_vlan_vid_masked : of_oxm {
+    uint32_t type_len == 0x00033104;
+    uint16_t value;
+    uint16_t value_mask;
+};
diff --git a/openflow_input/bsn_port_generation_id b/openflow_input/bsn_port_generation_id
new file mode 100644
index 0000000..fddf9a3
--- /dev/null
+++ b/openflow_input/bsn_port_generation_id
@@ -0,0 +1,38 @@
+// Copyright 2015, 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.
+
+// This generation ID is changed whenever a port goes link-down.
+
+#version 5
+
+struct of_port_desc_prop_bsn_generation_id : of_port_desc_prop_bsn {
+    uint16_t type == 0xffff;
+    uint16_t length;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t exp_type == 1;
+    uint64_t generation_id;
+};
diff --git a/openflow_input/bsn_takeover b/openflow_input/bsn_takeover
new file mode 100644
index 0000000..1b95611
--- /dev/null
+++ b/openflow_input/bsn_takeover
@@ -0,0 +1,42 @@
+// Copyright 2015, 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 2015, 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.
+
+#version 5
+
+// This message is used by IVS for hitless restart.
+
+struct of_bsn_takeover : of_bsn_header {
+    uint8_t version;
+    uint8_t type == 4;
+    uint16_t length;
+    uint32_t xid;
+    uint32_t experimenter == 0x5c16c7;
+    uint32_t subtype == 69;
+};
diff --git a/openflow_input/bsn_tlv b/openflow_input/bsn_tlv
index 150c879..0985e1c 100644
--- a/openflow_input/bsn_tlv
+++ b/openflow_input/bsn_tlv
@@ -500,3 +500,55 @@
     uint16_t type == 76;
     uint16_t length;
 };
+
+struct of_bsn_tlv_vlan_vid_mask : of_bsn_tlv {
+    uint16_t type == 77;
+    uint16_t length;
+    uint16_t value;
+};
+
+struct of_bsn_tlv_igmp_snooping : of_bsn_tlv {
+    uint16_t type == 78;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_l2_multicast_lookup : of_bsn_tlv {
+    uint16_t type == 79;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_generation_id : of_bsn_tlv {
+    uint16_t type == 80;
+    uint16_t length;
+    uint64_t value;
+};
+
+enum ofp_bsn_anchor(wire_type=uint16_t) {
+    OFP_BSN_ANCHOR_PACKET_START = 0,
+    OFP_BSN_ANCHOR_L3_HEADER_START = 1,
+    OFP_BSN_ANCHOR_L4_HEADER_START = 2,
+    OFP_BSN_ANCHOR_L4_PAYLOAD_START = 3,
+};
+
+struct of_bsn_tlv_anchor : of_bsn_tlv {
+    uint16_t type == 81;
+    uint16_t length;
+    enum ofp_bsn_anchor value;
+};
+
+struct of_bsn_tlv_offset : of_bsn_tlv {
+    uint16_t type == 82;
+    uint16_t length;
+    uint16_t value;
+};
+
+struct of_bsn_tlv_negate : of_bsn_tlv {
+    uint16_t type == 83;
+    uint16_t length;
+};
+
+struct of_bsn_tlv_ipv6 : of_bsn_tlv {
+    uint16_t type == 84;
+    uint16_t length;
+    of_ipv6_t value; 
+};
diff --git a/openflow_input/standard-1.3 b/openflow_input/standard-1.3
index fa1a967..1edabb2 100644
--- a/openflow_input/standard-1.3
+++ b/openflow_input/standard-1.3
@@ -1606,99 +1606,97 @@
     uint32_t subtype;
 };
 
-// FIXME: These are padded to 8 byte align beyond the length indicated
-
 struct of_table_feature_prop {
     uint16_t         type == ?;
     uint16_t         length;
 };
 
-struct of_table_feature_prop_instructions : of_table_feature_prop {
+struct of_table_feature_prop_instructions(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 0;
     uint16_t         length;
     // FIXME Check if instruction_t is right for ids here
     list(of_instruction_id_t)   instruction_ids;
 };
 
-struct of_table_feature_prop_instructions_miss : of_table_feature_prop {
+struct of_table_feature_prop_instructions_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 1;
     uint16_t         length;
     list(of_instruction_id_t)   instruction_ids;
 };
 
-struct of_table_feature_prop_next_tables : of_table_feature_prop {
+struct of_table_feature_prop_next_tables(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 2;
     uint16_t         length;
     list(of_uint8_t) next_table_ids;
 };
 
-struct of_table_feature_prop_next_tables_miss : of_table_feature_prop {
+struct of_table_feature_prop_next_tables_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 3;
     uint16_t         length;
     list(of_uint8_t) next_table_ids;
 };
 
-struct of_table_feature_prop_write_actions : of_table_feature_prop {
+struct of_table_feature_prop_write_actions(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 4;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct of_table_feature_prop_write_actions_miss : of_table_feature_prop {
+struct of_table_feature_prop_write_actions_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 5;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct of_table_feature_prop_apply_actions : of_table_feature_prop {
+struct of_table_feature_prop_apply_actions(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 6;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct of_table_feature_prop_apply_actions_miss : of_table_feature_prop {
+struct of_table_feature_prop_apply_actions_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 7;
     uint16_t         length;
     list(of_action_id_t) action_ids;
 };
 
-struct of_table_feature_prop_match : of_table_feature_prop {
+struct of_table_feature_prop_match(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 8;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_wildcards : of_table_feature_prop {
+struct of_table_feature_prop_wildcards(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 10;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_write_setfield : of_table_feature_prop {
+struct of_table_feature_prop_write_setfield(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 12;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_write_setfield_miss : of_table_feature_prop {
+struct of_table_feature_prop_write_setfield_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 13;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_apply_setfield : of_table_feature_prop {
+struct of_table_feature_prop_apply_setfield(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 14;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_apply_setfield_miss : of_table_feature_prop {
+struct of_table_feature_prop_apply_setfield_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 15;
     uint16_t         length;
     list(of_uint32_t) oxm_ids;
 };
 
-struct of_table_feature_prop_experimenter : of_table_feature_prop {
+struct of_table_feature_prop_experimenter(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 65534;
     uint16_t         length;
     uint32_t         experimenter == ?;
@@ -1706,7 +1704,7 @@
     of_octets_t      experimenter_data;
 };
 
-struct of_table_feature_prop_experimenter_miss : of_table_feature_prop {
+struct of_table_feature_prop_experimenter_miss(align=8, length_includes_align=False) : of_table_feature_prop {
     uint16_t         type == 65535;
     uint16_t         length;
     uint32_t         experimenter == ?;
@@ -1898,7 +1896,7 @@
     uint16_t stats_type == 10;
     enum ofp_stats_reply_flags flags;
     pad(4);
-    list(of_meter_band_t) entries;
+    list(of_meter_config_t) entries;
 };
 
 // FIXME stats added to get things working
diff --git a/openflow_input/standard-1.4 b/openflow_input/standard-1.4
index edcc781..20511cc 100644
--- a/openflow_input/standard-1.4
+++ b/openflow_input/standard-1.4
@@ -880,7 +880,7 @@
     uint16_t type == 0xffff;
     uint16_t length;
     uint32_t experimenter == ?;
-    uint32_t exp_type;
+    //uint32_t exp_type;
 };
 
 struct of_port_desc {
@@ -2224,7 +2224,7 @@
     uint16_t stats_type == 10;
     enum ofp_stats_reply_flags flags;
     pad(4);
-    list(of_meter_band_t) entries;
+    list(of_meter_config_t) entries;
 };
 
 // FIXME stats added to get things working
diff --git a/test_data/of13/meter_config_stats_reply.data b/test_data/of13/meter_config_stats_reply.data
index 940e4f5..29ac4aa 100644
--- a/test_data/of13/meter_config_stats_reply.data
+++ b/test_data/of13/meter_config_stats_reply.data
@@ -1,25 +1,25 @@
 -- binary
 04 13 # version, type
-00 30 # length
+00 28 # length
 12 34 56 78 # xid
 00 0a # stats_type
 00 00 # flags
 00 00 00 00 # pad
-00 01 # entries[0].type
-00 10 # entries[0].length
-00 00 00 01 # entries[0].rate
-00 00 00 02 # entries[0].burst_size
+00 18 # entires[0].len
+00 00 # entries[0].flags
+00 00 00 01 # entries[0].meterId
+00 01 # entries[0].bands[0].type
+00 10 # entries[0].bands[0].length
+00 00 00 01 # entries[0].bands[0].rate
+00 00 00 02 # entries[0]bands[0].burst_size
 00 00 00 00 # pad
-00 02 # entries[1].type
-00 10 # entries[1].length
-00 00 00 03 # entries[1].rate
-00 00 00 04 # entries[1].burst_size
-05 # entries[1].prec_level
-00 00 00 # pad
 -- python
 ofp.message.meter_config_stats_reply(
     xid=0x12345678,
     flags=0,
     entries=[
-        ofp.meter_band.drop(rate=1, burst_size=2),
-        ofp.meter_band.dscp_remark(rate=3, burst_size=4, prec_level=5)])
+        ofp.meter_config(flags = 0, 
+                         meter_id = 1,
+                         entries = [
+                                    ofp.meter_band.drop(rate=1, burst_size=2)])
+                         ])