diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 177c46dbb5bcd534d8f4426b4a24a0be012c5d44..a4ee23073aa462db36295c529a48ffebee16519d 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -45,6 +46,7 @@ import net.floodlightcontroller.core.internal.Controller.IUpdate;
 import net.floodlightcontroller.core.internal.Controller.SwitchUpdate;
 import net.floodlightcontroller.core.internal.Controller.SwitchUpdateType;
 import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
+import net.floodlightcontroller.core.internal.RoleChanger.PendingRoleRequestEntry;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.core.test.MockThreadPoolService;
@@ -71,6 +73,7 @@ import org.openflow.protocol.OFError;
 import org.openflow.protocol.OFError.OFBadRequestCode;
 import org.openflow.protocol.OFError.OFErrorType;
 import org.openflow.protocol.OFFeaturesReply;
+import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPacketOut;
 import org.openflow.protocol.OFPhysicalPort;
@@ -88,9 +91,12 @@ import org.openflow.protocol.statistics.OFDescriptionStatistics;
 import org.openflow.protocol.statistics.OFFlowStatisticsReply;
 import org.openflow.protocol.statistics.OFStatistics;
 import org.openflow.protocol.statistics.OFStatisticsType;
+import org.openflow.protocol.vendor.OFVendorData;
 import org.openflow.util.HexString;
 import org.openflow.vendor.nicira.OFNiciraVendorData;
 import org.openflow.vendor.nicira.OFRoleReplyVendorData;
+import org.openflow.vendor.nicira.OFRoleRequestVendorData;
+import org.openflow.vendor.nicira.OFRoleVendorData;
 
 /**
  *
@@ -996,11 +1002,9 @@ public class ControllerTest extends FloodlightTestCase
         // in SLAVE mode and the switch does not support role-request messages
         state.firstRoleReplyReceived = false;
         controller.role = Role.SLAVE;
-        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupported(xid);
-        expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
-        expect(chdlr.sw.getRole()).andReturn(null).anyTimes();
-        expect(ch.close()).andReturn(null);
+        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);                
+        chdlr.sw.setHARole(Role.SLAVE, false);
+        chdlr.sw.disconnectOutputStream();
         
         replay(ch, chdlr.sw);
         chdlr.processOFMessage(msg);
@@ -1017,11 +1021,9 @@ public class ControllerTest extends FloodlightTestCase
         msg.setErrorCode(OFBadRequestCode.OFPBRC_EPERM);
         state.firstRoleReplyReceived = false;
         controller.role = Role.SLAVE;
-        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupported(xid);
-        expect(chdlr.sw.getChannel()).andReturn(ch).anyTimes();
-        expect(chdlr.sw.getRole()).andReturn(null).anyTimes();
-        expect(ch.close()).andReturn(null);
+        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);                
+        chdlr.sw.setHARole(Role.SLAVE, false);
+        chdlr.sw.disconnectOutputStream();
         replay(ch, chdlr.sw);
         
         chdlr.processOFMessage(msg);
@@ -1037,8 +1039,8 @@ public class ControllerTest extends FloodlightTestCase
         // switches.
         state.firstRoleReplyReceived = false;
         controller.role = Role.MASTER;
-        expect(chdlr.sw.checkFirstPendingRoleRequestXid(xid)).andReturn(true);
-        chdlr.sw.deliverRoleRequestNotSupported(xid);
+        setupPendingRoleRequest(chdlr.sw, xid, controller.role, 123456);                
+        chdlr.sw.setHARole(controller.role, false);
         setupSwitchForAddSwitch(chdlr.sw, 0L);
         chdlr.sw.clearAllFlowMods();
         expect(chdlr.sw.getRole()).andReturn(null).anyTimes();
@@ -1087,7 +1089,18 @@ public class ControllerTest extends FloodlightTestCase
         roleReplyVendorData.setRole(nicira_role);
         return msg;
     }
-   
+    
+    // Helper function
+    protected void setupPendingRoleRequest(IOFSwitch sw, int xid, Role role,
+            long cookie) {
+        LinkedList<PendingRoleRequestEntry> pendingList =
+                new LinkedList<PendingRoleRequestEntry>();
+        controller.roleChanger.pendingRequestMap.put(sw, pendingList);
+        PendingRoleRequestEntry entry =
+                new PendingRoleRequestEntry(xid, role, cookie);
+        pendingList.add(entry);
+    }
+    
     /** invalid role in role reply */
     @Test 
     public void testNiciraRoleReplyInvalidRole() 
@@ -1111,8 +1124,9 @@ public class ControllerTest extends FloodlightTestCase
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
-        
-        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);                
+        chdlr.sw.setHARole(Role.MASTER, true);
         expect(chdlr.sw.isActive()).andReturn(true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
         chdlr.sw.clearAllFlowMods();
@@ -1135,8 +1149,9 @@ public class ControllerTest extends FloodlightTestCase
         Controller.OFChannelHandler chdlr = getChannelHandlerForRoleReplyTest();
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
-        
-        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
+
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);        
+        chdlr.sw.setHARole(Role.MASTER, true);
         expect(chdlr.sw.isActive()).andReturn(true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
         chdlr.state.firstRoleReplyReceived = true;
@@ -1159,7 +1174,8 @@ public class ControllerTest extends FloodlightTestCase
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid,
                                        OFRoleReplyVendorData.NX_ROLE_OTHER);
         
-        chdlr.sw.deliverRoleReply(xid, Role.EQUAL);
+        setupPendingRoleRequest(chdlr.sw, xid, Role.EQUAL, 123456);                
+        chdlr.sw.setHARole(Role.EQUAL, true);
         expect(chdlr.sw.isActive()).andReturn(true);
         setupSwitchForAddSwitch(chdlr.sw, 1L);
         chdlr.sw.clearAllFlowMods();
@@ -1181,7 +1197,8 @@ public class ControllerTest extends FloodlightTestCase
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                        OFRoleReplyVendorData.NX_ROLE_SLAVE);
         
-        chdlr.sw.deliverRoleReply(xid, Role.SLAVE);
+        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);                
+        chdlr.sw.setHARole(Role.SLAVE, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
         expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                     .anyTimes();
@@ -1205,7 +1222,8 @@ public class ControllerTest extends FloodlightTestCase
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                        OFRoleReplyVendorData.NX_ROLE_MASTER);
         
-        chdlr.sw.deliverRoleReply(xid, Role.MASTER);
+        setupPendingRoleRequest(chdlr.sw, xid, Role.MASTER, 123456);                
+        chdlr.sw.setHARole(Role.MASTER, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
         expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                     .anyTimes();
@@ -1230,7 +1248,8 @@ public class ControllerTest extends FloodlightTestCase
         OFVendor msg = getRoleReplyMsgForRoleReplyTest(xid, 
                                        OFRoleReplyVendorData.NX_ROLE_SLAVE);
         
-        chdlr.sw.deliverRoleReply(xid, Role.SLAVE);
+        setupPendingRoleRequest(chdlr.sw, xid, Role.SLAVE, 123456);                
+        chdlr.sw.setHARole(Role.SLAVE, true);
         expect(chdlr.sw.getId()).andReturn(1L).anyTimes();
         expect(chdlr.sw.getStringId()).andReturn("00:00:00:00:00:00:00:01")
                     .anyTimes();
@@ -1331,4 +1350,43 @@ public class ControllerTest extends FloodlightTestCase
         }
         return null;
     }
+    
+    public void doSendNxRoleRequest(Role role, int nx_role) throws Exception {
+        long cookie = System.nanoTime();
+        OFSwitchImpl sw = new OFSwitchImpl();
+        Channel ch = createMock(Channel.class);
+        sw.setChannel(ch);
+        sw.setFloodlightProvider(controller);
+        
+        // verify that the correct OFMessage is sent
+        Capture<List<OFMessage>> msgCapture = new Capture<List<OFMessage>>();
+        expect(sw.channel.write(capture(msgCapture))).andReturn(null);
+        replay(sw.channel);
+        int xid = sw.sendHARoleRequest(role, cookie);
+        verify(sw.channel);
+        List<OFMessage> msgList = msgCapture.getValue();
+        assertEquals(1, msgList.size());
+        OFMessage msg = msgList.get(0);
+        assertEquals("Transaction Ids must match", xid, msg.getXid()); 
+        assertTrue("Message must be an OFVendor type", msg instanceof OFVendor);
+        assertEquals(OFType.VENDOR, msg.getType());
+        OFVendor vendorMsg = (OFVendor)msg;
+        assertEquals("Vendor message must be vendor Nicira",
+                     OFNiciraVendorData.NX_VENDOR_ID, vendorMsg.getVendor());
+        OFVendorData vendorData = vendorMsg.getVendorData();
+        assertTrue("Vendor Data must be an OFRoleRequestVendorData",
+                     vendorData instanceof OFRoleRequestVendorData);
+        OFRoleRequestVendorData roleRequest = (OFRoleRequestVendorData)vendorData;
+        assertEquals(nx_role, roleRequest.getRole());
+        
+        reset(sw.channel);
+    }
+    
+    @Test
+    public void testSendNxRoleRequest() throws Exception {
+        doSendNxRoleRequest(Role.MASTER, OFRoleVendorData.NX_ROLE_MASTER);
+        doSendNxRoleRequest(Role.SLAVE, OFRoleVendorData.NX_ROLE_SLAVE);
+        doSendNxRoleRequest(Role.EQUAL, OFRoleVendorData.NX_ROLE_OTHER);
+    }
+
 }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
index f70e56579715a7d5551311a85664035575330b07..fafcf28cc6fc6c082b4a56147fbf221119692246 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchImplTest.java
@@ -1,27 +1,18 @@
 package net.floodlightcontroller.core.internal;
 
 import static org.easymock.EasyMock.*;
+import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.util.List;
-
-import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.HARoleUnsupportedException;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.internal.OFSwitchImpl.PendingRoleRequestEntry;
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.test.FloodlightTestCase;
 
-import org.easymock.Capture;
 import org.jboss.netty.channel.Channel;
 import org.junit.Before;
 import org.junit.Test;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFVendor;
-import org.openflow.protocol.vendor.OFVendorData;
-import org.openflow.vendor.nicira.OFNiciraVendorData;
-import org.openflow.vendor.nicira.OFRoleRequestVendorData;
-import org.openflow.vendor.nicira.OFRoleVendorData;
 
 public class OFSwitchImplTest extends FloodlightTestCase {
     protected OFSwitchImpl sw;
@@ -36,201 +27,87 @@ public class OFSwitchImplTest extends FloodlightTestCase {
         sw.setChannel(ch);
         MockFloodlightProvider floodlightProvider = new MockFloodlightProvider();
         sw.setFloodlightProvider(floodlightProvider);
-    }
-
-    
-    public void doSendNxRoleRequest(Role role, int nx_role) throws Exception {
-        long cookie = System.nanoTime();
-        
-        // verify that the correct OFMessage is sent
-        Capture<List<OFMessage>> msgCapture = new Capture<List<OFMessage>>();
-        expect(sw.channel.write(capture(msgCapture))).andReturn(null);
-        replay(sw.channel);
-        int xid = sw.sendHARoleRequest(role, cookie);
-        verify(sw.channel);
-        List<OFMessage> msgList = msgCapture.getValue();
-        assertEquals(1, msgList.size());
-        OFMessage msg = msgList.get(0);
-        assertEquals("Transaction Ids must match", xid, msg.getXid()); 
-        assertTrue("Message must be an OFVendor type", msg instanceof OFVendor);
-        assertEquals(OFType.VENDOR, msg.getType());
-        OFVendor vendorMsg = (OFVendor)msg;
-        assertEquals("Vendor message must be vendor Nicira",
-                     OFNiciraVendorData.NX_VENDOR_ID, vendorMsg.getVendor());
-        OFVendorData vendorData = vendorMsg.getVendorData();
-        assertTrue("Vendor Data must be an OFRoleRequestVendorData",
-                     vendorData instanceof OFRoleRequestVendorData);
-        OFRoleRequestVendorData roleRequest = (OFRoleRequestVendorData)vendorData;
-        assertEquals(nx_role, roleRequest.getRole());
-        
-        // Now verify that we've added the pending request correctly
-        // to the pending queue
-        assertEquals(1, sw.pendingRoleRequests.size());
-        PendingRoleRequestEntry pendingRoleRequest = sw.pendingRoleRequests.poll();
-        assertEquals(msg.getXid(), pendingRoleRequest.xid);
-        assertEquals(role, pendingRoleRequest.role);
-        assertEquals(cookie, pendingRoleRequest.cookie);
-        reset(sw.channel);
-    }
+    }    
     
     @Test
-    public void testSendNxRoleRequest() throws Exception {
-        doSendNxRoleRequest(Role.MASTER, OFRoleVendorData.NX_ROLE_MASTER);
-        doSendNxRoleRequest(Role.SLAVE, OFRoleVendorData.NX_ROLE_SLAVE);
-        doSendNxRoleRequest(Role.EQUAL, OFRoleVendorData.NX_ROLE_OTHER);
+    public void testSendHARoleRequestFirstTime() {
+        boolean ioExceptionCaught = false;
+        boolean unsupportedExceptionCaught = false;
+        try {
+            sw.sendHARoleRequest(Role.MASTER, 12355);
+        } catch (IOException e) {
+            ioExceptionCaught = true;
+        } catch (HARoleUnsupportedException e) {
+            unsupportedExceptionCaught = true;
+        }
+        assertEquals(false, ioExceptionCaught);
+        assertEquals(false, unsupportedExceptionCaught);
     }
     
-    
     @Test
-    public void testDeliverRoleReplyOk() {
-        // test normal case
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.pendingRoleRequests.add(pending);
-        replay(sw.channel);
-        sw.deliverRoleReply(pending.xid, pending.role);
-        verify(sw.channel);
-        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
-        assertEquals(pending.role, sw.role);
-        assertEquals(0, sw.pendingRoleRequests.size());
+    public void testSendHARoleRequestSecondTime() {
+        boolean ioExceptionCaught = false;
+        boolean unsupportedExceptionCaught = false;
+        try {
+            sw.setHARole(Role.EQUAL, true);
+            sw.sendHARoleRequest(Role.MASTER, 12355);
+        } catch (IOException e) {
+            ioExceptionCaught = true;
+        } catch (HARoleUnsupportedException e) {
+            unsupportedExceptionCaught = true;
+        }
+        assertEquals(false, ioExceptionCaught);
+        assertEquals(false, unsupportedExceptionCaught);
     }
     
     @Test
-    public void testDeliverRoleReplyOkRepeated() {
-        // test normal case. Not the first role reply
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true);
-        sw.pendingRoleRequests.add(pending);
-        replay(sw.channel);
-        sw.deliverRoleReply(pending.xid, pending.role);
-        verify(sw.channel);
-        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
-        assertEquals(pending.role, sw.role);
-        assertEquals(0, sw.pendingRoleRequests.size());
+    public void testSendHARoleRequestUnsupported() {
+        boolean ioExceptionCaught = false;
+        boolean unsupportedExceptionCaught = false;
+        try {
+            sw.setHARole(Role.EQUAL, false);
+            sw.sendHARoleRequest(Role.MASTER, 12355);
+        } catch (IOException e) {
+            ioExceptionCaught = true;
+        } catch (HARoleUnsupportedException e) {
+            unsupportedExceptionCaught = true;
+        }
+        assertEquals(false, ioExceptionCaught);
+        assertEquals(true, unsupportedExceptionCaught);
     }
     
     @Test
-    public void testDeliverRoleReplyNonePending() {
-        // nothing pending 
-        expect(sw.channel.close()).andReturn(null);
-        replay(sw.channel);
-        sw.deliverRoleReply(1, Role.MASTER);
-        verify(sw.channel);
-        assertEquals(0, sw.pendingRoleRequests.size());
-    }
-    
-    @Test
-    public void testDeliverRoleReplyWrongXid() {
-        // wrong xid received 
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.pendingRoleRequests.add(pending);
-        expect(sw.channel.close()).andReturn(null);
-        replay(sw.channel);
-        sw.deliverRoleReply(pending.xid+1, pending.role);
-        verify(sw.channel);
+    public void testSetHARoleReplyReceived() {
         assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
-        assertEquals(0, sw.pendingRoleRequests.size());
+
+        sw.setHARole(Role.MASTER, true);
+        assertEquals(Role.MASTER, sw.role);
+        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        
+        sw.setHARole(Role.EQUAL, true);
+        assertEquals(Role.EQUAL, sw.role);
+        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        
+        sw.setHARole(Role.SLAVE, true);
+        assertEquals(Role.SLAVE, sw.role);
+        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
     }
     
     @Test
-    public void testDeliverRoleReplyWrongRole() {
-        // correct xid but incorrect role received
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.pendingRoleRequests.add(pending);
-        expect(sw.channel.close()).andReturn(null);
-        replay(sw.channel);
-        sw.deliverRoleReply(pending.xid, Role.SLAVE);
-        verify(sw.channel);
+    public void testSetHARoleNoReply() {
         assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
-        assertEquals(0, sw.pendingRoleRequests.size());
-    }
-    
-    @Test
-    public void testCheckFirstPendingRoleRequestXid() {
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            54321, Role.MASTER, 232323);
-        replay(sw.channel); // we don't expect any invocations 
-        sw.pendingRoleRequests.add(pending);
-        assertEquals(true, sw.checkFirstPendingRoleRequestXid(54321));
-        assertEquals(false, sw.checkFirstPendingRoleRequestXid(0));
-        sw.pendingRoleRequests.clear();
-        assertEquals(false, sw.checkFirstPendingRoleRequestXid(54321));
-        verify(sw.channel);
-    }
-    
-    @Test
-    public void testCheckFirstPendingRoleRequestCookie() {
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            54321, Role.MASTER, 232323);
-        replay(sw.channel); // we don't expect any invocations 
-        sw.pendingRoleRequests.add(pending);
-        assertEquals(true, sw.checkFirstPendingRoleRequestCookie(232323));
-        assertEquals(false, sw.checkFirstPendingRoleRequestCookie(0));
-        sw.pendingRoleRequests.clear();
-        assertEquals(false, sw.checkFirstPendingRoleRequestCookie(232323));
-        verify(sw.channel);
-    }
-    
-    @Test
-    public void testDeliverRoleRequestNotSupported () {
-        // normal case. xid is pending 
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.role = Role.SLAVE;
-        sw.pendingRoleRequests.add(pending);
-        replay(sw.channel);
-        sw.deliverRoleRequestNotSupported(pending.xid);
-        verify(sw.channel);
+
+        sw.setHARole(Role.MASTER, false);
+        assertEquals(Role.MASTER, sw.role);
+        assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        
+        sw.setHARole(Role.EQUAL, false);
+        assertEquals(Role.EQUAL, sw.role);
+        assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        
+        sw.setHARole(Role.SLAVE, false);
+        assertEquals(Role.SLAVE, sw.role);
         assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
-        assertEquals(null, sw.role);
-        assertEquals(0, sw.pendingRoleRequests.size());
-    }
-    
-    @Test
-    public void testDeliverRoleRequestNotSupportedNonePending() {
-        // nothing pending 
-        sw.role = Role.SLAVE;
-        expect(sw.channel.close()).andReturn(null);
-        replay(sw.channel);
-        sw.deliverRoleRequestNotSupported(1);
-        verify(sw.channel);
-        assertEquals(null, sw.role);
-        assertEquals(0, sw.pendingRoleRequests.size());
-    }
-    
-    @Test
-    public void testDeliverRoleRequestNotSupportedWrongXid() {
-        // wrong xid received 
-        PendingRoleRequestEntry pending = new PendingRoleRequestEntry(
-                            (int)System.currentTimeMillis(),  // arbitrary xid
-                            Role.MASTER,
-                            System.nanoTime() // arbitrary cookie
-                            );
-        sw.role = Role.SLAVE;
-        sw.pendingRoleRequests.add(pending);
-        expect(sw.channel.close()).andReturn(null);
-        replay(sw.channel);
-        sw.deliverRoleRequestNotSupported(pending.xid+1);
-        verify(sw.channel);
-        assertEquals(null, sw.role);
-        assertEquals(0, sw.pendingRoleRequests.size());
     }
+
 }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
index 76ea85d58b74a8c62138988496e3f3de069303f9..0b068824bfb4a8d1a33f14848c4afda4521a6877 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
@@ -7,10 +7,15 @@ import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.*;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
 import java.util.Collection;
 import java.util.LinkedList;
+
+import net.floodlightcontroller.core.HARoleUnsupportedException;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.internal.RoleChanger.PendingRoleRequestEntry;
 import net.floodlightcontroller.core.internal.RoleChanger.RoleChangeTask;
 
 import org.easymock.EasyMock;
@@ -31,7 +36,7 @@ public class RoleChangerTest {
      * The connection should be closed.
      */
     @Test
-    public void testSendRoleRequestSlaveNotSupported() {
+    public void testSendRoleRequestSlaveNotSupported() throws Exception {
         LinkedList<IOFSwitch> switches = new LinkedList<IOFSwitch>();
         
         // a switch that doesn't support role requests
@@ -39,8 +44,8 @@ public class RoleChangerTest {
         Channel channel1 = createMock(Channel.class);
         expect(sw1.getChannel()).andReturn(channel1);
         // No support for NX_ROLE
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(false); 
+        expect(sw1.sendHARoleRequest(Role.SLAVE, 123456))
+                .andThrow(new HARoleUnsupportedException()).once();;
         expect(channel1.close()).andReturn(null);
         switches.add(sw1);
         
@@ -58,14 +63,14 @@ public class RoleChangerTest {
      * The connection should be closed.
      */
     @Test
-    public void testSendRoleRequestMasterNotSupported() {
+    public void testSendRoleRequestMasterNotSupported() throws Exception {
         LinkedList<IOFSwitch> switches = new LinkedList<IOFSwitch>();
         
         // a switch that doesn't support role requests
         OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
         // No support for NX_ROLE
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(false); 
+        expect(sw1.sendHARoleRequest(Role.MASTER, 123456))
+                .andThrow(new HARoleUnsupportedException()).once();;
         switches.add(sw1);
         
         replay(sw1);
@@ -86,8 +91,6 @@ public class RoleChangerTest {
         // a switch that supports role requests
         OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
         // No support for NX_ROLE
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(true); 
         expect(sw1.sendHARoleRequest(Role.MASTER, 123456))
                     .andThrow(new IOException()).once();
         Channel channel1 = createMock(Channel.class);
@@ -112,20 +115,15 @@ public class RoleChangerTest {
         
         // a switch that supports role requests
         OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
-        // No support for NX_ROLE
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(true); 
+        // Support for NX_ROLE
         expect(sw1.sendHARoleRequest(Role.MASTER, 123456)).andReturn(1).once();
         switches.add(sw1);
         
-        // a switch for which we don't have SUPPORTS_NX_ROLE yet
+        // second switch
         OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class);
-        // No support for NX_ROLE
-        expect(sw2.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(null); 
+        // Support for NX_ROLE
         expect(sw2.sendHARoleRequest(Role.MASTER, 123456)).andReturn(1).once();
-        switches.add(sw2);
-        
+        switches.add(sw2);        
         
         replay(sw1, sw2);
         roleChanger.sendRoleRequest(switches, Role.MASTER, 123456);
@@ -135,22 +133,27 @@ public class RoleChangerTest {
     }
     
     @Test
-    public void testVerifyRoleReplyReceived() {
+    public void testVerifyRoleReplyReceived() throws Exception {
         Collection<IOFSwitch> switches = new LinkedList<IOFSwitch>();
         
         // Add a switch that has received a role reply
         OFSwitchImpl sw1 = EasyMock.createMock(OFSwitchImpl.class);
-        expect(sw1.checkFirstPendingRoleRequestCookie(123456))
-                        .andReturn(false).once();
+        LinkedList<PendingRoleRequestEntry> pendingList1 =
+                new LinkedList<PendingRoleRequestEntry>();
+        roleChanger.pendingRequestMap.put(sw1, pendingList1);
         switches.add(sw1);
         
         // Add a switch that has not yet received a role reply
         OFSwitchImpl sw2 = EasyMock.createMock(OFSwitchImpl.class);
-        expect(sw2.checkFirstPendingRoleRequestCookie(123456))
-                        .andReturn(true).once();
-        Channel channel2 = createMock(Channel.class);
-        expect(sw2.getChannel()).andReturn(channel2);
-        expect(channel2.close()).andReturn(null);
+        LinkedList<PendingRoleRequestEntry> pendingList2 =
+                new LinkedList<PendingRoleRequestEntry>();
+        roleChanger.pendingRequestMap.put(sw2, pendingList2);
+        PendingRoleRequestEntry entry =
+                new PendingRoleRequestEntry(1, Role.MASTER, 123456);
+        pendingList2.add(entry);
+        // Timed out switch should disconnect
+        sw2.setHARole(null, false);
+        EasyMock.expectLastCall();
         switches.add(sw2);
         
         
@@ -191,20 +194,11 @@ public class RoleChangerTest {
         
         // a switch that supports role requests
         OFSwitchImpl sw1 = EasyMock.createStrictMock(OFSwitchImpl.class);
-        // No support for NX_ROLE
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(true); 
+        // Support for NX_ROLE
         expect(sw1.sendHARoleRequest(EasyMock.same(Role.MASTER), EasyMock.anyLong()))
                        .andReturn(1);
-        expect(sw1.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE))
-                        .andReturn(true); 
         expect(sw1.sendHARoleRequest(EasyMock.same(Role.SLAVE), EasyMock.anyLong()))
                        .andReturn(1);
-        // The following calls happen for timeout handling:
-        expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong()))
-                        .andReturn(false);
-        expect(sw1.checkFirstPendingRoleRequestCookie(EasyMock.anyLong()))
-                        .andReturn(false);
         switches.add(sw1);
         
         
@@ -230,4 +224,176 @@ public class RoleChangerTest {
         
     }
     
+    // Helper function
+    protected void setupPendingRoleRequest(IOFSwitch sw, int xid, Role role,
+            long cookie) {
+        LinkedList<PendingRoleRequestEntry> pendingList =
+                new LinkedList<PendingRoleRequestEntry>();
+        roleChanger.pendingRequestMap.put(sw, pendingList);
+        PendingRoleRequestEntry entry =
+                new PendingRoleRequestEntry(xid, role, cookie);
+        pendingList.add(entry);
+    }
+    
+
+    @Test
+    public void testDeliverRoleReplyOk() {
+        // test normal case
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        roleChanger.deliverRoleReply(sw, xid, role);
+        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(role, sw.role);
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+    
+    @Test
+    public void testDeliverRoleReplyOkRepeated() {
+        // test normal case. Not the first role reply
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        sw.setAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE, true);
+        roleChanger.deliverRoleReply(sw, xid, role);
+        assertEquals(true, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(role, sw.role);
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+    
+    @Test
+    public void testDeliverRoleReplyNonePending() {
+        // nothing pending 
+        OFSwitchImpl sw = new OFSwitchImpl();
+        Channel ch = createMock(Channel.class);
+        SocketAddress sa = new InetSocketAddress(42);
+        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
+        sw.setChannel(ch);
+        roleChanger.deliverRoleReply(sw, 1, Role.MASTER);
+        assertEquals(null, sw.role);
+    }
+    
+    @Test
+    public void testDeliverRoleReplyWrongXid() {
+        // wrong xid received 
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        Channel ch = createMock(Channel.class);
+        SocketAddress sa = new InetSocketAddress(42);
+        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
+        sw.setChannel(ch);
+        expect(ch.close()).andReturn(null);
+        replay(ch);
+        roleChanger.deliverRoleReply(sw, xid+1, role);
+        verify(ch);
+        assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+    
+    @Test
+    public void testDeliverRoleReplyWrongRole() {
+        // correct xid but incorrect role received
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        Channel ch = createMock(Channel.class);
+        SocketAddress sa = new InetSocketAddress(42);
+        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
+        sw.setChannel(ch);
+        expect(ch.close()).andReturn(null);
+        replay(ch);
+        roleChanger.deliverRoleReply(sw, xid, Role.SLAVE);
+        verify(ch);
+        assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+    
+    @Test
+    public void testCheckFirstPendingRoleRequestXid() {
+        int xid = 54321;
+        long cookie = 232323;
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        assertEquals(true,
+                roleChanger.checkFirstPendingRoleRequestXid(sw, xid));
+        assertEquals(false,
+                roleChanger.checkFirstPendingRoleRequestXid(sw, 0));
+        roleChanger.pendingRequestMap.get(sw).clear();
+        assertEquals(false,
+                roleChanger.checkFirstPendingRoleRequestXid(sw, xid));
+    }
+    
+    @Test
+    public void testCheckFirstPendingRoleRequestCookie() {
+        int xid = 54321;
+        long cookie = 232323;
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        assertEquals(true,
+                roleChanger.checkFirstPendingRoleRequestCookie(sw, cookie));
+        assertEquals(false,
+                roleChanger.checkFirstPendingRoleRequestCookie(sw, 0));
+        roleChanger.pendingRequestMap.get(sw).clear();
+        assertEquals(false,
+                roleChanger.checkFirstPendingRoleRequestCookie(sw, cookie));
+    }
+    
+    @Test
+    public void testDeliverRoleRequestNotSupported () {
+        // normal case. xid is pending 
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        roleChanger.deliverRoleRequestNotSupported(sw, xid);
+        assertEquals(false, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(role, sw.role);
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+    
+    @Test
+    public void testDeliverRoleRequestNotSupportedNonePending() {
+        // nothing pending 
+        OFSwitchImpl sw = new OFSwitchImpl();
+        Channel ch = createMock(Channel.class);
+        SocketAddress sa = new InetSocketAddress(42);
+        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
+        sw.setChannel(ch);
+        roleChanger.deliverRoleRequestNotSupported(sw, 1);
+        assertEquals(null, sw.role);
+    }
+    
+    @Test
+    public void testDeliverRoleRequestNotSupportedWrongXid() {
+        // wrong xid received 
+        // wrong xid received 
+        int xid = (int) System.currentTimeMillis();
+        long cookie = System.nanoTime();
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        Channel ch = createMock(Channel.class);
+        SocketAddress sa = new InetSocketAddress(42);
+        expect(ch.getRemoteAddress()).andReturn(sa).anyTimes();
+        sw.setChannel(ch);
+        expect(ch.close()).andReturn(null);
+        replay(ch);
+        roleChanger.deliverRoleRequestNotSupported(sw, xid+1);
+        verify(ch);
+        assertEquals(null, sw.getAttribute(IOFSwitch.SWITCH_SUPPORTS_NX_ROLE));
+        assertEquals(0, roleChanger.pendingRequestMap.get(sw).size());
+    }
+
 }
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index 301832f6a9400f29f28a0d7c6fa9c871e2ffc449..589a15586d78945c34d47da7a92ead1a77157595 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -355,4 +355,10 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro
         
     }
 
+    @Override
+    public void sendNxRoleRequest(IOFSwitch sw, int xid, Role role, long cookie) {
+        // TODO Auto-generated method stub
+        
+    }
+
 }
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 68da09206efa9cef9ce8beecb90cbb53ad033827..04c442f25c3ff9da97002fb088bad01143130bb7 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -355,12 +355,6 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return 0;
     }
 
-    @Override
-    public boolean checkFirstPendingRoleRequestCookie(long cookie) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
     @Override
     public void setChannel(Channel channel) {
         // TODO Auto-generated method stub
@@ -379,18 +373,6 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         
     }
 
-    @Override
-    public void deliverRoleReply(int xid, Role role) {
-        // TODO Auto-generated method stub
-        
-    }
-
-    @Override
-    public void deliverRoleRequestNotSupported(int xid) {
-        // TODO Auto-generated method stub
-        
-    }
-
     @Override
     public Lock getListenerReadLock() {
         // TODO Auto-generated method stub
@@ -398,15 +380,15 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
     }
 
     @Override
-    public boolean checkFirstPendingRoleRequestXid(int xid) {
+    public Lock getListenerWriteLock() {
         // TODO Auto-generated method stub
-        return false;
+        return null;
     }
 
     @Override
-    public Lock getListenerWriteLock() {
+    public void setHARole(Role role, boolean haRoleReplyReceived) {
         // TODO Auto-generated method stub
-        return null;
+        
     }
 
 }
\ No newline at end of file