diff --git a/build.xml b/build.xml
index 19e6d34afd8c0067b77901e65187d754dace4e12..c94be94c1475fafe689bd3811b2e9fbfade75047 100644
--- a/build.xml
+++ b/build.xml
@@ -35,8 +35,6 @@
     <property name="packetstreamer-gen" location="lib/gen-java" />
     <property name="packetstreamer-gen-build" location="lib/gen-java-bin"/>
     <property name="packetstreamer-thrift-jar" value="packetstreamer-thrift.jar"/>
-    <property name="floodlight-nodeps-jar" location="${target}/floodlight-nodeps.jar"/>
-    <property name="floodlight-debian-jar" location="${target}/floodlight-debian.jar"/>
     <property name="floodlight-jar" location="${target}/floodlight.jar"/>
     <property name="floodlight-test-jar" location="${target}/floodlight-test.jar"/>
 
@@ -58,15 +56,6 @@
         <include name="jython-2.5.2.jar"/>
         <include name="libthrift-0.7.0.jar"/>
     </patternset>
-    <!-- Dependencies we can't get from Debian/Ubuntu. -->
-    <patternset id="debian-lib">
-        <include name="org.restlet-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.jackson-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.simple-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.slf4j-2.1-RC1.jar"/>
-        <include name="libthrift-0.7.0.jar"/>
-        <include name="simple-4.1.21.jar"/>
-    </patternset>
     <patternset id="genlib">
         <include name="${packetstreamer-thrift-jar}"/>
     </patternset>
@@ -212,7 +201,7 @@
     <target name="coverage" depends="instrument,test,coverage-report"/>
 
     <target name="dist" depends="compile,compile-test">
-        <jar destfile="${floodlight-nodeps-jar}" filesetmanifest="mergewithoutmain">
+        <jar destfile="${floodlight-jar}" filesetmanifest="mergewithoutmain">
             <manifest>
                 <attribute name="Main-Class" value="${main-class}"/>
                 <attribute name="Class-Path" value="."/>
@@ -222,30 +211,12 @@
             <fileset dir="${python-src}">
                 <include name="**/*.py"/>
             </fileset>
-            <zipgroupfileset dir="${target}/lib">
-                <patternset refid="genlib"/>
-            </zipgroupfileset>
-        </jar>
-        <jar destfile="${floodlight-jar}">
-            <manifest>
-                <attribute name="Main-Class" value="${main-class}"/>
-                <attribute name="Class-Path" value="."/>
-            </manifest>
             <zipgroupfileset dir="lib">
                 <patternset refid="lib"/>
             </zipgroupfileset>
-            <zipfileset src="${floodlight-nodeps-jar}"/>
-        </jar>
-        <jar destfile="${floodlight-debian-jar}">
-            <manifest>
-                <attribute name="Main-Class" value="${main-class}"/>
-                <!-- JARs under /usr/share/java on Debian/Ubuntu -->
-                <attribute name="Class-Path" value="args4j.jar slf4j-api.jar logback-core.jar logback-classic.jar jackson-core-asl.jar jackson-mapper-asl.jar easymock.jar netty.jar concurrentlinkedhashmap-lru.jar jython.jar antlr3-runtime.jar asm3.jar asm3-tree.jar ."/>
-            </manifest>
-            <zipgroupfileset dir="lib">
-                <patternset refid="debian-lib"/>
+            <zipgroupfileset dir="${target}/lib">
+                <patternset refid="genlib"/>
             </zipgroupfileset>
-            <zipfileset src="${floodlight-nodeps-jar}"/>
         </jar>
         <jar destfile="${floodlight-test-jar}" filesetmanifest="mergewithoutmain">
             <manifest>
diff --git a/debian/.gitignore b/debian/.gitignore
deleted file mode 100644
index 972bbfe651b922d9d33bcc9051a37ab33236252c..0000000000000000000000000000000000000000
--- a/debian/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/files
-/floodlight.debhelper.log
-/floodlight.substvars
-/floodlight
-
diff --git a/debian/README b/debian/README
deleted file mode 100644
index 8583ef341267838fcc1ac25c84ab1a88a603aa3c..0000000000000000000000000000000000000000
--- a/debian/README
+++ /dev/null
@@ -1,6 +0,0 @@
-The Debian Package floodlight
-----------------------------
-
-Comments regarding the Package
-
- -- Rich Lane <rlane@bigswitch.com>  Thu, 10 May 2012 23:02:25 -0700
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index b3f5ace5775966ac692d3fb2c5de48e2c21963b5..0000000000000000000000000000000000000000
--- a/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-floodlight (0.82) unstable; urgency=low
-
-  * Initial Release.
-
- -- Rich Lane <rlane@bigswitch.com>  Thu, 10 May 2012 23:02:25 -0700
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index 45a4fb75db864000d01701c0f7a51864bd4daabf..0000000000000000000000000000000000000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-8
diff --git a/debian/control b/debian/control
deleted file mode 100644
index b11688589e622c7655c5fc613f7a18f52f8bb2e3..0000000000000000000000000000000000000000
--- a/debian/control
+++ /dev/null
@@ -1,16 +0,0 @@
-Source: floodlight
-Section: net
-Priority: extra
-Maintainer: Rich Lane <rlane@bigswitch.com>
-Build-Depends: debhelper (>= 8.0.0), javahelper (>= 0.40ubuntu1), liblogback-java (>= 1.0.0-1), libjackson-json-java (>= 1.9.2-1), libeasymock-java (>= 2.4+ds1-6), libslf4j-java (>= 1.6.4-1), libnetty-java (>= 1:3.2.6.Final-2), libargs4j-java (>= 2.0.16-2), libconcurrentlinkedhashmap-java (>= 1.1~jdk5-1), jython (>= 2.5.1-2ubuntu2)
-Standards-Version: 3.9.2
-Homepage: http://floodlight.openflowhub.org/
-Vcs-Git: git://github.com/floodlight/floodlight.git
-Vcs-Browser: https://github.com/floodlight/floodlight
-
-Package: floodlight
-Architecture: all
-Depends: ${java:Depends}, ${misc:Depends}
-Description: Java based OpenFlow controller
- Floodlight is a Java based OpenFlow controller originally written by David
- Erickson at Stanford University.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index e139e18b52babbe34fc4fcef6b260f1e501844c2..0000000000000000000000000000000000000000
--- a/debian/copyright
+++ /dev/null
@@ -1,27 +0,0 @@
-Format: http://dep.debian.net/deps/dep5
-Upstream-Name: floodlight
-Source: https://github.com/floodlight/floodlight
-
-Files: *
-Copyright: 2011 Big Switch Networks <rlane@bigswitch.com>
-License: Apache-2.0
-
-Files: debian/*
-Copyright: 2012 Big Switch Networks <rlane@bigswitch.com>
-License: Apache-2.0
-
-License: Apache-2.0
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- .
- http://www.apache.org/licenses/LICENSE-2.0
- .
- 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 License for the specific language governing permissions and
- limitations under the License.
- .
- On Debian systems, the complete text of the Apache version 2.0 license
- can be found in "/usr/share/common-licenses/Apache-2.0".
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 588b138a5aceaf1ecbaf91a1d08172598891cc11..0000000000000000000000000000000000000000
--- a/debian/docs
+++ /dev/null
@@ -1,2 +0,0 @@
-NOTICE.txt
-README.txt
diff --git a/debian/floodlight.1 b/debian/floodlight.1
deleted file mode 100644
index 80635073d7d13a860e182ac53853246ddeb9e188..0000000000000000000000000000000000000000
--- a/debian/floodlight.1
+++ /dev/null
@@ -1,40 +0,0 @@
-.\"                                      Hey, EMACS: -*- nroff -*-
-.\" First parameter, NAME, should be all caps
-.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
-.\" other parameters are allowed: see man(7), man(1)
-.TH FLOODLIGHT 1 "May 14, 2012"
-.\" Please adjust this date whenever revising the manpage.
-.\"
-.\" Some roff macros, for reference:
-.\" .nh        disable hyphenation
-.\" .hy        enable hyphenation
-.\" .ad l      left justify
-.\" .ad b      justify to both left and right margins
-.\" .nf        disable filling
-.\" .fi        enable filling
-.\" .br        insert line break
-.\" .sp <n>    insert n+1 empty lines
-.\" for manpage-specific macros, see man(7)
-.SH NAME
-floodlight \- An Apache licensed, Java based OpenFlow controller
-.SH SYNOPSIS
-.B floodlight
-.RI [ options ]
-.SH DESCRIPTION
-This manual page documents briefly the
-.B floodlight
-command.
-.PP
-.\" TeX users may be more comfortable with the \fB<whatever>\fP and
-.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
-.\" respectively.
-\fBfloodlight\fP is an Apache licensed, Java based OpenFlow controller.
-.SH OPTIONS
-.TP
-.B \-cf, \-\-configFile FILE
-Floodlight configuration file.
-.SH AUTHOR
-floodlight was written by David Erickson and Big Switch Networks.
-.PP
-This manual page was written by Rich Lane <rlane@bigswitch.com>,
-for the Debian project (and may be used by others).
diff --git a/debian/floodlight.install b/debian/floodlight.install
deleted file mode 100644
index f21b0d6c1f05b46f0c81f2c497c5c56e84fac247..0000000000000000000000000000000000000000
--- a/debian/floodlight.install
+++ /dev/null
@@ -1,2 +0,0 @@
-target/floodlight-debian.jar usr/share/java
-debian/misc/floodlight usr/bin
diff --git a/debian/floodlight.manpages b/debian/floodlight.manpages
deleted file mode 100644
index bec775d2741b6ae5db26abc89c80c7f41cd13f97..0000000000000000000000000000000000000000
--- a/debian/floodlight.manpages
+++ /dev/null
@@ -1 +0,0 @@
-debian/floodlight.1
diff --git a/debian/init.d b/debian/init.d
deleted file mode 100644
index ecb447884107bb4a9fb40d5b0ff73b1c44f12329..0000000000000000000000000000000000000000
--- a/debian/init.d
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides:          floodlight
-# Required-Start:    $network $local_fs $remote_fs
-# Required-Stop:     $remote_fs
-# Default-Start:     2 3 4 5
-# Default-Stop:      0 1 6
-# Short-Description: An Apache licensed, Java based OpenFlow controller
-# Description:       An Apache licensed, Java based OpenFlow controller
-### END INIT INFO
-
-# Author: Rich Lane <rlane@bigswitch.com>
-
-# PATH should only include /usr/* if it runs after the mountnfs.sh script
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
-DESC=floodlight             # Introduce a short description here
-NAME=floodlight             # Introduce the short server's name here
-DAEMON=/usr/bin/floodlight # Introduce the server's location here
-DAEMON_ARGS=""             # Arguments to run the daemon with
-PIDFILE=/var/run/$NAME.pid
-SCRIPTNAME=/etc/init.d/$NAME
-
-# Exit if the package is not installed
-[ -x $DAEMON ] || exit 0
-
-# Read configuration variable file if it is present
-[ -r /etc/default/$NAME ] && . /etc/default/$NAME
-
-# Load the VERBOSE setting and other rcS variables
-. /lib/init/vars.sh
-
-# Define LSB log_* functions.
-# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
-. /lib/lsb/init-functions
-
-#
-# Function that starts the daemon/service
-#
-do_start()
-{
-	# Return
-	#   0 if daemon has been started
-	#   1 if daemon was already running
-	#   2 if daemon could not be started
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --test > /dev/null \
-		|| return 1
-	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON -b -m -- \
-		$DAEMON_ARGS \
-		|| return 2
-        # Wait for the server to start.
-        while ! nc -z localhost 6633; do sleep 1; done
-}
-
-#
-# Function that stops the daemon/service
-#
-do_stop()
-{
-	# Return
-	#   0 if daemon has been stopped
-	#   1 if daemon was already stopped
-	#   2 if daemon could not be stopped
-	#   other if a failure occurred
-	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
-	RETVAL="$?"
-	[ "$RETVAL" = 2 ] && return 2
-	# Many daemons don't delete their pidfiles when they exit.
-	rm -f $PIDFILE
-	return "$RETVAL"
-}
-
-#
-# Function that sends a SIGHUP to the daemon/service
-#
-do_reload() {
-	#
-	# If the daemon can reload its configuration without
-	# restarting (for example, when it is sent a SIGHUP),
-	# then implement that here.
-	#
-	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE
-	return 0
-}
-
-case "$1" in
-  start)
-    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
-    do_start
-    case "$?" in
-		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-	esac
-  ;;
-  stop)
-	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
-	do_stop
-	case "$?" in
-		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
-		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
-	esac
-	;;
-  status)
-       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
-       ;;
-  #reload|force-reload)
-	#
-	# If do_reload() is not implemented then leave this commented out
-	# and leave 'force-reload' as an alias for 'restart'.
-	#
-	#log_daemon_msg "Reloading $DESC" "$NAME"
-	#do_reload
-	#log_end_msg $?
-	#;;
-  restart|force-reload)
-	#
-	# If the "reload" option is implemented then remove the
-	# 'force-reload' alias
-	#
-	log_daemon_msg "Restarting $DESC" "$NAME"
-	do_stop
-	case "$?" in
-	  0|1)
-		do_start
-		case "$?" in
-			0) log_end_msg 0 ;;
-			1) log_end_msg 1 ;; # Old process is still running
-			*) log_end_msg 1 ;; # Failed to start
-		esac
-		;;
-	  *)
-	  	# Failed to stop
-		log_end_msg 1
-		;;
-	esac
-	;;
-  *)
-	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
-	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
-	exit 3
-	;;
-esac
-
-:
diff --git a/debian/misc/floodlight b/debian/misc/floodlight
deleted file mode 100755
index b98a261ac74afb002e4ee8649d5240e76a0114db..0000000000000000000000000000000000000000
--- a/debian/misc/floodlight
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-exec java -jar /usr/share/java/floodlight-debian.jar "$@"
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index f35bb0c395caa40b3538262f854a0c49fce71652..0000000000000000000000000000000000000000
--- a/debian/rules
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-export JAVA_HOME=/usr/lib/jvm/default-java
-
-%:
-	dh $@ --with javahelper
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 89ae9db8f88b823b6a7eabf55e203658739da122..0000000000000000000000000000000000000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (native)
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 31f7e0613bd583f9d8fb9b36943765c78305704a..d65972029dc260bb919b783bbd95bb1a53e17861 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -166,6 +166,8 @@ public class Controller implements IFloodlightProviderService,
     // Configuration options
     protected int openFlowPort = 6633;
     protected int workerThreads = 0;
+    // The id for this controller node. Should be unique for each controller
+    // node in a controller cluster.
     protected String controllerId = "localhost";
     
     // The current role of the controller.
@@ -419,15 +421,42 @@ public class Controller implements IFloodlightProviderService,
      * @throws IOException
      */
     protected void sendRoleRequest(IOFSwitch sw, Role role) throws IOException {
+        // There are three cases to consider:
+        //
+        // 1) If the controller role at the point the switch connected was
+        //    null/disabled, then we never sent the role request probe to the
+        //    switch and therefore never set the SWITCH_SUPPORTS_NX_ROLE
+        //    attribute for the switch, so supportsNxRole is null. In that
+    	//    case since we're now enabling role support for the controller
+    	//    we should send out the role request probe/update to the switch.
+        //
+        // 2) If supportsNxRole == Boolean.TRUE then that means we've already
+        //    sent the role request probe to the switch and it replied with
+        //    a role reply message, so we know it supports role request
+        //    messages. Now we're changing the role and we want to send
+        //    it another role request message to inform it of the new role
+        //    for the controller.
+        //
+        // 3) If supportsNxRole == Boolean.FALSE, then that means we sent the
+        //    role request probe to the switch but it responded with an error
+        //    indicating that it didn't understand the role request message.
+        //    In that case we don't want to send it another role request that
+        //    it (still) doesn't understand. But if the new role of the
+    	//    controller is SLAVE, then we don't want the switch to remain
+        //    connected to this controller. It might support the older serial
+        //    failover model for HA support, so we want to terminate the
+        //    connection and get it to initiate a connection with another
+        //    controller in its list of controllers. Eventually (hopefully, if
+        //    things are configured correctly) it will walk down its list of
+    	//    controllers and connect to the current master controller.
         Boolean supportsNxRole = (Boolean)
                 sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE);
-        if ((supportsNxRole != null) && supportsNxRole) {
+        if ((supportsNxRole == null) || supportsNxRole) {
+        	// Handle cases #1 and #2
             sendNxRoleRequest(sw, role);
-        } else if (supportsNxRole != null && !supportsNxRole) {
-            // We know switch does not support role-request (and so sw.role is null)
-            // but we may have just switched roles from MASTER to SLAVE in which
-            // case we should disconnect switch
-            if (getRole() == Role.SLAVE && sw.getRole() == null) {
+        } else {
+        	// Handle case #3
+            if (getRole() == Role.SLAVE) {
                 log.error("Disconnecting switch {} that doesn't support " +
                 "role request messages from a controller that went to SLAVE mode");
                 // Closing the channel should result in a call to
@@ -1712,7 +1741,11 @@ public class Controller implements IFloodlightProviderService,
                     roleString = properties.getProperty("floodlight.role");
                 }
                 catch (IOException exc) {
-                    log.error("Error reading current role value from file: {}", rolePath);
+                	// Don't treat it as an error if the file specified by the
+                	// rolepath property doesn't exist. This lets us enable the
+                	// HA mechanism by just creating/setting the floodlight.role
+                	// property in that file without having to modify the
+                	// floodlight properties.
                 }
             }
         }
@@ -1862,6 +1895,7 @@ public class Controller implements IFloodlightProviderService,
         storageSource.createTable(SWITCH_TABLE_NAME, null);
         storageSource.createTable(PORT_TABLE_NAME, null);
         storageSource.createTable(CONTROLLER_INTERFACE_TABLE_NAME, null);
+        storageSource.createTable(SWITCH_CONFIG_TABLE_NAME, null);
         storageSource.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME,
                                              CONTROLLER_ID);
         storageSource.setTablePrimaryKeyName(SWITCH_TABLE_NAME,
diff --git a/src/main/java/net/floodlightcontroller/core/web/RoleResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerRoleResource.java
similarity index 72%
rename from src/main/java/net/floodlightcontroller/core/web/RoleResource.java
rename to src/main/java/net/floodlightcontroller/core/web/ControllerRoleResource.java
index d0bf2f837e62be1d4b915a1f23b60eb36e66d92d..2a1520577c0ebbb581f57b8989e71539acccbaa0 100644
--- a/src/main/java/net/floodlightcontroller/core/web/RoleResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/ControllerRoleResource.java
@@ -11,33 +11,10 @@ import org.restlet.resource.Post;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RoleResource extends ServerResource {
+public class ControllerRoleResource extends ServerResource {
 
-    protected static Logger log = LoggerFactory.getLogger(RoleResource.class);
+    protected static Logger log = LoggerFactory.getLogger(ControllerRoleResource.class);
 
-    public static class RoleInfo {
-        protected String role;
-        
-        public RoleInfo() {
-        }
-        
-        public RoleInfo(String role) {
-            setRole(role);
-        }
-        
-        public RoleInfo(Role role) {
-            this.role = (role != null) ? role.name() : "DISABLED";
-        }
-        
-        public String getRole() {
-            return role;
-        }
-        
-        public void setRole(String role) {
-            this.role = role;
-        }
-    }
-    
     @Get("json")
     public RoleInfo getRole() {
         IFloodlightProviderService floodlightProvider = 
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 66c462618ab10097892e680a8838d61a287bcde5..009681fb4693fcb83a3292d1babe319058cb3778 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -39,6 +39,7 @@ public class CoreWebRoutable implements RestletRoutable {
         Router router = new Router(context);
         router.attach("/module/all/json", ModuleLoaderResource.class);
         router.attach("/module/loaded/json", LoadedModuleLoaderResource.class);
+        router.attach("/switch/{switchId}/role/json", SwitchRoleResource.class);
         router.attach("/switch/all/{statType}/json", AllSwitchStatisticsResource.class);
         router.attach("/switch/{switchId}/{statType}/json", SwitchStatisticsResource.class);
         router.attach("/controller/switches/json", ControllerSwitchesResource.class);
@@ -56,7 +57,7 @@ public class CoreWebRoutable implements RestletRoutable {
                 EventHistoryTopologyClusterResource.class);
         router.attach("/storage/tables/json", StorageSourceTablesResource.class);
         router.attach("/controller/summary/json", ControllerSummaryResource.class);
-        router.attach("/role/json", RoleResource.class);
+        router.attach("/role/json", ControllerRoleResource.class);
         router.attach("/health/json", HealthCheckResource.class);
         return router;
     }
diff --git a/src/main/java/net/floodlightcontroller/core/web/RoleInfo.java b/src/main/java/net/floodlightcontroller/core/web/RoleInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..e600ea0eb02ada3d8003fb4c4e75b3e8b57f7b16
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/RoleInfo.java
@@ -0,0 +1,26 @@
+package net.floodlightcontroller.core.web;
+
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+
+public class RoleInfo {
+    protected String role;
+    
+    public RoleInfo() {
+    }
+    
+    public RoleInfo(String role) {
+        setRole(role);
+    }
+    
+    public RoleInfo(Role role) {
+        this.role = (role != null) ? role.name() : "DISABLED";
+    }
+    
+    public String getRole() {
+        return role;
+    }
+    
+    public void setRole(String role) {
+        this.role = role;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchRoleResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchRoleResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d73f93f12130c1df48fc995b1ccd50ad53ef82e
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchRoleResource.java
@@ -0,0 +1,46 @@
+package net.floodlightcontroller.core.web;
+
+import java.util.HashMap;
+
+import org.openflow.util.HexString;
+import org.restlet.resource.ServerResource;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+
+import org.restlet.resource.Get;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SwitchRoleResource extends ServerResource {
+
+    protected static Logger log = LoggerFactory.getLogger(SwitchRoleResource.class);
+
+    @Get("json")
+    public Object getRole() {
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
+
+        String switchId = (String) getRequestAttributes().get("switchId");
+        
+        RoleInfo roleInfo;
+        
+        if (switchId.equalsIgnoreCase("all")) {
+            HashMap<String,RoleInfo> model = new HashMap<String,RoleInfo>();
+            for (IOFSwitch sw: floodlightProvider.getSwitches().values()) {
+            	switchId = sw.getStringId();
+            	roleInfo = new RoleInfo(sw.getRole());
+            	model.put(switchId, roleInfo);
+            }
+            return model;
+        }
+        
+    	Long dpid = HexString.toLong(switchId);
+    	IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+    	if (sw == null)
+    		return null;
+    	roleInfo = new RoleInfo(sw.getRole());
+    	return roleInfo;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/APBlockedException.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/APBlockedException.java
deleted file mode 100644
index eab0ebfc50199529880ed6728a6d6cc98955efa8..0000000000000000000000000000000000000000
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/APBlockedException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    Licensed under the Apache License, Version 2.0 (the "License"); you may
-*    not use this file except in compliance with the License. You may obtain
-*    a copy of the License at
-*
-*         http://www.apache.org/licenses/LICENSE-2.0
-*
-*    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
-*    License for the specific language governing permissions and limitations
-*    under the License.
-**/
-
-package net.floodlightcontroller.devicemanager.internal;
-
-/**
- * Exception thrown when an attachment point is blocked
- * @author readams
- */
-public class APBlockedException extends Exception {
-
-    private static final long serialVersionUID = 4554154651844610376L;
-
-    public APBlockedException() {
-
-    }
-
-    public APBlockedException(String message) {
-        super(message);
-    }
-
-    public APBlockedException(Throwable cause) {
-        super(cause);
-    }
-
-    public APBlockedException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
index 20448def33437f49bf4b3ea2be42462d81cf9c9a..57abf6c532b4e08b9bd7c41cca488abb69b5aa94 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
@@ -275,7 +275,11 @@ public class Device implements IDevice {
             
             if (prev != null && 
                 !(dpid.equals(prev.getSwitchDPID()) &&
-                  port.equals(prev.getSwitchPort()))) {
+                  port.equals(prev.getSwitchPort())) &&
+                !topology.isInSameBroadcastDomain(dpid.longValue(),
+                		port.shortValue(),
+                        prev.getSwitchDPID().longValue(),
+                        prev.getSwitchPort().shortValue())) {
                 long curActive = 
                         deviceManager.apComparator.
                             getEffTS(cur, cur.getActiveSince());
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 469b0621697c86c767b3e72d60420217337cc654..80960bbc90436048b7382f50be04c3e93afd1e27 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -38,9 +38,11 @@ import java.util.concurrent.TimeUnit;
 
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IHAListener;
 import net.floodlightcontroller.core.IInfoProvider;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
@@ -81,7 +83,7 @@ import org.slf4j.LoggerFactory;
 public class DeviceManagerImpl implements 
         IDeviceService, IOFMessageListener,
         IStorageSourceListener, IFloodlightModule,
-        IInfoProvider {  
+        IInfoProvider, IHAListener {  
     protected static Logger logger = 
         LoggerFactory.getLogger(DeviceManagerImpl.class);
 
@@ -602,6 +604,28 @@ public class DeviceManagerImpl implements
             logger.error("Could not instantiate REST API");
         }
     }
+
+    // ***************
+    // IHAListener
+    // ***************
+
+    @Override
+    public void roleChanged(Role oldRole, Role newRole) {
+        switch(newRole) {
+            case SLAVE:
+                logger.debug("Resetting device state because of role change");
+                startUp(null);
+                break;
+        }
+    }
+
+    @Override
+    public void controllerNodeIPsChanged(
+                          Map<String, String> curControllerNodeIPs,
+                          Map<String, String> addedControllerNodeIPs,
+                          Map<String, String> removedControllerNodeIPs) {
+        // no-op
+    }
     
     // ****************
     // Internal methods
diff --git a/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java b/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0930bd0fcf73c977ae778ed6dcaf53cbbe15c24
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/packet/LLDPOrganizationalTLV.java
@@ -0,0 +1,181 @@
+/**
+ *    Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *    not use this file except in compliance with the License. You may obtain
+ *    a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    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
+ *    License for the specific language governing permissions and limitations
+ *    under the License.
+ **/
+
+package net.floodlightcontroller.packet;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+/**
+ * The class representing LLDP Organizationally Specific TLV.
+ *
+ * @author Sho Shimizu (sho.shimizu@gmail.com)
+ */
+public class LLDPOrganizationalTLV extends LLDPTLV {
+    public static final int OUI_LENGTH = 3;
+    public static final int SUBTYPE_LENGTH = 1;
+    public static final byte ORGANIZATIONAL_TLV_TYPE = 127;
+    public static final int MAX_INFOSTRING_LENGTH = 507;
+
+    protected byte[] oui;
+    protected byte subType;
+    private byte[] infoString;
+
+    public LLDPOrganizationalTLV() {
+        type = ORGANIZATIONAL_TLV_TYPE;
+    }
+
+    /**
+     * Set the value of OUI.
+     * @param oui The value of OUI to be set.
+     * @return This LLDP Organizationally Specific TLV.
+     */
+    public LLDPOrganizationalTLV setOUI(byte[] oui) {
+        if (oui.length != OUI_LENGTH) {
+            throw new IllegalArgumentException("The length of OUI must be " + OUI_LENGTH +
+                ", but it is " + oui.length);
+        }
+        this.oui = Arrays.copyOf(oui, oui.length);
+        return this;
+    }
+
+    /**
+     * Returns the value of the OUI.
+     * @return The value of the OUI .
+     */
+    public byte[] getOUI() {
+        return Arrays.copyOf(oui, oui.length);
+    }
+
+    /**
+     * Set the value of sub type.
+     * @param subType The value of sub type to be set.
+     * @return This LLDP Organizationally Specific TLV.
+     */
+    public LLDPOrganizationalTLV setSubType(byte subType) {
+        this.subType = subType;
+        return this;
+    }
+
+    /**
+     * Returns the value of the sub type.
+     * @return The value of the sub type.
+     */
+    public byte getSubType() {
+        return subType;
+    }
+
+    /**
+     * Set the value of information string.
+     * @param infoString the byte array of the value of information string.
+     * @return This LLDP Organizationally Specific TLV.
+     */
+    public LLDPOrganizationalTLV setInfoString(byte[] infoString) {
+        if (infoString.length > MAX_INFOSTRING_LENGTH) {
+            throw new IllegalArgumentException("The length of infoString cannot exceed " + MAX_INFOSTRING_LENGTH);
+        }
+        this.infoString = Arrays.copyOf(infoString, infoString.length);
+        return this;
+    }
+
+    /**
+     * Set the value of information string.
+     * The String value is automatically converted into byte array with UTF-8 encoding.
+     * @param infoString the String value of information string.
+     * @return This LLDP Organizationally Specific TLV.
+     */
+    public LLDPOrganizationalTLV setInfoString(String infoString) {
+        byte[] infoStringBytes = infoString.getBytes(Charset.forName("UTF-8"));
+        return setInfoString(infoStringBytes);
+    }
+
+    /**
+     * Returns the value of information string.
+     * @return the value of information string.
+     */
+    public byte[] getInfoString() {
+        return Arrays.copyOf(infoString, infoString.length);
+    }
+
+    @Override
+    public byte[] serialize() {
+        int valueLength = OUI_LENGTH + SUBTYPE_LENGTH + infoString.length;
+        value = new byte[valueLength];
+        ByteBuffer bb = ByteBuffer.wrap(value);
+        bb.put(oui);
+        bb.put(subType);
+        bb.put(infoString);
+        return super.serialize();
+    }
+
+    @Override
+    public LLDPTLV deserialize(ByteBuffer bb) {
+        super.deserialize(bb);
+        ByteBuffer optionalField = ByteBuffer.wrap(value);
+
+        byte[] oui = new byte[OUI_LENGTH];
+        optionalField.get(oui);
+        setOUI(oui);
+
+        setSubType(optionalField.get());
+
+        byte[] infoString = new byte[getLength() - OUI_LENGTH - SUBTYPE_LENGTH];
+        optionalField.get(infoString);
+        setInfoString(infoString);
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 1423;
+        int result = 1;
+        result = prime * result + type;
+        result = prime * result + length;
+        result = prime * result + Arrays.hashCode(oui);
+        result = prime * result + subType;
+        result = prime * result + Arrays.hashCode(infoString);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof LLDPOrganizationalTLV)) {
+            return false;
+        }
+
+        LLDPOrganizationalTLV other = (LLDPOrganizationalTLV)o;
+        if (this.type != other.type) {
+            return false;
+        }
+        if (this.length != other.length) {
+            return false;
+        }
+        if (!Arrays.equals(this.oui, other.oui)) {
+            return false;
+        }
+        if (this.subType != other.subType) {
+            return false;
+        }
+        if (!Arrays.equals(this.infoString, other.infoString)) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java
index b5a486c31cee6766fe9a0e1a8afb459ae8c0e391..7dec16b69d8d295985363703585fb82ab08f3da1 100644
--- a/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java
+++ b/src/main/java/org/openflow/protocol/statistics/OFAggregateStatisticsReply.java
@@ -18,6 +18,7 @@
 package org.openflow.protocol.statistics;
 
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.jboss.netty.buffer.ChannelBuffer;
 
 /**
@@ -72,6 +73,7 @@ public class OFAggregateStatisticsReply implements OFStatistics {
     }
 
     @Override
+    @JsonIgnore
     public int getLength() {
         return 24;
     }
diff --git a/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java
index 420717fb3df42007eb168af167bcaefd85467063..803db8a9167fee4918e7d795cb9b42b665191100 100644
--- a/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java
+++ b/src/main/java/org/openflow/protocol/statistics/OFFlowStatisticsReply.java
@@ -19,6 +19,7 @@ package org.openflow.protocol.statistics;
 
 import java.util.List;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.action.OFAction;
@@ -195,6 +196,7 @@ public class OFFlowStatisticsReply implements OFStatistics, OFActionFactoryAware
     }
 
     @Override
+    @JsonIgnore
     public int getLength() {
         return U16.f(length);
     }
diff --git a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java
index 047ca5425ee6cdc56f18a19091e3f56d8d84f580..87a2465eaef54df954157d05edf53ab5052c95eb 100644
--- a/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java
+++ b/src/main/java/org/openflow/protocol/statistics/OFPortStatisticsReply.java
@@ -18,6 +18,7 @@
 package org.openflow.protocol.statistics;
 
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.jboss.netty.buffer.ChannelBuffer;
 
 /**
@@ -222,6 +223,7 @@ public class OFPortStatisticsReply implements OFStatistics {
     }
 
     @Override
+    @JsonIgnore
     public int getLength() {
         return 104;
     }
diff --git a/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java b/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java
index 7d0238a3fffcd2fbf9e90450bdb3ef946924b8c6..03cbb9cef0c87b3056a57fef8c309e2ad2d1ed23 100644
--- a/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java
+++ b/src/main/java/org/openflow/protocol/statistics/OFQueueStatisticsReply.java
@@ -18,6 +18,7 @@
 package org.openflow.protocol.statistics;
 
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.jboss.netty.buffer.ChannelBuffer;
 
 /**
@@ -102,6 +103,7 @@ public class OFQueueStatisticsReply implements OFStatistics {
     }
 
     @Override
+    @JsonIgnore
     public int getLength() {
         return 32;
     }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index b238228f6158301239af76ce459ee07c556e5f2b..1b2b7e9a94b0dfb98e30c1b4a1c665999d3f47b2 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -685,7 +685,6 @@ public class ControllerTest extends FloodlightTestCase {
         
         // newsw.role is null because the switch does not support
         // role request messages
-        expect(newsw.getRole()).andReturn(null);
         expect(newsw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
                         .andReturn(false);
         // switch is connected 
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 18cc280309fe34ad2a8f9d87012971ba497ad5c6..7db7c6659843b6117297325f8f3597b15f4e11b8 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -415,6 +415,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         andReturn(10L).anyTimes();
         expect(mockTopology.isBroadcastDomainPort(anyLong(), anyShort())).
                 andReturn(false).anyTimes();
+        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
+        		anyLong(), anyShort())).andReturn(false).anyTimes();
         
         expect(mockTopology.isInternal(anyLong(), 
                                        anyShort())).andReturn(false).anyTimes();
@@ -499,6 +501,10 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
                 andReturn(false).anyTimes();
         expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
                 andReturn(true).anyTimes();
+        expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
+        		1L, (short)2)).andReturn(true).anyTimes();
+        expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
+        		1L, (short)1)).andReturn(true).anyTimes();
         
         replay(mockTopology);
         
@@ -717,6 +723,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         expect(mockTopology.isBroadcastDomainPort(anyLong(), 
                                                   anyShort())).
                                        andReturn(false).anyTimes();
+        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
+        		anyLong(), anyShort())).andReturn(false).anyTimes();
         expect(mockTopology.getSwitchClusterId(anyLong())).
                     andReturn(1L).anyTimes();
         replay(mockTopology);
@@ -809,6 +817,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         expect(mockTopology.isBroadcastDomainPort(anyLong(), 
                                                   anyShort())).
                                        andReturn(false).anyTimes();
+        expect(mockTopology.isInSameBroadcastDomain(anyLong(), anyShort(),
+                anyLong(), anyShort())).andReturn(false).anyTimes();
         expect(mockTopology.getSwitchClusterId(1L)).
                 andReturn(1L).anyTimes();
         expect(mockTopology.getSwitchClusterId(5L)).
diff --git a/src/test/java/net/floodlightcontroller/packet/LLDPOrganizationalTLVTest.java b/src/test/java/net/floodlightcontroller/packet/LLDPOrganizationalTLVTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..88fb26f2e75ed8dbf34d85d2f4a7e7b32e1e1e2b
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/packet/LLDPOrganizationalTLVTest.java
@@ -0,0 +1,95 @@
+/**
+ *    Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *    not use this file except in compliance with the License. You may obtain
+ *    a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    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
+ *    License for the specific language governing permissions and limitations
+ *    under the License.
+ **/
+
+package net.floodlightcontroller.packet;
+
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class LLDPOrganizationalTLVTest {
+    private final byte[] expected = new byte[] {
+        //  Type: 127, Length: 13
+        (byte) 254, 13,
+        // OpenFlow OUI: 00-26-E1
+        0x0, 0x26, (byte)0xe1,
+        //  SubType: 12
+        0xc,
+        //  Bytes in "ExtraInfo"
+        0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f
+    };
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testShortOUI() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setOUI(new byte[2]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLongOUI() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setOUI(new byte[4]);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLongInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString(new byte[LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH + 1]);
+    }
+
+    @Test
+    public void testMaxInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString(new byte[LLDPOrganizationalTLV.MAX_INFOSTRING_LENGTH]);
+    }
+
+    @Test
+    public void testInfoString() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setInfoString("ExtraInfo");
+        assertThat(tlv.getInfoString(), is("ExtraInfo".getBytes(Charset.forName("UTF-8"))));
+    }
+
+    @Test
+    public void testSerialize() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.setLength((short) 13);
+        // OpenFlow OUI is 00-26-E1
+        tlv.setOUI(new byte[] {0x0, 0x26, (byte) 0xe1});
+        tlv.setSubType((byte) 12);
+        tlv.setInfoString("ExtraInfo".getBytes(Charset.forName("UTF-8")));
+
+        assertThat(tlv.getType(), is((byte)127));
+        assertThat(tlv.getLength(), is((short)13));
+        assertThat(tlv.getOUI(), is(new byte[] {0x0, 0x26, (byte) 0xe1}));
+        assertThat(tlv.getSubType(), is((byte)12));
+        assertThat(tlv.serialize(), is(expected));
+    }
+
+    @Test
+    public void testDeserialize() {
+        LLDPOrganizationalTLV tlv = new LLDPOrganizationalTLV();
+        tlv.deserialize(ByteBuffer.wrap(expected));
+
+        assertThat(tlv.getType(), is((byte)127));
+        assertThat(tlv.getLength(), is((short)13));
+        assertThat(tlv.getOUI(), is(new byte[] {0x0, 0x26, (byte) 0xe1}));
+        assertThat(tlv.getSubType(), is((byte)12));
+        assertThat(tlv.getInfoString(), is("ExtraInfo".getBytes(Charset.forName("UTF-8"))));
+    }
+}