diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c
index d875b842dde266e3b7779a6a14cd6f95d3136828..cbcfd7e6c761daa508121af13e128c2a75a0278d 100644
--- a/Bootloaders/CDC/BootloaderCDC.c
+++ b/Bootloaders/CDC/BootloaderCDC.c
@@ -165,9 +165,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				
 				Endpoint_ClearIN();
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -176,16 +174,18 @@ void EVENT_USB_UnhandledControlPacket(void)
 			{
 				Endpoint_ClearSETUP();
 
-				while (!(Endpoint_IsOUTReceived()));
-
+				while (!(Endpoint_IsOUTReceived()))
+				{				
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
+			
 				for (uint8_t i = 0; i < sizeof(LineCoding); i++)
 				  *(LineCodingData++) = Endpoint_Read_Byte();
 
 				Endpoint_ClearOUT();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -194,9 +194,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 			{
 				Endpoint_ClearSETUP();
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -333,7 +331,12 @@ static uint8_t FetchNextCommandByte(void)
 	while (!(Endpoint_IsReadWriteAllowed()))
 	{
 		Endpoint_ClearOUT();
-		while (!(Endpoint_IsOUTReceived()));
+
+		while (!(Endpoint_IsOUTReceived()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return 0;
+		}
 	}
 	
 	/* Fetch the next byte from the OUT endpoint */
@@ -354,7 +357,12 @@ static void WriteNextResponseByte(const uint8_t Response)
 	if (!(Endpoint_IsReadWriteAllowed()))
 	{
 		Endpoint_ClearIN();
-		while (!(Endpoint_IsINReady()));
+		
+		while (!(Endpoint_IsINReady()))
+		{				
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 	}
 	
 	/* Write the next byte to the OUT endpoint */
@@ -563,12 +571,21 @@ void CDC_Task(void)
 		/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
 		if (IsEndpointFull)
 		{
-			while (!(Endpoint_IsINReady()));
+			while (!(Endpoint_IsINReady()))
+			{				
+				if (USB_DeviceState == DEVICE_STATE_Unattached)
+				  return;
+			}
+
 			Endpoint_ClearIN();
 		}
 
 		/* Wait until the data has been sent to the host */
-		while (!(Endpoint_IsINReady()));
+		while (!(Endpoint_IsINReady()))
+		{				
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 		
 		/* Select the OUT endpoint */
 		Endpoint_SelectEndpoint(CDC_RX_EPNUM);
diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c
index 2086a91d2095093999568afb12766ab54269a238..f9c8195f37910ba7d9066434d20beb407e1f4f0d 100644
--- a/Bootloaders/DFU/BootloaderDFU.c
+++ b/Bootloaders/DFU/BootloaderDFU.c
@@ -177,7 +177,11 @@ void EVENT_USB_UnhandledControlPacket(void)
 			/* If the request has a data stage, load it into the command struct */
 			if (SentCommand.DataSize)
 			{
-				while (!(Endpoint_IsOUTReceived()));
+				while (!(Endpoint_IsOUTReceived()))
+				{				
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 
 				/* First byte of the data stage is the DNLOAD request's command */
 				SentCommand.Command = Endpoint_Read_Byte();
@@ -235,7 +239,12 @@ void EVENT_USB_UnhandledControlPacket(void)
 							if (!(Endpoint_BytesInEndpoint()))
 							{
 								Endpoint_ClearOUT();
-								while (!(Endpoint_IsOUTReceived()));
+
+								while (!(Endpoint_IsOUTReceived()))
+								{				
+									if (USB_DeviceState == DEVICE_STATE_Unattached)
+									  return;
+								}
 							}
 
 							/* Write the next word into the current flash page */
@@ -279,7 +288,12 @@ void EVENT_USB_UnhandledControlPacket(void)
 							if (!(Endpoint_BytesInEndpoint()))
 							{
 								Endpoint_ClearOUT();
-								while (!(Endpoint_IsOUTReceived()));
+
+								while (!(Endpoint_IsOUTReceived()))
+								{				
+									if (USB_DeviceState == DEVICE_STATE_Unattached)
+									  return;
+								}
 							}
 
 							/* Read the byte from the USB interface and write to to the EEPROM */
@@ -297,16 +311,18 @@ void EVENT_USB_UnhandledControlPacket(void)
 
 			Endpoint_ClearOUT();
 
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsINReady()));
-			Endpoint_ClearIN();
-				
+			Endpoint_ClearStatusStage();
+
 			break;
 		case DFU_UPLOAD:
 			Endpoint_ClearSETUP();
 
-			while (!(Endpoint_IsINReady()));
-
+			while (!(Endpoint_IsINReady()))
+			{				
+				if (USB_DeviceState == DEVICE_STATE_Unattached)
+				  return;
+			}
+							
 			if (DFU_State != dfuUPLOAD_IDLE)
 			{
 				if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01))       // Blank Check
@@ -343,7 +359,12 @@ void EVENT_USB_UnhandledControlPacket(void)
 						if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
 						{
 							Endpoint_ClearIN();
-							while (!(Endpoint_IsINReady()));
+
+							while (!(Endpoint_IsINReady()))
+							{				
+								if (USB_DeviceState == DEVICE_STATE_Unattached)
+								  return;
+							}
 						}
 
 						/* Read the flash word and send it via USB to the host */
@@ -368,7 +389,12 @@ void EVENT_USB_UnhandledControlPacket(void)
 						if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
 						{
 							Endpoint_ClearIN();
-							while (!(Endpoint_IsINReady()));
+							
+							while (!(Endpoint_IsINReady()))
+							{				
+								if (USB_DeviceState == DEVICE_STATE_Unattached)
+								  return;
+							}
 						}
 
 						/* Read the EEPROM byte and send it via USB to the host */
@@ -385,10 +411,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 
 			Endpoint_ClearIN();
 
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsOUTReceived()));
-			Endpoint_ClearOUT();
-
+			Endpoint_ClearStatusStage();
 			break;
 		case DFU_GETSTATUS:
 			Endpoint_ClearSETUP();
@@ -408,10 +431,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 
 			Endpoint_ClearIN();
 			
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsOUTReceived()));
-			Endpoint_ClearOUT();
-	
+			Endpoint_ClearStatusStage();
 			break;		
 		case DFU_CLRSTATUS:
 			Endpoint_ClearSETUP();
@@ -419,10 +439,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 			/* Reset the status value variable to the default OK status */
 			DFU_Status = OK;
 
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsINReady()));
-			Endpoint_ClearIN();
-			
+			Endpoint_ClearStatusStage();
 			break;
 		case DFU_GETSTATE:
 			Endpoint_ClearSETUP();
@@ -432,21 +449,15 @@ void EVENT_USB_UnhandledControlPacket(void)
 		
 			Endpoint_ClearIN();
 			
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsOUTReceived()));
-			Endpoint_ClearOUT();
-
+			Endpoint_ClearStatusStage();
 			break;
 		case DFU_ABORT:
 			Endpoint_ClearSETUP();
 			
 			/* Reset the current state variable to the default idle state */
 			DFU_State = dfuIDLE;
-			
-			/* Acknowledge status stage */
-			while (!(Endpoint_IsINReady()));
-			Endpoint_ClearIN();
 
+			Endpoint_ClearStatusStage();
 			break;
 	}
 }
@@ -465,7 +476,11 @@ static void DiscardFillerBytes(uint8_t NumberOfBytes)
 			Endpoint_ClearOUT();
 
 			/* Wait until next data packet received */
-			while (!(Endpoint_IsOUTReceived()));
+			while (!(Endpoint_IsOUTReceived()))
+			{				
+				if (USB_DeviceState == DEVICE_STATE_Unattached)
+				  return;
+			}
 		}
 		else
 		{
diff --git a/Bootloaders/TeensyHID/TeensyHID.c b/Bootloaders/TeensyHID/TeensyHID.c
index 12d5c0de846c909aaf0bacb9a6479bc9bb6a7e0a..eed709783deec6d63abd6e0f9230ae316a4e7083 100644
--- a/Bootloaders/TeensyHID/TeensyHID.c
+++ b/Bootloaders/TeensyHID/TeensyHID.c
@@ -119,7 +119,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				
 				/* Wait until the command (report) has been sent by the host */
 				while (!(Endpoint_IsOUTReceived()));
-
+			
 				/* Read in the write destination address */
 				uint16_t PageAddress = Endpoint_Read_Word_LE();
 				
@@ -158,9 +158,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 
 				Endpoint_ClearOUT();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
diff --git a/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c b/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c
index 1c584e71c3bec831c345a15aa7f2331121f92c64..5f12d02b438193313b656dc601571fe80d5e4396 100644
--- a/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c
+++ b/Demos/Device/ClassDriver/MassStorage/Lib/DataflashManager.c
@@ -69,7 +69,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
 	Dataflash_SendAddressBytes(0, CurrDFPageByte);
 
 	/* Wait until endpoint is ready before continuing */
-	while (!(Endpoint_IsReadWriteAllowed()));
+	while (!(Endpoint_IsReadWriteAllowed()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;
+	}
 
 	while (TotalBlocks)
 	{
@@ -85,7 +89,11 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
 				Endpoint_ClearOUT();
 				
 				/* Wait until the host has sent another packet */
-				while (!(Endpoint_IsReadWriteAllowed()));
+				while (!(Endpoint_IsReadWriteAllowed()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 			}
 
 			/* Check if end of dataflash page reached */
@@ -197,7 +205,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
 	Dataflash_SendByte(0x00);
 	
 	/* Wait until endpoint is ready before continuing */
-	while (!(Endpoint_IsReadWriteAllowed()));
+	while (!(Endpoint_IsReadWriteAllowed()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;
+	}
 	
 	while (TotalBlocks)
 	{
@@ -213,7 +225,11 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
 				Endpoint_ClearIN();
 				
 				/* Wait until the endpoint is ready for more data */
-				while (!(Endpoint_IsReadWriteAllowed()));
+				while (!(Endpoint_IsReadWriteAllowed()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 			}
 			
 			/* Check if end of dataflash page reached */
diff --git a/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c b/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c
index ac63f0f9fc6eaa3092ba43a7a19329d5935fa579..89537066c67104f7cbbd9c15776f30522da02fca 100644
--- a/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c
+++ b/Demos/Device/ClassDriver/USBtoSerial/USBtoSerial.c
@@ -152,7 +152,7 @@ void EVENT_USB_UnhandledControlPacket(void)
  */
 ISR(USART1_RX_vect, ISR_BLOCK)
 {
-	if (USB_IsConnected)
+	if (USB_DeviceState == DEVICE_STATE_Configured)
 	  Buffer_StoreElement(&Tx_Buffer, UDR1);
 }
 
diff --git a/Demos/Device/Incomplete/Sideshow/Sideshow.c b/Demos/Device/Incomplete/Sideshow/Sideshow.c
index cc8bd51c383333a0bb2833715db135b240629276..d67fae03fb74f103b038fc30394e9e81a43d46ed 100644
--- a/Demos/Device/Incomplete/Sideshow/Sideshow.c
+++ b/Demos/Device/Incomplete/Sideshow/Sideshow.c
@@ -142,7 +142,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 void SideShow_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Select the SideShow data out endpoint */
diff --git a/Demos/Device/LowLevel/AudioInput/AudioInput.c b/Demos/Device/LowLevel/AudioInput/AudioInput.c
index 5656b05d1008242e19e497209c9b7296edaac41f..bf790169ddd1f1e4264ee5855b149597a07f23a0 100644
--- a/Demos/Device/LowLevel/AudioInput/AudioInput.c
+++ b/Demos/Device/LowLevel/AudioInput/AudioInput.c
@@ -139,9 +139,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
 				StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -152,7 +150,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 void USB_Audio_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Check to see if the streaming interface is selected, if not the host is not receiving audio */
diff --git a/Demos/Device/LowLevel/AudioOutput/AudioOutput.c b/Demos/Device/LowLevel/AudioOutput/AudioOutput.c
index 6d22009dcc358249c86c1f3e1026caa44871db55..89c4446bcc839f1ce08ab20fe2b9792763ef14b3 100644
--- a/Demos/Device/LowLevel/AudioOutput/AudioOutput.c
+++ b/Demos/Device/LowLevel/AudioOutput/AudioOutput.c
@@ -166,9 +166,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
 				StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -181,7 +179,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 void USB_Audio_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Check to see if the streaming interface is selected, if not the host is not receiving audio */
diff --git a/Demos/Device/LowLevel/CDC/CDC.c b/Demos/Device/LowLevel/CDC/CDC.c
index d8263b11f75a4162fc11e2425bb2b2cd7eb97d8b..e63257dbdc2dc7a934d1d278f3c67082b3b3693b 100644
--- a/Demos/Device/LowLevel/CDC/CDC.c
+++ b/Demos/Device/LowLevel/CDC/CDC.c
@@ -56,12 +56,15 @@ CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
  */
 	
 static int CDC_putchar (char c, FILE *stream)
-{
-	if (!(USB_IsConnected))
-	  return -1;
-	  
+{	  
 	Endpoint_SelectEndpoint(CDC_TX_EPNUM);
-	while (!(Endpoint_IsReadWriteAllowed()));
+
+	while (!(Endpoint_IsReadWriteAllowed()))
+	{
+		if (USB_DeviceState != DEVICE_STATE_Configured)
+		  return -1;
+	}
+
 	Endpoint_Write_Byte(c);
 	Endpoint_ClearIN();
 	
@@ -76,10 +79,11 @@ static int CDC_getchar (FILE *stream)
 	
 	for (;;)
 	{
-		if (!(USB_IsConnected))
-		  return -1;
-
-		while (!(Endpoint_IsReadWriteAllowed()));
+		while (!(Endpoint_IsReadWriteAllowed()))
+		{
+			if (USB_DeviceState != DEVICE_STATE_Configured)
+			  return -1;
+		}
 	
 		if (!(Endpoint_BytesInEndpoint()))
 		{
@@ -229,9 +233,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 						 CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
 				*/
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -244,18 +246,17 @@ void CDC_Task(void)
 	char*       ReportString    = NULL;
 	uint8_t     JoyStatus_LCL   = Joystick_GetStatus();
 	static bool ActionSent      = false;
-
-	char* JoystickStrings[] =
-		{
-			"Joystick Up\r\n",
-			"Joystick Down\r\n",
-			"Joystick Left\r\n",
-			"Joystick Right\r\n",
-			"Joystick Pressed\r\n",
-		};
+	char*       JoystickStrings[] =
+					{
+						"Joystick Up\r\n",
+						"Joystick Down\r\n",
+						"Joystick Left\r\n",
+						"Joystick Right\r\n",
+						"Joystick Pressed\r\n",
+					};
 	
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 	  
 #if 0
@@ -319,7 +320,11 @@ void CDC_Task(void)
 		if (IsFull)
 		{
 			/* Wait until the endpoint is ready for another packet */
-			while (!(Endpoint_IsINReady()));
+			while (!(Endpoint_IsINReady()))
+			{
+				if (USB_DeviceState == DEVICE_STATE_Unattached)
+				  return;
+			}
 			
 			/* Send an empty packet to ensure that the host does not buffer data sent to it */
 			Endpoint_ClearIN();
diff --git a/Demos/Device/LowLevel/DualCDC/DualCDC.c b/Demos/Device/LowLevel/DualCDC/DualCDC.c
index 862945e63187d5a76807e9ba27990a250502b5d9..dd278d5353dc95dcdbd7b123d0a9697fb0716da9 100644
--- a/Demos/Device/LowLevel/DualCDC/DualCDC.c
+++ b/Demos/Device/LowLevel/DualCDC/DualCDC.c
@@ -211,9 +211,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Acknowledge the SETUP packet, ready for data transfer */
 				Endpoint_ClearSETUP();
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -228,20 +226,19 @@ void CDC1_Task(void)
 	char*       ReportString    = NULL;
 	uint8_t     JoyStatus_LCL   = Joystick_GetStatus();
 	static bool ActionSent      = false;
-
+	char*       JoystickStrings[] =
+					{
+						"Joystick Up\r\n",
+						"Joystick Down\r\n",
+						"Joystick Left\r\n",
+						"Joystick Right\r\n",
+						"Joystick Pressed\r\n",
+					};
+	
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
-	char* JoystickStrings[] =
-		{
-			"Joystick Up\r\n",
-			"Joystick Down\r\n",
-			"Joystick Left\r\n",
-			"Joystick Right\r\n",
-			"Joystick Pressed\r\n",
-		};
-
 	/* Determine if a joystick action has occurred */
 	if (JoyStatus_LCL & JOY_UP)
 	  ReportString = JoystickStrings[0];
@@ -273,7 +270,11 @@ void CDC1_Task(void)
 		Endpoint_ClearIN();
 
 		/* Wait until the endpoint is ready for another packet */
-		while (!(Endpoint_IsINReady()));
+		while (!(Endpoint_IsINReady()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 		
 		/* Send an empty packet to ensure that the host does not buffer data sent to it */
 		Endpoint_ClearIN();
@@ -293,7 +294,7 @@ void CDC1_Task(void)
 void CDC2_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Select the Serial Rx Endpoint */
@@ -324,7 +325,11 @@ void CDC2_Task(void)
 		Endpoint_ClearIN();
 
 		/* Wait until the endpoint is ready for the next packet */
-		while (!(Endpoint_IsINReady()));
+		while (!(Endpoint_IsINReady()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 
 		/* Send an empty packet to prevent host buffering */
 		Endpoint_ClearIN();
diff --git a/Demos/Device/LowLevel/GenericHID/GenericHID.c b/Demos/Device/LowLevel/GenericHID/GenericHID.c
index 5c6d1ee4701ccb4ab015812cc755845706dc135f..34c991f12fa646aaf9addf54eaf072b4851d2ec2 100644
--- a/Demos/Device/LowLevel/GenericHID/GenericHID.c
+++ b/Demos/Device/LowLevel/GenericHID/GenericHID.c
@@ -148,7 +148,11 @@ void EVENT_USB_UnhandledControlPacket(void)
 				Endpoint_ClearSETUP();
 				
 				/* Wait until the generic report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
+				while (!(Endpoint_IsOUTReceived()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 
 				Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));
 
@@ -158,7 +162,11 @@ void EVENT_USB_UnhandledControlPacket(void)
 				Endpoint_ClearOUT();
 
 				/* Wait until the host is ready to receive the request confirmation */
-				while (!(Endpoint_IsINReady()));
+				while (!(Endpoint_IsINReady()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 				
 				/* Handshake the request by sending an empty IN packet */
 				Endpoint_ClearIN();
@@ -203,7 +211,7 @@ void CreateGenericHIDReport(uint8_t* DataArray)
 void HID_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);
diff --git a/Demos/Device/LowLevel/Joystick/Joystick.c b/Demos/Device/LowLevel/Joystick/Joystick.c
index e117475376235c2e8227babcd69b94d89a0d1054..db2415e4bcfd6eb0ed91a51492f4ad38640a4bd5 100644
--- a/Demos/Device/LowLevel/Joystick/Joystick.c
+++ b/Demos/Device/LowLevel/Joystick/Joystick.c
@@ -182,7 +182,7 @@ bool GetNextReport(USB_JoystickReport_Data_t* ReportData)
 void HID_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
   
 	/* Select the Joystick Report Endpoint */
diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.c b/Demos/Device/LowLevel/Keyboard/Keyboard.c
index 9950484bae970ea11094830a48248edae2fe8c3f..e27b22827fed54834b8774fd05b3ecf9a2dc8fb3 100644
--- a/Demos/Device/LowLevel/Keyboard/Keyboard.c
+++ b/Demos/Device/LowLevel/Keyboard/Keyboard.c
@@ -172,7 +172,11 @@ void EVENT_USB_UnhandledControlPacket(void)
 				Endpoint_ClearSETUP();
 				
 				/* Wait until the LED report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
+				while (!(Endpoint_IsOUTReceived()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 
 				/* Read in the LED report from the host */
 				uint8_t LEDStatus = Endpoint_Read_Byte();
@@ -183,9 +187,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Clear the endpoint data */
 				Endpoint_ClearOUT();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -200,9 +202,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Send the flag to the host */
 				Endpoint_ClearIN();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -214,9 +214,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Set or clear the flag depending on what the host indicates that the current Protocol should be */
 				UsingReportProtocol = (USB_ControlRequest.wValue != 0);
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -228,9 +226,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Get idle period in MSB, IdleCount must be multiplied by 4 to get number of milliseconds */
 				IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -245,9 +241,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Send the flag to the host */
 				Endpoint_ClearIN();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -378,7 +372,7 @@ void ReceiveNextReport(void)
 void HID_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 	  
 	/* Send the next keypress report to the host */
diff --git a/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c b/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c
index c60f08f9c526916b1cc2f143c5d692ca4960a42e..7d486e16e38ab32909b688e9060fb299541f860a 100644
--- a/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c
+++ b/Demos/Device/LowLevel/KeyboardMouse/KeyboardMouse.c
@@ -174,7 +174,11 @@ void EVENT_USB_UnhandledControlPacket(void)
 				Endpoint_ClearSETUP();
 				
 				/* Wait until the LED report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
+				while (!(Endpoint_IsOUTReceived()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 
 				/* Read in the LED report from the host */
 				uint8_t LEDStatus = Endpoint_Read_Byte();
@@ -195,9 +199,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Clear the endpoint data */
 				Endpoint_ClearOUT();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -213,7 +215,7 @@ void Keyboard_HID_Task(void)
 	uint8_t JoyStatus_LCL = Joystick_GetStatus();
 
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Check if board button is not pressed, if so mouse mode enabled */
@@ -284,7 +286,7 @@ void Mouse_HID_Task(void)
 	uint8_t JoyStatus_LCL = Joystick_GetStatus();
 
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Check if board button is pressed, if so mouse mode enabled */
diff --git a/Demos/Device/LowLevel/MIDI/MIDI.c b/Demos/Device/LowLevel/MIDI/MIDI.c
index 954cbcbf640d01fc37fad6862dec9bf7cd58d528..8aed527dbe82206a780c80fd90bfd950077ebc73 100644
--- a/Demos/Device/LowLevel/MIDI/MIDI.c
+++ b/Demos/Device/LowLevel/MIDI/MIDI.c
@@ -117,7 +117,7 @@ void MIDI_Task(void)
 	static uint8_t PrevJoystickStatus;
 
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
diff --git a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c
index fdc91dd5d8304d8bce77aa51ae563372672fc899..2bd03c98d925caab5bf263200ec00a6fde494a29 100644
--- a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c
+++ b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c
@@ -68,8 +68,12 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
 	Dataflash_SendAddressBytes(0, CurrDFPageByte);
 
 	/* Wait until endpoint is ready before continuing */
-	while (!(Endpoint_IsReadWriteAllowed()));
-
+	while (!(Endpoint_IsReadWriteAllowed()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;
+	}
+	
 	while (TotalBlocks)
 	{
 		uint8_t BytesInBlockDiv16 = 0;
@@ -84,7 +88,11 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
 				Endpoint_ClearOUT();
 				
 				/* Wait until the host has sent another packet */
-				while (!(Endpoint_IsReadWriteAllowed()));
+				while (!(Endpoint_IsReadWriteAllowed()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 			}
 
 			/* Check if end of dataflash page reached */
@@ -195,7 +203,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
 	Dataflash_SendByte(0x00);
 	
 	/* Wait until endpoint is ready before continuing */
-	while (!(Endpoint_IsReadWriteAllowed()));
+	while (!(Endpoint_IsReadWriteAllowed()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;
+	}
 	
 	while (TotalBlocks)
 	{
@@ -211,7 +223,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
 				Endpoint_ClearIN();
 				
 				/* Wait until the endpoint is ready for more data */
-				while (!(Endpoint_IsReadWriteAllowed()));
+				while (!(Endpoint_IsReadWriteAllowed()))
+				{
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
 			}
 			
 			/* Check if end of dataflash page reached */
diff --git a/Demos/Device/LowLevel/MassStorage/MassStorage.c b/Demos/Device/LowLevel/MassStorage/MassStorage.c
index 2c80fc595e7074aee3bb5ab6e77e9a0a66fa0029..01d27f043aa529f091b2bb86596110a375c08bbb 100644
--- a/Demos/Device/LowLevel/MassStorage/MassStorage.c
+++ b/Demos/Device/LowLevel/MassStorage/MassStorage.c
@@ -142,9 +142,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Indicate that the current transfer should be aborted */
 				IsMassStoreReset = true;			
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -158,9 +156,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				
 				Endpoint_ClearIN();
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -172,67 +168,67 @@ void EVENT_USB_UnhandledControlPacket(void)
  */
 void MassStorage_Task(void)
 {
-	/* Check if the USB System is connected to a Host */
-	if (USB_IsConnected)
+	/* Device must be connected and configured for the task to run */
+	if (USB_DeviceState != DEVICE_STATE_Configured)
+	  return;
+	  
+	/* Select the Data Out Endpoint */
+	Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
+	
+	/* Check to see if a command from the host has been issued */
+	if (Endpoint_IsReadWriteAllowed())
 	{
-		/* Select the Data Out Endpoint */
-		Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-		
-		/* Check to see if a command from the host has been issued */
-		if (Endpoint_IsReadWriteAllowed())
-		{
-			/* Indicate busy */
-			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+		/* Indicate busy */
+		LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 
-			/* Process sent command block from the host */
-			if (ReadInCommandBlock())
-			{
-				/* Check direction of command, select Data IN endpoint if data is from the device */
-				if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
-				  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
+		/* Process sent command block from the host */
+		if (ReadInCommandBlock())
+		{
+			/* Check direction of command, select Data IN endpoint if data is from the device */
+			if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
+			  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
 
-				/* Decode the received SCSI command */
-				SCSI_DecodeSCSICommand();
+			/* Decode the received SCSI command */
+			SCSI_DecodeSCSICommand();
 
-				/* Load in the CBW tag into the CSW to link them together */
-				CommandStatus.Tag = CommandBlock.Tag;
+			/* Load in the CBW tag into the CSW to link them together */
+			CommandStatus.Tag = CommandBlock.Tag;
 
-				/* Load in the data residue counter into the CSW */
-				CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
+			/* Load in the data residue counter into the CSW */
+			CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
 
-				/* Stall the selected data pipe if command failed (if data is still to be transferred) */
-				if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
-				  Endpoint_StallTransaction();
+			/* Stall the selected data pipe if command failed (if data is still to be transferred) */
+			if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
+			  Endpoint_StallTransaction();
 
-				/* Return command status block to the host */
-				ReturnCommandStatus();
-				
-				/* Check if a Mass Storage Reset occurred */
-				if (IsMassStoreReset)
-				{
-					/* Reset the data endpoint banks */
-					Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
-					Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
-					
-					Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-					Endpoint_ClearStall();
-					Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-					Endpoint_ClearStall();
-				}
-
-				/* Indicate ready */
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-			}
-			else
+			/* Return command status block to the host */
+			ReturnCommandStatus();
+			
+			/* Check if a Mass Storage Reset occurred */
+			if (IsMassStoreReset)
 			{
-				/* Indicate error reading in the command block from the host */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+				/* Reset the data endpoint banks */
+				Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
+				Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
+				
+				Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
+				Endpoint_ClearStall();
+				Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
+				Endpoint_ClearStall();
 			}
-		}
 
-		/* Clear the abort transfer flag */
-		IsMassStoreReset = false;
+			/* Indicate ready */
+			LEDs_SetAllLEDs(LEDMASK_USB_READY);
+		}
+		else
+		{
+			/* Indicate error reading in the command block from the host */
+			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		}
 	}
+
+	/* Clear the abort transfer flag */
+	IsMassStoreReset = false;
 }
 
 /** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block
diff --git a/Demos/Device/LowLevel/Mouse/Mouse.c b/Demos/Device/LowLevel/Mouse/Mouse.c
index febb36450c2a6b596d12843d32ec04359a1c7e36..d15f688d64f2259bf0039202a05638efd46fe29a 100644
--- a/Demos/Device/LowLevel/Mouse/Mouse.c
+++ b/Demos/Device/LowLevel/Mouse/Mouse.c
@@ -172,9 +172,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Send the flag to the host */
 				Endpoint_ClearIN();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -186,9 +184,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Set or clear the flag depending on what the host indicates that the current Protocol should be */
 				UsingReportProtocol = (USB_ControlRequest.wValue != 0);
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -200,9 +196,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Get idle period in MSB, must multiply by 4 to get the duration in milliseconds */
 				IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
 				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -217,9 +211,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 				/* Send the flag to the host */
 				Endpoint_ClearIN();
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -314,7 +306,7 @@ void SendNextReport(void)
 void Mouse_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 	  
 	/* Send the next mouse report to the host */
diff --git a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c
index 1c0e0304cc8cda0b412edf03d71858bde74d0416..ca38c24d601f7e1c06c12290c67c988ba0492ed8 100644
--- a/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c
+++ b/Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.c
@@ -285,7 +285,7 @@ void Ethernet_Task(void)
 	   Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */
 
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	/* Check if a frame has been written to the IN frame buffer */
diff --git a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c
index 9160dd10733b351f492eb8701a93ecfa0344ade9..af963b1fc5cb08866cb57dca2fe67a6fd9acbea3 100644
--- a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c
+++ b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c
@@ -192,9 +192,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 						 CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
 				*/
 
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -205,7 +203,7 @@ void EVENT_USB_UnhandledControlPacket(void)
 void CDC_Task(void)
 {
 	/* Device must be connected and configured for the task to run */
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 	  
 #if 0
@@ -264,7 +262,11 @@ void CDC_Task(void)
 	if (Tx_Buffer.Elements)
 	{
 		/* Wait until Serial Tx Endpoint Ready for Read/Write */
-		while (!(Endpoint_IsReadWriteAllowed()));
+		while (!(Endpoint_IsReadWriteAllowed()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 		
 		/* Write the bytes from the buffer to the endpoint while space is available */
 		while (Tx_Buffer.Elements && Endpoint_IsReadWriteAllowed())
@@ -284,8 +286,12 @@ void CDC_Task(void)
 		if (IsFull && !(Tx_Buffer.Elements))
 		{
 			/* Wait until Serial Tx Endpoint Ready for Read/Write */
-			while (!(Endpoint_IsReadWriteAllowed()));
-
+			while (!(Endpoint_IsReadWriteAllowed()))
+			{
+				if (USB_DeviceState == DEVICE_STATE_Unattached)
+				  return;
+			}
+				
 			/* Send an empty packet to terminate the transfer */
 			Endpoint_ClearIN();
 		}
@@ -298,11 +304,8 @@ void CDC_Task(void)
 ISR(USART1_RX_vect, ISR_BLOCK)
 {
 	/* Only store received characters if the USB interface is connected */
-	if (USB_IsConnected)
-	{
-		/* Character received, store it into the buffer */
-		Buffer_StoreElement(&Tx_Buffer, UDR1);
-	}
+	if (USB_DeviceState != DEVICE_STATE_Configured)
+	  Buffer_StoreElement(&Tx_Buffer, UDR1);
 }
 
 /** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c
index ddd159ef751d4cb2f1c4b6b72cb85f78208a629f..54291bf7528249030bc85ce8638063835933b6f1 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothHCICommands.c
@@ -114,7 +114,12 @@ void Bluetooth_ProcessHCICommands(void)
 
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+		
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 
@@ -133,7 +138,12 @@ void Bluetooth_ProcessHCICommands(void)
 
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 
@@ -155,7 +165,12 @@ void Bluetooth_ProcessHCICommands(void)
 			                                                                    EventMask[3], EventMask[2], EventMask[1], EventMask[0]);
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 		
@@ -176,7 +191,12 @@ void Bluetooth_ProcessHCICommands(void)
 			
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 			
@@ -195,7 +215,12 @@ void Bluetooth_ProcessHCICommands(void)
 
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 
@@ -215,7 +240,12 @@ void Bluetooth_ProcessHCICommands(void)
 
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{
+					if (USB_HostState == HOST_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 
@@ -366,7 +396,12 @@ void Bluetooth_ProcessHCICommands(void)
 		
 			do
 			{
-				while (!(Bluetooth_GetNextHCIEventHeader()));
+				while (!(Bluetooth_GetNextHCIEventHeader()))
+				{				
+					if (USB_DeviceState == DEVICE_STATE_Unattached)
+					  return;
+				}
+
 				Bluetooth_DiscardRemainingHCIEventParameters();
 			} while (HCIEventHeader.EventCode != EVENT_COMMAND_COMPLETE);
 
diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
index e2659102e4d84b9eb4a1fac3bc91c2b6e12b18d5..628fa217cb45427ab941201cb289af0838da1543 100644
--- a/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
+++ b/Demos/Host/Incomplete/BluetoothHost/Lib/BluetoothStack.c
@@ -41,7 +41,7 @@ Bluetooth_Device_t     Bluetooth_DeviceConfiguration ATTR_WEAK =
 
 void Bluetooth_Stack_Task(void)
 {
-	if (!(USB_IsConnected) || (USB_HostState != HOST_STATE_Ready))
+	if (USB_HostState != HOST_STATE_Configured)
 	  Bluetooth_HCIProcessingState = Bluetooth_Init;
 		
 	Bluetooth_ProcessHCICommands();
diff --git a/Demos/Host/LowLevel/CDCHost/CDCHost.c b/Demos/Host/LowLevel/CDCHost/CDCHost.c
index a3cde7826cd75095781f6c8282678bc31a45ac88..e20fa2cfcc86a2353441804fefbecff524745b29 100644
--- a/Demos/Host/LowLevel/CDCHost/CDCHost.c
+++ b/Demos/Host/LowLevel/CDCHost/CDCHost.c
@@ -164,15 +164,12 @@ void CDC_Host_Task(void)
 				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
 				break;
 			}
-				
+
+			puts_P(PSTR("CDC Device Enumerated.\r\n"));
+
 			USB_HostState = HOST_STATE_Configured;
 			break;
 		case HOST_STATE_Configured:
-			puts_P(PSTR("CDC Device Enumerated.\r\n"));
-				
-			USB_HostState = HOST_STATE_Ready;
-			break;
-		case HOST_STATE_Ready:
 			/* Select and the data IN pipe */
 			Pipe_SelectPipe(CDC_DATAPIPE_IN);
 			Pipe_Unfreeze();
diff --git a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
index 3a055c82097f636c6ce7d3b7d3816eabe4808694..d360643332fea8602a4969ed03f3d89a765e9ed0 100644
--- a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
+++ b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
@@ -266,14 +266,11 @@ void HID_Host_Task(void)
 				break;
 			}
 			
+			puts_P(PSTR("HID Device Enumerated.\r\n"));
+
 			USB_HostState = HOST_STATE_Configured;
 			break;
 		case HOST_STATE_Configured:
-			puts_P(PSTR("HID Device Enumerated.\r\n"));
-					
-			USB_HostState = HOST_STATE_Ready;
-			break;
-		case HOST_STATE_Ready:
 			ReadNextReport();
 
 			break;
diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
index c2d8dd4a6312a5eea2f4702840778ce13f5b1fa2..273cd717511883c1ebac5cda491d264523d1dec1 100644
--- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
@@ -230,9 +230,6 @@ void Keyboard_HID_Task(void)
 				break;
 			}
 				
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
 			/* HID class request to set the keyboard protocol to the Boot Protocol */
 			USB_ControlRequest = (USB_Request_Header_t)
 				{
@@ -262,9 +259,9 @@ void Keyboard_HID_Task(void)
 
 			puts_P(PSTR("Keyboard Enumerated.\r\n"));
 
-			USB_HostState = HOST_STATE_Ready;
+			USB_HostState = HOST_STATE_Configured;
 			break;
-		case HOST_STATE_Ready:
+		case HOST_STATE_Configured:
 			/* If a report has been received, read and process it */
 			ReadNextReport();
 
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
index dc1707bd0c8fa1bd3d1b59e989326e25d3b9e396..eee1755bf7eaf84c74abb21904b2e5ad70343e8c 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -166,9 +166,6 @@ void Keyboard_HID_Task(void)
 				break;
 			}
 				
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
 			puts_P(PSTR("Processing HID Report.\r\n"));
 
 			/* Get and process the device's first HID report descriptor */
@@ -187,9 +184,9 @@ void Keyboard_HID_Task(void)
 
 			puts_P(PSTR("Keyboard Enumerated.\r\n"));
 
-			USB_HostState = HOST_STATE_Ready;
+			USB_HostState = HOST_STATE_Configured;
 			break;
-		case HOST_STATE_Ready:
+		case HOST_STATE_Configured:
 			/* Select and unfreeze keyboard data pipe */
 			Pipe_SelectPipe(KEYBOARD_DATAPIPE);	
 			Pipe_Unfreeze();
diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c
index 7ee7de138287b82e5bc9e513f793b8d2a4d9351f..d0518df1f0d3a652f2cabe4176ff4fa394c48620 100644
--- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c
+++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c
@@ -154,7 +154,7 @@ static uint8_t MassStore_WaitForDataReceived(void)
 		}
 		  
 		/* Check to see if the device was disconnected, if so exit function */
-		if (!(USB_IsConnected))
+		if (USB_HostState == HOST_STATE_Unattached)
 		  return PIPE_RWSTREAM_DeviceDisconnected;
 	};
 	
@@ -206,7 +206,11 @@ static uint8_t MassStore_SendReceiveData(void* BufferPtr)
 		/* Acknowledge the packet */
 		Pipe_ClearOUT();
 		
-		while (!(Pipe_IsOUTReady()));
+		while (!(Pipe_IsOUTReady()))
+		{
+			if (USB_HostState == HOST_STATE_Unattached)
+			  return PIPE_RWSTREAM_DeviceDisconnected;
+		}
 	}
 	
 	/* Freeze used pipe after use */
diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
index 1adec5bcf45978c7d9edecf158dc2cf44271af6e..6cfe669f6bbadceaf3d8debda3e05bffa4819ed6 100644
--- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
+++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
@@ -171,14 +171,11 @@ void MassStorage_Task(void)
 				break;
 			}
 				
+			puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
+
 			USB_HostState = HOST_STATE_Configured;
 			break;
 		case HOST_STATE_Configured:
-			puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
-				
-			USB_HostState = HOST_STATE_Ready;
-			break;
-		case HOST_STATE_Ready:
 			/* Indicate device busy via the status LEDs */
 			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 			
@@ -241,7 +238,11 @@ void MassStorage_Task(void)
 			{
 				Serial_TxByte('.');
 				
-				if ((ErrorCode = MassStore_TestUnitReady(0)) != 0)
+				/* Abort if device removed */
+				if (USB_HostState == HOST_STATE_Unattached)
+				  break;
+
+				if ((ErrorCode = MassStore_TestUnitReady(0)) != PIPE_RWSTREAM_NoError)
 				{
 					ShowDiskReadError(PSTR("Test Unit Ready"), false, ErrorCode);
 
@@ -249,11 +250,7 @@ void MassStorage_Task(void)
 					break;
 				}
 			}
-			while ((SCSICommandStatus.Status != Command_Pass) && USB_IsConnected);
-			
-			/* Abort if device removed */
-			if (!(USB_IsConnected))
-			  break;
+			while (SCSICommandStatus.Status != Command_Pass);
 
 			puts_P(PSTR("\r\nRetrieving Capacity... "));
 
@@ -320,7 +317,7 @@ void MassStorage_Task(void)
 			while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
 			{
 				/* Abort if device removed */
-				if (!(USB_IsConnected))
+				if (USB_HostState == HOST_STATE_Unattached)
 				  break;
 			}
 			
@@ -346,7 +343,7 @@ void MassStorage_Task(void)
 				}
 
 				/* Abort if device removed */
-				if (!(USB_IsConnected))
+				if (USB_HostState == HOST_STATE_Unattached)
 				  break;
 			}
 			
diff --git a/Demos/Host/LowLevel/MouseHost/MouseHost.c b/Demos/Host/LowLevel/MouseHost/MouseHost.c
index 5340aa11fb585d8c2bc299ccfd78829db8ec8f80..b98f4bf968f43966b43d7899544a53d46b1444f0 100644
--- a/Demos/Host/LowLevel/MouseHost/MouseHost.c
+++ b/Demos/Host/LowLevel/MouseHost/MouseHost.c
@@ -226,9 +226,6 @@ void Mouse_HID_Task(void)
 				break;
 			}
 			
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
 			/* HID class request to set the mouse protocol to the Boot Protocol */
 			USB_ControlRequest = (USB_Request_Header_t)
 				{
@@ -257,10 +254,10 @@ void Mouse_HID_Task(void)
 			}
 
 			puts_P(PSTR("Mouse Enumerated.\r\n"));
-			
-			USB_HostState = HOST_STATE_Ready;
+
+			USB_HostState = HOST_STATE_Configured;
 			break;
-		case HOST_STATE_Ready:
+		case HOST_STATE_Configured:
 			/* If a report has been received, read and process it */
 			ReadNextReport();
 
diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
index 42865e515ea78f0c9b5876503d294893e6aeb68f..63fce0dcb6e35e7f746e1b61f248da5d62379a1a 100644
--- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
+++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
@@ -166,9 +166,6 @@ void Mouse_HID_Task(void)
 				break;
 			}
 			
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
 			puts_P(PSTR("Processing HID Report.\r\n"));
 
 			/* Get and process the device's first HID report descriptor */
@@ -186,10 +183,10 @@ void Mouse_HID_Task(void)
 			}
 
 			puts_P(PSTR("Mouse Enumerated.\r\n"));
-				
-			USB_HostState = HOST_STATE_Ready;
+
+			USB_HostState = HOST_STATE_Configured;
 			break;
-		case HOST_STATE_Ready:
+		case HOST_STATE_Configured:
 			/* Select and unfreeze mouse data pipe */
 			Pipe_SelectPipe(MOUSE_DATAPIPE);	
 			Pipe_Unfreeze();
diff --git a/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c b/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c
index 4c88bb4f266d8dd2d9b462e271fc0b9be6a7f749..cb051cdf11e6cadc67d6173f206edbb026f55d09 100644
--- a/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c
+++ b/Demos/Host/LowLevel/PrinterHost/Lib/PrinterCommands.c
@@ -54,7 +54,11 @@ uint8_t Printer_SendData(Printer_Data_t* PrinterCommands)
 	  return ErrorCode;
 
 	Pipe_ClearOUT();
-	while (!(Pipe_IsOUTReady()));
+	while (!(Pipe_IsOUTReady()))
+	{
+		if (USB_HostState == HOST_STATE_Unattached)
+		  return PIPE_RWSTREAM_DeviceDisconnected;
+	}
 	
 	Pipe_Freeze();
 
diff --git a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
index 3b145a63dac0185fdffa4ab9452550534fe5d488..bbda0c24b5d4d3ab1bbd464b1f23310ab8a59eb2 100644
--- a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
+++ b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
@@ -195,9 +195,6 @@ void USB_Printer_Host(void)
 				}
 			}
 			
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
 			puts_P(PSTR("Retrieving Device ID...\r\n"));
 		
 			char DeviceIDString[256];
@@ -217,10 +214,10 @@ void USB_Printer_Host(void)
 			printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
 
 			puts_P(PSTR("Printer Enumerated.\r\n"));
-					
-			USB_HostState = HOST_STATE_Ready;
+
+			USB_HostState = HOST_STATE_Configured;
 			break;
-		case HOST_STATE_Ready:
+		case HOST_STATE_Configured:
 			/* Indicate device busy via the status LEDs */
 			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 		
diff --git a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
index e0d71a059118598a02235400c2018c552236a2a1..970df4f879a0eff425c303cebb5aa89b5889d48f 100644
--- a/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
+++ b/Demos/Host/LowLevel/StillImageHost/Lib/StillImageCommands.c
@@ -152,12 +152,9 @@ uint8_t SImage_RecieveBlockHeader(void)
 		}
 		  
 		/* Check to see if the device was disconnected, if so exit function */
-		if (!(USB_IsConnected))
-		{
-			/* Return error code */
-			return PIPE_RWSTREAM_DeviceDisconnected;
-		}
-	};
+		if (USB_HostState == HOST_STATE_Unattached)
+		  return PIPE_RWSTREAM_DeviceDisconnected;
+	}
 	
 	/* Freeze OUT pipe after use */
 	Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);
diff --git a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
index 5cfaf46bed80e17b9bed9068a6eee89685b3b1f2..ca0771a94bee197fd5df35ede92000f7916cd38e 100644
--- a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
+++ b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
@@ -166,14 +166,11 @@ void StillImage_Task(void)
 				break;
 			}
 				
+			puts_P(PSTR("Still Image Device Enumerated.\r\n"));
+
 			USB_HostState = HOST_STATE_Configured;
 			break;
 		case HOST_STATE_Configured:
-			puts_P(PSTR("Still Image Device Enumerated.\r\n"));
-				
-			USB_HostState = HOST_STATE_Ready;
-			break;
-		case HOST_STATE_Ready:
 			/* Indicate device busy via the status LEDs */
 			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 			
@@ -331,9 +328,7 @@ void StillImage_Task(void)
 			/* Indicate device no longer busy */
 			LEDs_SetAllLEDs(LEDMASK_USB_READY);
 			
-			/* Wait until USB device disconnected */
-			while (USB_IsConnected);
-			
+			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
 			break;
 	}
 }
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
index d117bedf6835ad217b0f02369376eb5b3db456c5..116921e6ef690923e25e5a90025731f466ff3256 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.c
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -50,8 +50,7 @@ void Audio_Device_ProcessControlPacket(USB_ClassInfo_Audio_Device_t* const Audio
 				
 				AudioInterfaceInfo->State.InterfaceEnabled = (USB_ControlRequest.wValue != 0);
 				  
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
index 12b55938c427034a158a209f1e97b7a167e8a1e0..237e1dd2fa947d1c2a186b03ac4379797915efd6 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.c
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -78,8 +78,7 @@ void CDC_Device_ProcessControlPacket(USB_ClassInfo_CDC_Device_t* CDCInterfaceInf
 				
 				EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
 
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 	
 			break;
@@ -114,7 +113,7 @@ bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 
 void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 {
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
@@ -125,7 +124,12 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 	if (!(Endpoint_IsReadWriteAllowed()))
 	{
 		Endpoint_ClearIN();
-		while (!(Endpoint_IsReadWriteAllowed()));
+
+		while (!(Endpoint_IsReadWriteAllowed()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
 	}	
 	
 	Endpoint_ClearIN();
@@ -133,7 +137,7 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 
 void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, char* const Data, const uint16_t Length)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
@@ -142,7 +146,7 @@ void CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, c
 
 void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);
@@ -150,7 +154,12 @@ void CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, con
 	if (!(Endpoint_IsReadWriteAllowed()))
 	{
 		Endpoint_ClearIN();
-		while (!(Endpoint_IsReadWriteAllowed()));
+		
+		while (!(Endpoint_IsReadWriteAllowed()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;		
+		}
 	}
 
 	Endpoint_Write_Byte(Data);	
@@ -165,7 +174,7 @@ uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterface
 
 uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return 0;
 
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
@@ -180,7 +189,7 @@ uint8_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* CDCInterfaceInfo)
 
 void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpointNumber);
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
index 4a6295ab0c4f3205e9b31a731ec6e57a548650fb..f292c633e7c011e9c60dd7b210d38dbd62bae0f9 100644
--- a/LUFA/Drivers/USB/Class/Device/HID.c
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -88,8 +88,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
 				Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
 				Endpoint_ClearIN();
 
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -100,8 +99,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
 
 				HIDInterfaceInfo->State.UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
 				
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -115,8 +113,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
 					
 					HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
 					
-					while (!(Endpoint_IsINReady()));
-					Endpoint_ClearIN();
+					Endpoint_ClearStatusStage();
 				}
 			}
 			
@@ -129,8 +126,7 @@ void HID_Device_ProcessControlPacket(USB_ClassInfo_HID_Device_t* const HIDInterf
 				Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
 				Endpoint_ClearIN();
 
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -152,7 +148,7 @@ bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfac
 		
 void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo)
 {
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpointNumber);
diff --git a/LUFA/Drivers/USB/Class/Device/MIDI.c b/LUFA/Drivers/USB/Class/Device/MIDI.c
index da33bdb610582022dcc47d96c0cf655725b8bf1c..364327595540efa6fdf645d6f4f91cd884046e8f 100644
--- a/LUFA/Drivers/USB/Class/Device/MIDI.c
+++ b/LUFA/Drivers/USB/Class/Device/MIDI.c
@@ -70,7 +70,7 @@ void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
 
 void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 	
 	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
@@ -84,7 +84,7 @@ void MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfac
 
 bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
 {
-	if (!(USB_IsConnected))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return false;
 	
 	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpointNumber);
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
index f7f3fd9f232d121d41569f572d2b24e280716afb..9f8688c1dff77a22c783a1231ac517dbe592153f 100644
--- a/LUFA/Drivers/USB/Class/Device/MassStorage.c
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -53,8 +53,7 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* const MSInterface
 
 				MSInterfaceInfo->State.IsMassStoreReset = true;			
 
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
+				Endpoint_ClearStatusStage();
 			}
 
 			break;
@@ -63,12 +62,10 @@ void MS_Device_ProcessControlPacket(USB_ClassInfo_MS_Device_t* const MSInterface
 			{
 				Endpoint_ClearSETUP();
 
-				Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
-				
+				Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);				
 				Endpoint_ClearIN();
 				
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
+				Endpoint_ClearStatusStage();
 			}
 			
 			break;
@@ -96,7 +93,7 @@ bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceIn
 
 void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
 {
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c
index 0d35ee6b400464bcebe423cd3a9a19757f240d81..37771c646fe5051a25fe8439e20fe7253be52f37 100644
--- a/LUFA/Drivers/USB/Class/Device/RNDIS.c
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c
@@ -138,7 +138,7 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISIn
 
 void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)
 {
-	if (!(USB_IsConnected) || !(USB_ConfigurationNumber))
+	if (USB_DeviceState != DEVICE_STATE_Configured)
 	  return;
 
 	RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h
index 2df0dda08d43fbf4f691bfc346959f667906c80c..4042d46703ee2f8e2a5127c06f87aa9a9f40b41d 100644
--- a/LUFA/Drivers/USB/HighLevel/Events.h
+++ b/LUFA/Drivers/USB/HighLevel/Events.h
@@ -98,7 +98,7 @@
 			 *        which is not always accurate (host may suspend the bus while still connected). If the actual connection state
 			 *        needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
 			 *        passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
-			 *        and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually.
+			 *        and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually.
 			 *
 			 *  \see USBTask.h for more information on the USB management task and reducing CPU usage.
 			 */
@@ -116,7 +116,7 @@
 			 *        which is not always accurate (host may suspend the bus while still connected). If the actual connection state
 			 *        needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
 			 *        passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
-			 *        and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually.
+			 *        and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually.
 			 *
 			 *  \see USBTask.h for more information on the USB management task and reducing CPU usage.
 			 */
diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
index c240bef6ea3efba78bea2177f9fa16e68d3eb120..5edefa9967d5b30d32bb0d50991c66bcc110c18f 100644
--- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
+++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
@@ -78,19 +78,17 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 		{
 			EVENT_USB_VBUSConnect();
 			
-			if (USB_IsConnected)
+			if (USB_DeviceState != DEVICE_STATE_Unattached)
 			  EVENT_USB_Disconnect();
 				
 			USB_ResetInterface();
-				
-			USB_IsConnected = true;
 
+			USB_DeviceState = DEVICE_STATE_Powered;
 			EVENT_USB_Connect();
 		}
 		else
 		{
-			USB_IsConnected = false;
-
+			USB_DeviceState = DEVICE_STATE_Unattached;
 			EVENT_USB_Disconnect();
 		
 			USB_Detach();
@@ -117,16 +115,12 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 		if (!(USB_Options & USB_OPT_MANUAL_PLL))
 		  USB_PLL_Off();
 
-		USB_IsSuspended = true;
-
-		EVENT_USB_Suspend();
-
 		#if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT)
-		if (USB_IsConnected)
-		{
-			USB_IsConnected = false;
-			EVENT_USB_Disconnect();
-		}
+		USB_DeviceState = DEVICE_STATE_Unattached;
+		EVENT_USB_Disconnect();
+		#else
+		USB_DeviceState = DEVICE_STATE_Suspended;
+		EVENT_USB_Suspend();
 		#endif
 	}
 
@@ -146,22 +140,19 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 		USB_INT_Enable(USB_INT_SUSPEND);
 		
 		#if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT)
-		if (!(USB_IsConnected))
-		{
-			USB_IsConnected = true;
-			EVENT_USB_Connect();
-		}
+		USB_DeviceState = DEVICE_STATE_Powered;
+		EVENT_USB_Connect();
+		#else
+		USB_DeviceState = DEVICE_STATE_Configured;
+		EVENT_USB_WakeUp();		
 		#endif
-
-		USB_IsSuspended = false;
-
-		EVENT_USB_WakeUp();
 	}
    
 	if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI))
 	{
 		USB_INT_Clear(USB_INT_EORSTI);
 
+		USB_DeviceState         = DEVICE_STATE_Default;
 		USB_ConfigurationNumber = 0;
 
 		USB_INT_Clear(USB_INT_SUSPEND);
@@ -217,7 +208,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 
 		USB_INT_Enable(USB_INT_DDISCI);
 		
-		USB_HostState = HOST_STATE_Attached;
+		USB_HostState = HOST_STATE_Powered;
 	}
 
 	if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI))
@@ -227,7 +218,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 		EVENT_USB_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0);
 		EVENT_USB_DeviceUnattached();
 		
-		if (USB_IsConnected)
+		if (USB_HostState != HOST_STATE_Unattached)
 		  EVENT_USB_Disconnect();
 
 		USB_ResetInterface();
@@ -239,13 +230,16 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 	{		
 		USB_INT_Clear(USB_INT_IDTI);
 
-		if (USB_IsConnected)
-		{
-			if (USB_CurrentMode == USB_MODE_HOST)
-			  EVENT_USB_DeviceUnattached();
+		if (USB_DeviceState != DEVICE_STATE_Unattached)
+		  EVENT_USB_Disconnect();
 
+		if (USB_HostState != HOST_STATE_Unattached)
+		{
 			EVENT_USB_Disconnect();
+			EVENT_USB_DeviceUnattached();
 		}
+	
+		EVENT_USB_Disconnect();
 
 		EVENT_USB_UIDChange();
 		
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c
index 894171f246561f8b24bc0fa70914f18922f45e7d..500a697bcf6457868b0c07157cc0fa10992b82a6 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.c
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.c
@@ -33,8 +33,6 @@
 #define  INCLUDE_FROM_USBTASK_C
 #include "USBTask.h"
 
-volatile bool        USB_IsSuspended;
-volatile bool        USB_IsConnected;
 volatile bool        USB_IsInitialized;
 USB_Request_Header_t USB_ControlRequest;
 
@@ -42,6 +40,10 @@ USB_Request_Header_t USB_ControlRequest;
 volatile uint8_t     USB_HostState;
 #endif
 
+#if defined(USB_CAN_BE_DEVICE)
+volatile uint8_t     USB_DeviceState;
+#endif
+
 void USB_USBTask(void)
 {
 	#if defined(USB_HOST_ONLY)
@@ -59,7 +61,7 @@ void USB_USBTask(void)
 #if defined(USB_CAN_BE_DEVICE)
 static void USB_DeviceTask(void)
 {
-	if (USB_IsConnected)
+	if (USB_DeviceState != DEVICE_STATE_Unattached)
 	{
 		uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
 	
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h
index 2a9bf195350b7f6ac562293c525ce2cb35235331..12acb11951a9fc8182db39829f186c9636f0d106 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.h
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.h
@@ -55,23 +55,6 @@
 
 	/* Public Interface - May be used in end-application: */
 		/* Global Variables: */
-			/** Indicates if the USB interface is currently connected to a host if in device mode, or to a
-			 *  device while running in host mode.
-			 *
-			 *  \note This variable should be treated as read-only in the user application, and never manually
-			 *        changed in value.
-			 *
-			 *  \note For the smaller USB AVRs (AT90USBXX2) with limited USB controllers, VBUS is not available to the USB controller.
-			 *        this means that the current connection state is derived from the bus suspension and wake up events by default,
-			 *        which is not always accurate (host may suspend the bus while still connected). If the actual connection state
-			 *        needs to be determined, VBUS should be routed to an external pin, and the auto-detect behaviour turned off by
-			 *        passing the NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection
-			 *        and disconnection events may be manually fired, and the \ref USB_IsConnected global changed manually.
-			 *
-			 *  \ingroup Group_USBManagement
-			 */
-			extern volatile bool USB_IsConnected;
-
 			/** Indicates if the USB interface is currently initialized but not necessarily connected to a host
 			 *  or device (i.e. if \ref USB_Init() has been run). If this is false, all other library globals are invalid.
 			 *
@@ -90,39 +73,43 @@
 			 */
 			 extern USB_Request_Header_t USB_ControlRequest;
 			
-			#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
-			/** Indicates if the USB interface is currently suspended by the host when in device mode. When suspended,
-			 *  the device should consume minimal power, and cannot communicate to the host. If Remote Wakeup is
-			 *  supported by the device and \ref USB_RemoteWakeupEnabled is true, suspension can be terminated by the device
-			 *  by issuing a Remote Wakeup request.
-			 *
-			 *  \note This global is only present if the user application can be a USB device.
-			 *
-			 *  \note This variable should be treated as read-only in the user application, and never manually
-			 *        changed in value.
-			 *
-			 *  \ingroup Group_Device
-			 */
-			extern volatile bool USB_IsSuspended;
-			#endif
-
 			#if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)
 			/** Indicates the current host state machine state. When in host mode, this indicates the state
-			 *  via one of the values of the \ref USB_Host_States_t enum values in Host.h.
+			 *  via one of the values of the \ref USB_Host_States_t enum values.
 			 *
 			 *  This value may be altered by the user application to implement the \ref HOST_STATE_Addressed,
-			 *  \ref HOST_STATE_Configured, \ref HOST_STATE_Ready and \ref HOST_STATE_Suspended states which
-			 *  are not implemented by the library.
+			 *  \ref HOST_STATE_Configured and \ref HOST_STATE_Suspended states which are not implemented by
+			 *  the library.
 			 *
 			 *  \note This global is only present if the user application can be a USB host.
 			 *
-			 *  \see \ref USB_Host_States_t for a list of possible host states
+			 *  \see \ref USB_Host_States_t for a list of possible device states
 			 *
 			 *  \ingroup Group_Host
 			 */
 			extern volatile uint8_t USB_HostState;
 			#endif
 
+			#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
+			/** Indicates the current device state machine state. When in device mode, this indicates the state
+			 *  via one of the values of the \ref USB_Device_States_t enum values.
+			 *
+			 *  This value should not be altered by the user application as it is handled automatically by the
+			 *  library. The only exception to this rule is if the NO_LIMITED_CONTROLLER_CONNECT token is used
+			 *  (see \ref EVENT_USB_Connect() and \ref EVENT_USB_Disconnect() events).
+			 *
+			 *  \note This global is only present if the user application can be a USB device.
+			 *
+			 *  \note This variable should be treated as read-only in the user application, and never manually
+			 *        changed in value except in the circumstances outlined above.
+			 *
+			 *  \see \ref USB_Device_States_t for a list of possible device states
+			 *
+			 *  \ingroup Group_Device
+			 */
+			extern volatile uint8_t USB_DeviceState;
+			#endif
+
 		/* Function Prototypes: */
 			/** This is the main USB management task. The USB driver requires that this task be executed
 			 *  continuously when the USB system is active (device attached in host mode, or attached to a host
diff --git a/LUFA/Drivers/USB/LowLevel/DevChapter9.c b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
index 10dce7298df4e447cb8cd236d74ddb718e73b4b6..8de4bd6a82752c83da726ef8da2f33907c57d909 100644
--- a/LUFA/Drivers/USB/LowLevel/DevChapter9.c
+++ b/LUFA/Drivers/USB/LowLevel/DevChapter9.c
@@ -117,13 +117,22 @@ void USB_Device_ProcessControlPacket(void)
 
 static void USB_Device_SetAddress(void)
 {
+	uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F);
+
 	Endpoint_ClearSETUP();
 	
 	Endpoint_ClearIN();
 	
-	while (!(Endpoint_IsINReady()));
+	while (!(Endpoint_IsINReady()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;
+	}
+
+	UDADDR = ((1 << ADDEN) | DeviceAddress);
 
-	UDADDR = ((1 << ADDEN) | ((uint8_t)USB_ControlRequest.wValue & 0x7F));
+	if (DeviceAddress)
+	  USB_DeviceState = DEVICE_STATE_Addressed;
 
 	return;
 }
@@ -185,8 +194,17 @@ static void USB_Device_SetConfiguration(void)
 
 	Endpoint_ClearIN();
 
-	if (!(AlreadyConfigured) && USB_ConfigurationNumber)
-	  EVENT_USB_DeviceEnumerationComplete();
+	if (USB_ConfigurationNumber)
+	{
+		USB_DeviceState = DEVICE_STATE_Configured;
+
+		if (!(AlreadyConfigured))
+		  EVENT_USB_DeviceEnumerationComplete();
+	}
+	else
+	{
+		USB_DeviceState = DEVICE_STATE_Addressed;
+	}
 
 	EVENT_USB_ConfigurationChanged();
 }
@@ -199,7 +217,12 @@ void USB_Device_GetConfiguration(void)
 	
 	Endpoint_ClearIN();
 
-	while (!(Endpoint_IsOUTReceived()));
+	while (!(Endpoint_IsOUTReceived()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;	
+	}
+
 	Endpoint_ClearOUT();
 }
 
@@ -332,7 +355,12 @@ static void USB_Device_GetStatus(void)
 
 	Endpoint_ClearIN();
 	
-	while (!(Endpoint_IsOUTReceived()));
+	while (!(Endpoint_IsOUTReceived()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return;	
+	}
+	
 	Endpoint_ClearOUT();
 }
 
diff --git a/LUFA/Drivers/USB/LowLevel/Device.h b/LUFA/Drivers/USB/LowLevel/Device.h
index 975d09a79e38cf7602e464edd5a5048a184169d3..e162a5980115b269d34330aa047db7004280d791 100644
--- a/LUFA/Drivers/USB/LowLevel/Device.h
+++ b/LUFA/Drivers/USB/LowLevel/Device.h
@@ -118,7 +118,36 @@
 
 				#define USB_Device_IsUSBSuspended()           ((UDINT &  (1 << SUSPI)) ? true : false)
 			#endif
-
+			
+		/* Type Defines: */
+			enum USB_Device_States_t
+			{
+				DEVICE_STATE_Unattached                   = 0, /**< Internally implemented by the library. This state indicates
+				                                                *   that the device is not currently connected to a host.
+				                                                */
+				DEVICE_STATE_Powered                      = 1, /**< Internally implemented by the library. This state indicates
+				                                                *   that the device is connected to a host, but enumeration has not
+				                                                *   yet begun.
+				                                                */
+				DEVICE_STATE_Default                      = 2, /**< Internally implemented by the library. This state indicates
+				                                                *   that the device's USB bus has been reset by the host and it is
+				                                                *   now waiting for the host to begin the enumeration process.
+				                                                */
+				DEVICE_STATE_Addressed                    = 3, /**< Internally implemented by the library. This state indicates
+				                                                *   that the device has been addressed by the USB Host, but is not
+				                                                *   yet configured.
+				                                                */
+				DEVICE_STATE_Configured                   = 4, /**< May be implemented by the user project. This state indicates
+				                                                *   that the device has been enumerated by the host and is ready
+				                                                *   for USB communications to begin.
+				                                                */
+				DEVICE_STATE_Suspended                    = 5, /**< May be implemented by the user project. This state indicates
+				                                                *   that the USB bus has been suspended by the host, and the device
+				                                                *   should power down to a minimal power level until the bus is
+				                                                *   resumed.
+				                                                */
+			};
+			
 		/* Function Prototypes: */
 			/** Function to retrieve a given descriptor's size and memory location from the given descriptor type value,
 			 *  index and language ID. This function MUST be overridden in the user application (added with full, identical  
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index f9db9cd224a2a923d21b8349a0a8a024ca2ed7c7..e4d01404ddc2696e345855e0ef0e7b6f4aede3d2 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -71,6 +71,30 @@ void Endpoint_ClearEndpoints(void)
 	}
 }
 
+void Endpoint_ClearStatusStage(void)
+{
+	if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST)
+	{
+		while (!(Endpoint_IsOUTReceived()))
+		{				
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
+
+		Endpoint_ClearOUT();
+	}
+	else
+	{
+		while (!(Endpoint_IsINReady()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return;
+		}
+		
+		Endpoint_ClearIN();
+	}
+}
+
 #if !defined(CONTROL_ONLY_DEVICE)
 uint8_t Endpoint_WaitUntilReady(void)
 {
@@ -93,7 +117,7 @@ uint8_t Endpoint_WaitUntilReady(void)
 			  return ENDPOINT_READYWAIT_NoError;		
 		}
 		
-		if (!(USB_IsConnected))
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
 		  return ENDPOINT_READYWAIT_DeviceDisconnected;
 		else if (Endpoint_IsStalled())
 		  return ENDPOINT_READYWAIT_EndpointStalled;
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.h b/LUFA/Drivers/USB/LowLevel/Endpoint.h
index 2caea8343ac54b96f33c69507f431765cc8ff11c..a9ec122a27236b5ebb954cfaa5515b462c45190d 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.h
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.h
@@ -431,14 +431,14 @@
 				ENDPOINT_RWSTREAM_EndpointStalled    = 1, /**< The endpoint was stalled during the stream
 				                                           *   transfer by the host or device.
 				                                           */
-				ENDPOINT_RWSTREAM_DeviceDisconnected = 1, /**< Device was disconnected from the host during
+				ENDPOINT_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
 				                                           *   the transfer.
 				                                           */
-				ENDPOINT_RWSTREAM_Timeout            = 2, /**< The host failed to accept or send the next packet
+				ENDPOINT_RWSTREAM_Timeout            = 3, /**< The host failed to accept or send the next packet
 				                                           *   within the software timeout period set by the
 				                                           *   \ref USB_STREAM_TIMEOUT_MS macro.
 				                                           */
-				ENDPOINT_RWSTREAM_CallbackAborted    = 3, /**< Indicates that the stream's callback function
+				ENDPOINT_RWSTREAM_CallbackAborted    = 4, /**< Indicates that the stream's callback function
 			                                               *   aborted the transfer early.
 				                                           */
 			};
@@ -451,6 +451,9 @@
 			{
 				ENDPOINT_RWCSTREAM_NoError            = 0, /**< Command completed successfully, no error. */
 				ENDPOINT_RWCSTREAM_HostAborted        = 1, /**< The aborted the transfer prematurely. */
+				ENDPOINT_RWCSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during
+				                                            *   the transfer.
+				                                            */
 			};
 
 		/* Inline Functions: */
@@ -726,6 +729,12 @@
 			 *  \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum.
 			 */
 			uint8_t Endpoint_WaitUntilReady(void);
+			
+			/** Completes the status stage of a control transfer on a CONTROL type endpoint automatically,
+			 *  with respect to the data direction. This is a convenience function which can be used to
+			 *  simplify user control request handling.
+			 */
+			void Endpoint_ClearStatusStage(void);
 
 			/** Reads and discards the given number of bytes from the endpoint from the given buffer,
 			 *  discarding fully read packets from the host as needed. The last packet is not automatically
@@ -922,6 +931,9 @@
 			 *  in both failure and success states; the user is responsible for manually clearing the setup OUT to
 			 *  finalize the transfer via the \ref Endpoint_ClearOUT() macro.
 			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
+			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
 			 *  \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
@@ -937,6 +949,9 @@
 			uint8_t Endpoint_Write_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
@@ -953,6 +968,9 @@
 			uint8_t Endpoint_Write_Control_EStream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
 			 *
@@ -975,6 +993,9 @@
 			 *  in both failure and success states; the user is responsible for manually clearing the setup OUT to
 			 *  finalize the transfer via the \ref Endpoint_ClearOUT() macro.
 			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
+			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
 			 *  \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
@@ -990,6 +1011,9 @@
 			uint8_t Endpoint_Write_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
@@ -1006,6 +1030,9 @@
 			uint8_t Endpoint_Write_Control_EStream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note The FLASH data must be located in the first 64KB of FLASH for this function to work correctly.
 			 *
@@ -1028,6 +1055,9 @@
 			 *  automatically sent after success or failure states; the user is responsible for manually sending the
 			 *  setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro.
 			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
+			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
 			 *  \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
@@ -1043,6 +1073,9 @@
 			uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
 
 			/** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
@@ -1063,6 +1096,9 @@
 			 *  automatically sent after success or failure states; the user is responsible for manually sending the
 			 *  setup IN to finalize the transfer via the \ref Endpoint_ClearIN() macro.
 			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
+			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
 			 *  \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained
@@ -1078,6 +1114,9 @@
 			uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);		
 			
 			/** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE.
+			 *
+			 *  \note This function automatically clears the control transfer's status stage. Do not manually attempt
+			 *        to clear the status stage when using this routine in a control transaction.
 			 *
 			 *  \note This routine should only be used on CONTROL type endpoints.
 			 *
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index efe4baeeb227346c7b01ce5a9766ea22e365793e..ae7525bee7838ce8ff02ab563727ba2c8914917c 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -60,12 +60,12 @@ void USB_Host_ProcessNextHostState(void)
 			}
 		
 			break;
-		case HOST_STATE_Attached:
+		case HOST_STATE_Powered:
 			WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS;
 		
-			USB_HostState = HOST_STATE_Attached_WaitForDeviceSettle;
+			USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle;
 			break;
-		case HOST_STATE_Attached_WaitForDeviceSettle:
+		case HOST_STATE_Powered_WaitForDeviceSettle:
 			#if HOST_DEVICE_SETTLE_DELAY_MS > 0
 			_delay_ms(1);
 
@@ -77,14 +77,14 @@ void USB_Host_ProcessNextHostState(void)
 				USB_Host_VBUS_Auto_Enable();
 				USB_Host_VBUS_Auto_On();
 				
-				USB_HostState = HOST_STATE_Attached_WaitForConnect;
+				USB_HostState = HOST_STATE_Powered_WaitForConnect;
 			}
 			#else
-			USB_HostState = HOST_STATE_Attached_WaitForConnect;			
+			USB_HostState = HOST_STATE_Powered_WaitForConnect;			
 			#endif
 			
 			break;
-		case HOST_STATE_Attached_WaitForConnect:		
+		case HOST_STATE_Powered_WaitForConnect:		
 			if (USB_INT_HasOccurred(USB_INT_DCONNI))
 			{	
 				USB_INT_Clear(USB_INT_DCONNI);
@@ -93,22 +93,21 @@ void USB_Host_ProcessNextHostState(void)
 				USB_INT_Clear(USB_INT_VBERRI);
 				USB_INT_Enable(USB_INT_VBERRI);
 
-				USB_IsConnected = true;
 				EVENT_USB_Connect();
 					
 				USB_Host_ResumeBus();
 				Pipe_ClearPipes();
 				
-				HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Attached_DoReset);
+				HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset);
 			}
 
 			break;
-		case HOST_STATE_Attached_DoReset:
+		case HOST_STATE_Powered_DoReset:
 			USB_Host_ResetDevice();
 
-			HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered);
+			HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe);
 			break;
-		case HOST_STATE_Powered:
+		case HOST_STATE_Powered_ConfigPipe:
 			Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
 							   PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
 							   PIPE_CONTROLPIPE_DEFAULT_SIZE, PIPE_BANK_SINGLE);		
@@ -199,9 +198,7 @@ void USB_Host_ProcessNextHostState(void)
 		USB_Host_VBUS_Auto_Off();
 
 		EVENT_USB_DeviceUnattached();
-		
-		if (USB_IsConnected)
-		  EVENT_USB_Disconnect();
+		EVENT_USB_Disconnect();
 
 		USB_ResetInterface();
 	}
@@ -222,7 +219,7 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
 			MS--;
 		}
 					
-		if ((USB_IsConnected == false) || (USB_CurrentMode == USB_MODE_DEVICE))
+		if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode == USB_MODE_DEVICE))
 		{
 			ErrorCode = HOST_WAITERROR_DeviceDisconnect;
 			
diff --git a/LUFA/Drivers/USB/LowLevel/Host.h b/LUFA/Drivers/USB/LowLevel/Host.h
index 88634fdae09ae6c548e8c1819ee879a640daf6a7..a602cee77100b50c92cd5b8b4a04312615903f97 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.h
+++ b/LUFA/Drivers/USB/LowLevel/Host.h
@@ -241,32 +241,32 @@
 				                                               *   
 				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Attached                     = 3,  /**< Internally implemented by the library. This state indicates
+				HOST_STATE_Powered                      = 3,  /**< Internally implemented by the library. This state indicates
 				                                               *   that a device has been attached, and the library's internals
 				                                               *   are being configured to begin the enumeration process.
 				                                               *   
 				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Attached_WaitForDeviceSettle = 4,  /**< Internally implemented by the library. This state indicates
+				HOST_STATE_Powered_WaitForDeviceSettle = 4,   /**< Internally implemented by the library. This state indicates
 				                                               *   that the stack is waiting for the initial settling period to
 				                                               *   elapse before beginning the enumeration process.
 				                                               *   
 				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Attached_WaitForConnect      = 5,  /**< Internally implemented by the library. This state indicates
+				HOST_STATE_Powered_WaitForConnect      = 5,   /**< Internally implemented by the library. This state indicates
 				                                               *   that the stack is waiting for a connection event from the USB
 				                                               *   controller to indicate a valid USB device has been attached to
 				                                               *   the bus and is ready to be enumerated.
 				                                               *   
 				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Attached_DoReset             = 6,  /**< Internally implemented by the library. This state indicates
+				HOST_STATE_Powered_DoReset             = 6,   /**< Internally implemented by the library. This state indicates
 				                                               *   that a valid USB device has been attached, and that it is
 				                                               *   will now be reset to ensure it is ready for enumeration.
 				                                               *   
 				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Powered                      = 7,  /**< Internally implemented by the library. This state indicates
+				HOST_STATE_Powered_ConfigPipe           = 7,  /**< Internally implemented by the library. This state indicates
 				                                               *   that the attached device is currently powered and reset, and
 				                                               *   that the control pipe is now being configured by the stack.
 				                                               *   
@@ -301,20 +301,12 @@
 				                                               *   retrieval and processing of the device descriptor) should also
 				                                               *   be placed in this state.
 				                                               */
-				HOST_STATE_Configured                   = 12, /**< May be implemented by the user project. This state should
-				                                               *   implement any extra device configuration (such as the setting of
-				                                               *   class-specific parameters) before normal communication is begun
-				                                               *   in the HOST_STATE_Ready state.
-				                                               */
-				HOST_STATE_Ready                        = 13, /**< May be implemented by the user project. This state should
-				                                               *   contain the main communications with the attached device. From this
-				                                               *   this state the host state machine should be changed to either
-				                                               *   HOST_STATE_Suspended (after the bus is manually suspended using the
-				                                               *   USB_Host_SuspendBus() macro) or HOST_STATE_WaitForDeviceRemoval as
-				                                               *   needed.
+				HOST_STATE_Configured                   = 12, /**< May be implemented by the user project. This state should implement the
+				                                               *   actual work performed on the attached device and changed to the
+				                                               *   HOST_STATE_Suspended or HOST_STATE_WaitForDeviceRemoval states as needed.
 				                                               */
 				HOST_STATE_Suspended                    = 15, /**< May be implemented by the user project. This state should be maintained
-				                                               *   while the bus is suspended, and changed to either the HOST_STATE_Ready
+				                                               *   while the bus is suspended, and changed to either the HOST_STATE_Configured
 				                                               *   (after resuming the bus with the USB_Host_ResumeBus() macro) or the
 				                                               *   HOST_STATE_WaitForDeviceRemoval states as needed.
 				                                               */
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.c b/LUFA/Drivers/USB/LowLevel/LowLevel.c
index 4fcf4fcabe83b2cf717ed6099231628db249ce02..cd7fa891d0cef7e2690278499fd76d6ad0f03a9a 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.c
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.c
@@ -110,15 +110,21 @@ void USB_Init(
 
 void USB_ShutDown(void)
 {
-	if (USB_IsConnected)
+	#if defined(USB_CAN_BE_DEVICE)
+	if (USB_DeviceState != DEVICE_STATE_Unattached)
+	  EVENT_USB_Disconnect();
+	#endif
+	
+	#if defined(USB_CAN_BE_HOST)
+	if (USB_HostState != HOST_STATE_Unattached)
 	  EVENT_USB_Disconnect();
+	#endif
 
 	USB_Detach();
 
 	USB_INT_DisableAllInterrupts();
 	USB_INT_ClearAllInterrupts();
 
-	USB_IsConnected   = false;
 	USB_IsInitialized = false;
 
 	#if defined(USB_CAN_BE_HOST)
@@ -126,7 +132,10 @@ void USB_ShutDown(void)
 	#endif
 
 	#if defined(USB_CAN_BE_DEVICE)
-	USB_ConfigurationNumber = 0;
+	USB_DeviceState = DEVICE_STATE_Unattached;
+	USB_ConfigurationNumber  = 0;
+	USB_RemoteWakeupEnabled  = false;
+	USB_CurrentlySelfPowered = false;
 	#endif
 
 	#if defined(CAN_BE_BOTH)
@@ -149,16 +158,14 @@ void USB_ResetInterface(void)
 {
 	USB_INT_DisableAllInterrupts();
 	USB_INT_ClearAllInterrupts();
-
-	USB_IsConnected = false;
-
+	
 	#if defined(USB_CAN_BE_HOST)
-	USB_HostState = HOST_STATE_Unattached;
+	USB_HostState   = HOST_STATE_Unattached;
 	#endif
-
+	
 	#if defined(USB_CAN_BE_DEVICE)
+	USB_DeviceState = DEVICE_STATE_Unattached;
 	USB_ConfigurationNumber  = 0;
-	USB_IsSuspended          = false;
 	USB_RemoteWakeupEnabled  = false;
 	USB_CurrentlySelfPowered = false;
 	#endif
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index 3fb30a2f79e06cf699b7f69ab0529c415ff703dd..7d3e87602e8b43e28e2ed07a5f39b4a88be06615 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -93,7 +93,7 @@ uint8_t Pipe_WaitUntilReady(void)
 
 		if (Pipe_IsStalled())
 		  return PIPE_READYWAIT_PipeStalled;
-		else if (!(USB_IsConnected))
+		else if (USB_HostState == HOST_STATE_Unattached)
 		  return PIPE_READYWAIT_DeviceDisconnected;
 			  
 		if (USB_INT_HasOccurred(USB_INT_HSOFI))
diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c
index d66edafd6caa75da72d747d910a67c3d1a018504..b85705c22678556235887f0e1e680c1e679091e0 100644
--- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c
+++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_R.c
@@ -14,9 +14,16 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length)
 			
 			Endpoint_ClearOUT();
 		}
+
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return ENDPOINT_RWCSTREAM_DeviceDisconnected;
 	}
 	
-	while (!(Endpoint_IsINReady()));
+	while (!(Endpoint_IsINReady()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return ENDPOINT_RWCSTREAM_DeviceDisconnected;
+	}
 	
 	return ENDPOINT_RWCSTREAM_NoError;
 }
diff --git a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c
index 2796c64255579ec7dc10b2b04422721512263feb..43a9f3d42c184fd4921db43e252a721d3d6f91f0 100644
--- a/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c
+++ b/LUFA/Drivers/USB/LowLevel/Template/Template_Endpoint_Control_W.c
@@ -8,7 +8,11 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length)
 	
 	while (Length && !(Endpoint_IsOUTReceived()))
 	{
-		while (!(Endpoint_IsINReady()));
+		while (!(Endpoint_IsINReady()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return ENDPOINT_RWCSTREAM_DeviceDisconnected;
+		}
 		
 		while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
 		{
@@ -25,11 +29,20 @@ uint8_t TEMPLATE_FUNC_NAME (void* Buffer, uint16_t Length)
 	
 	if (LastPacketFull)
 	{
-		while (!(Endpoint_IsINReady()));
+		while (!(Endpoint_IsINReady()))
+		{
+			if (USB_DeviceState == DEVICE_STATE_Unattached)
+			  return ENDPOINT_RWCSTREAM_DeviceDisconnected;		
+		}
+		
 		Endpoint_ClearIN();
 	}
 	
-	while (!(Endpoint_IsOUTReceived()));
+	while (!(Endpoint_IsOUTReceived()))
+	{
+		if (USB_DeviceState == DEVICE_STATE_Unattached)
+		  return ENDPOINT_RWCSTREAM_DeviceDisconnected;	
+	}
 
 	return ENDPOINT_RWCSTREAM_NoError;
 }
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 0c51940edc8e2ccbff5be2a34d2051acb36025aa..b2500b0c4a181593162af3f6d95f06d9ccf57eb1 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -29,6 +29,8 @@
   *  - Added new USE_FLASH_DESCRIPTORS and TOTAL_NUM_CONFIGURATIONS compile time options
   *  - Added support for the new ATMEGA32U2, ATMEGA16U2 and ATMEGA8U2 AVR models
   *  - Added new PrinterHost demo (thanks to John Andrews)
+  *  - Added new USB_DeviceState variable to keep track of the current Device mode USB state
+  *  - Added new Endpoint_ClearStatusStage() convenience function to assist with the status stages of control transfers
   *  
   *  <b>Changed:</b>
   *  - Deprecated psuedo-scheduler and removed dynamic memory allocator from the library (first no longer needed and second unused)
@@ -47,6 +49,8 @@
   *    descriptor is located can be specified. This means that descriptors can now be located in multiple memory spaces within a device.
   *  - Host mode demos now use sane terminal escape codes, so that text is always readable and events/program output is visually distinguished
   *    from oneanother using foreground colours
+  *  - Removed vague USB_IsConnected global - test USB_DeviceState or USB_HostState explicitly to gain previous functionality
+  *  - Removed USB_IsSuspended global - test USB_DeviceState against DEVICE_STATE_Suspended instead
   *
   *  <b>Fixed:</b>
   *  - Changed bootloaders to use FLASHEND rather than the existence of RAMPZ to determine if far FLASH pointers are needed to fix
@@ -91,6 +95,8 @@
   *    LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs
   *  - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure
   *  - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt
+  *  - Fixed possible enumeration errors from spinloops which may fail to exit if the USB connection is severed before the exit condition
+  *    becomes true
   *
   *
   *  \section Sec_ChangeLog090510 Version 090510
diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt
index 2d9ec7a95e56a95314c0ea1874097347c39ff684..f11dff2e1bd18e9d20172e7d6bf3a09d259e4cc3 100644
--- a/LUFA/ManPages/CompileTimeTokens.txt
+++ b/LUFA/ManPages/CompileTimeTokens.txt
@@ -157,7 +157,7 @@
  *  On the smaller USB AVRs, the USB controller lacks VBUS events to determine the physical connection state of the USB bus to a host. In lieu of
  *  VBUS events, the library attempts to determine the connection state via the bus suspension and wake up events instead. This however may be
  *  slightly inaccurate due to the possibility of the host suspending the bus while the device is still connected. If accurate connection status is
- *  required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_IsConnected global
+ *  required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_DeviceState global
  *  can be accurately set and the USB_Connect and USB_Disconnect events manually raised by the RAISE_EVENT macro. When defined, this token disables
  *  the library's auto-detection of the connection state by the aforementioned suspension and wake up events.
  *
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index 945406d61a8764464a662611de165184f3b56fe6..5ea8d9c1662e272de0cedb046abc610a797b5499 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -19,17 +19,23 @@
  *    - The "Dynamic Memory Block Allocator" has been removed, as it was unused in (and unrelated to) the LUFA library and never
  *      used in user applications. The library is available from the author's website for those wishing to still use it in their
  *      applications.
+ *    - The USB_IsConnected global has been removed, as it is too vague for general use. Test \ref USB_DeviceState or \ref USB_HostState
+ *      explicitly to ensure the device is in the desired state instead.
  *
  *  <b>Host Mode</b>
  *    - The HIDParser.c module has moved from LUFA/Drivers/USB/Class/ to LUFA/Drivers/USB/Class/Host/.
- *    - The USB_GetDeviceConfigDescriptor() function now requires the desired configuration index within the device as its first
+ *    - The \ref USB_GetDeviceConfigDescriptor() function now requires the desired configuration index within the device as its first
  *      parameter, to add support for multi-configuration devices. Existing code should use a configuration index of 1 to indicate the
  *      first configuration descriptor within the device.
+ *    - The non-standard "Ready" host state has been removed. Existing \ref HOST_STATE_Configured code should be moved to the end of
+ *      the existing \ref HOST_STATE_Addressed state, and the existing HOST_STATE_Ready state code should be moved to the \ref HOST_STATE_Configured
+ *      state.
  *
  *  <b>Device Mode</b>
  *    - The \ref CALLBACK_USB_GetDescriptor() function now takes an extra parameter to specify the descriptor's memory space so that
  *      descriptors in mixed memory spaces can be used. The previous functionality can be returned by defining the USE_FLASH_DESCRIPTORS
  *      token in the project makefile to fix all descriptors into FLASH space and remove the extra function parameter.
+ *    - Removed USB_IsSuspended - test \ref USB_DeviceState against \ref DEVICE_STATE_Suspended instead.
  *
  *
  * \section Sec_Migration090605 Migrating from 090510 to 090605
diff --git a/Projects/MissileLauncher/MissileLauncher.c b/Projects/MissileLauncher/MissileLauncher.c
index 88902cf2e7f9cfa94daed74405f05351dea77278..1ae37044f63ebff704310c289d05386c8971b121 100644
--- a/Projects/MissileLauncher/MissileLauncher.c
+++ b/Projects/MissileLauncher/MissileLauncher.c
@@ -337,9 +337,6 @@ void HID_Host_Task(void)
 			USB_HostState = HOST_STATE_Configured;
 			break;
 		case HOST_STATE_Configured:
-			USB_HostState = HOST_STATE_Ready;
-			break;
-		case HOST_STATE_Ready:
 			DiscardNextReport();
 
 			break;