Merge into master from pull request #411:
DatapathId and MacAddress factory methods (https://github.com/floodlight/loxigen/pull/411)
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 65bb22d..11a5705 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,14 +22,13 @@
 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;
 import org.projectfloodlight.openflow.types.VlanPcp;
 
-@SuppressWarnings("unchecked")
 public class MatchField<F extends OFValueType<F>> {
     private final String name;
     public final MatchFields id;
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/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)));
+        }
+    }
 }