Added functionality from old floodlight MACAddress class

- added isBroadcast and isMulticast methods
- improved error-checking when constructing from a string
- added more unit tests
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 87be7c2..009dae5 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
@@ -19,6 +19,9 @@
     private final static long NONE_VAL = 0x0L;
     public static final MacAddress NONE = new MacAddress(NONE_VAL);
 
+    private final static long BROADCAST_VAL = 0x0000FFFFFFFFFFFFL;
+    public static final MacAddress BROADCAST = new MacAddress(BROADCAST_VAL);
+
     public static final MacAddress NO_MASK = MacAddress.of(0xFFFFFFFFFFFFFFFFl);
     public static final MacAddress FULL_MASK = MacAddress.of(0x0);
 
@@ -27,6 +30,9 @@
     }
 
     public static MacAddress of(final byte[] address) {
+        if (address.length != MacAddrLen)
+            throw new IllegalArgumentException(
+                    "Mac address byte array must be exactly 6 bytes long; length = " + address.length);
         long raw =
                 (address[0] & 0xFFL) << 40 | (address[1] & 0xFFL) << 32
                         | (address[2] & 0xFFL) << 24 | (address[3] & 0xFFL) << 16
@@ -34,30 +40,36 @@
         return MacAddress.of(raw);
     }
 
-    public static MacAddress of(final long raw) {
+    public static MacAddress of(long raw) {
+        raw &= BROADCAST_VAL;
         if(raw == NONE_VAL)
             return NONE;
-
+        if (raw == BROADCAST_VAL)
+            return BROADCAST;
         return new MacAddress(raw);
     }
 
     public static MacAddress of(final String string) {
         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 (string.length() != 6 * 2 + 5)
-            throw new IllegalArgumentException("Mac address not well formed: " + string);
+            throw new IllegalArgumentException(FORMAT_ERROR + string);
 
         while (shift >= 0) {
-            raw |=
-                    ((long) (Character.digit(string.charAt(index++), 16) << 4 | Character
-                            .digit(string.charAt(index++), 16))) << shift;
+            int digit1 = Character.digit(string.charAt(index++), 16);
+            int digit2 = Character.digit(string.charAt(index++), 16);
+            if ((digit1 < 0) || (digit2 < 0))
+                throw new IllegalArgumentException(FORMAT_ERROR + string);
+            raw |= ((long) (digit1 << 4 | digit2)) << shift;
 
             if (shift == 0)
                 break;
             if (string.charAt(index++) != ':')
-                throw new IllegalArgumentException("Mac address not well formed: " + string);
+                throw new IllegalArgumentException(FORMAT_ERROR + string);
             shift -= 8;
         }
         return MacAddress.of(raw);
@@ -82,6 +94,25 @@
         return bytesCache;
     }
 
+    /**
+     * Returns {@code true} if the MAC address is the broadcast address.
+     * @return {@code true} if the MAC address is the broadcast address.
+     */
+    public boolean isBroadcast() {
+        return this == BROADCAST;
+    }
+
+    /**
+     * Returns {@code true} if the MAC address is a multicast address.
+     * @return {@code true} if the MAC address is a multicast address.
+     */
+    public boolean isMulticast() {
+        if (isBroadcast()) {
+            return false;
+        }
+        return (rawValue & (0x01L << 40)) != 0;
+    }
+
     @Override
     public int getLength() {
         return MacAddrLen;
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 dc25b12..ed380ee 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
@@ -2,6 +2,8 @@
 
 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;
@@ -29,9 +31,11 @@
             0x00ffffffffffffL
     };
 
-    String[] invalidMacs = {
+    String[] invalidMacStrings = {
             "",
             "1.2.3.4",
+            "0T:00:01:02:03:04",
+            "00:01:02:03:04:05:06",
             "00:ff:ef:12:12:ff:",
             "00:fff:ef:12:12:ff",
             "01:02:03:04:05;06",
@@ -39,6 +43,10 @@
             "01:02:03:04"
     };
 
+    byte[][] invalidMacBytes = {
+            new byte[]{0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
+            new byte[]{0x01, 0x01, 0x02, 0x03, 0x04}
+    };
 
     @Test
     public void testOfString() {
@@ -72,8 +80,8 @@
 
 
     @Test
-    public void testInvalidMacss() throws OFParseError {
-        for(String invalid : invalidMacs) {
+    public void testInvalidMacStrings() throws OFParseError {
+        for(String invalid : invalidMacStrings) {
             try {
                 MacAddress.of(invalid);
                 fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
@@ -82,4 +90,54 @@
             }
         }
     }
+
+    @Test
+    public void testInvalidMacBytes() throws OFParseError {
+        for(byte[] invalid : invalidMacBytes) {
+            try {
+                MacAddress.of(invalid);
+                fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
+            } catch(IllegalArgumentException e) {
+                // ok
+            }
+        }
+    }
+
+    //  Test data is imported from org.projectfloodlight.packet.EthernetTest
+    @Test
+    public void testToLong() {
+        assertEquals(
+                281474976710655L,
+                MacAddress.of(new byte[]{(byte) 0xff, (byte) 0xff,
+                        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}).getLong());
+
+        assertEquals(
+                1103823438081L,
+                MacAddress.of(new byte[] { (byte) 0x01, (byte) 0x01,
+                        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 }).getLong());
+
+        assertEquals(
+                141289400074368L,
+                MacAddress.of(new byte[] { (byte) 0x80, (byte) 0x80,
+                        (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80 }).getLong());
+
+    }
+
+    @Test
+    public void testIsBroadcast() {
+        assertTrue(MacAddress.of("FF:FF:FF:FF:FF:FF").isBroadcast());
+        assertTrue(MacAddress.of(-1).isBroadcast());
+        assertTrue(MacAddress.of(0x05FFFFFFFFFFFFL).isBroadcast());
+        assertFalse(MacAddress.of("11:22:33:44:55:66").isBroadcast());
+    }
+
+    @Test
+    public void testIsMulticast() {
+        assertTrue(MacAddress.of("01:80:C2:00:00:00").isMulticast());
+        assertFalse(MacAddress.of("00:80:C2:00:00:00").isMulticast());
+        assertFalse(MacAddress.of("FE:80:C2:00:00:00").isMulticast());
+        assertFalse(MacAddress.of(-1).isMulticast());
+        assertFalse(MacAddress.of(0x05FFFFFFFFFFFFL).isMulticast());
+        assertFalse(MacAddress.of("FF:FF:FF:FF:FF:FF").isMulticast());
+    }
 }