diff --git a/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.c b/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.c
index 3ef593ff0636024299fccf1cbd6a8a2b1dfeb7fc..246ff3571bc46b272588fbfb71aa72a6eee4ec17 100644
--- a/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.c
+++ b/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.c
@@ -74,7 +74,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
  *  enumerated by the host and is now ready to be used by the application.
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
-{
+{	
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		printf("Error Retrieving Configuration Descriptor.\r\n");
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Mouse_HID_Host_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		printf("Attached Device Not a Valid Mouse.\r\n");
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		printf("Error Setting Device Configuration.\r\n");
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetBootProtocol(&Mouse_HID_Host_Interface) != HOST_SENDCONTROL_Successful)
+	{
+		printf("Could not Set Boot Protocol Mode.\r\n");
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	printf("Mouse Enumerated.\r\n");
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -104,84 +140,38 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Host state machine task. This task handles the enumeration and control of USB Mice while in USB Host mode,
+/** Host USB management task. This task handles the control of USB Mice while in USB Host mode,
  *  setting up the appropriate data pipes and processing reports from the attached device.
  */
-void MouseHostTask(void)
+void MouseHost_Task(void)
 {
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-			uint16_t ConfigDescriptorSize;
-			uint8_t  ConfigDescriptorData[512];
-
-			if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-			                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-			{
-				printf("Error Retrieving Configuration Descriptor.\r\n");
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (HID_Host_ConfigurePipes(&Mouse_HID_Host_Interface,
-			                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-			{
-				printf("Attached Device Not a Valid Mouse.\r\n");
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
 
-			if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-			{
-				printf("Error Setting Device Configuration.\r\n");
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (HID_Host_SetBootProtocol(&Mouse_HID_Host_Interface) != HOST_SENDCONTROL_Successful)
-			{
-				printf("Could not Set Boot Protocol Mode.\r\n");
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf("Mouse Enumerated.\r\n");
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			if (HID_Host_IsReportReceived(&Mouse_HID_Host_Interface))
-			{
-				uint8_t LEDMask  = LEDS_NO_LEDS;
-
-				USB_MouseReport_Data_t MouseReport;
-				HID_Host_ReceiveReport(&Mouse_HID_Host_Interface, &MouseReport);
+	if (HID_Host_IsReportReceived(&Mouse_HID_Host_Interface))
+	{
+		uint8_t LEDMask  = LEDS_NO_LEDS;
 
-				printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
-															  MouseReport.Y,
-															  MouseReport.Button);
-				if (MouseReport.X > 0)
-				  LEDMask |= LEDS_LED1;
-				else if (MouseReport.X < 0)
-				  LEDMask |= LEDS_LED2;
+		USB_MouseReport_Data_t MouseReport;
+		HID_Host_ReceiveReport(&Mouse_HID_Host_Interface, &MouseReport);
 
-				if (MouseReport.Y > 0)
-				  LEDMask |= LEDS_LED3;
-				else if (MouseReport.Y < 0)
-				  LEDMask |= LEDS_LED4;
+		printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
+		                                              MouseReport.Y,
+		                                              MouseReport.Button);
+		if (MouseReport.X > 0)
+		  LEDMask |= LEDS_LED1;
+		else if (MouseReport.X < 0)
+		  LEDMask |= LEDS_LED2;
 
-				if (MouseReport.Button)
-				  LEDMask  = LEDS_ALL_LEDS;
+		if (MouseReport.Y > 0)
+		  LEDMask |= LEDS_LED3;
+		else if (MouseReport.Y < 0)
+		  LEDMask |= LEDS_LED4;
 
-				LEDs_SetAllLEDs(LEDMask);
-			}
+		if (MouseReport.Button)
+		  LEDMask  = LEDS_ALL_LEDS;
 
-			break;
+		LEDs_SetAllLEDs(LEDMask);
 	}
 }
 
diff --git a/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.h b/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.h
index c3187f3df504f409ce8441296133fac3001bed28..ab4c9ecf5ba71c41ada9d02f7a30a265f59412c9 100644
--- a/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.h
+++ b/Demos/DualRole/ClassDriver/MouseHostDevice/HostFunctions.h
@@ -43,7 +43,7 @@
 		extern USB_ClassInfo_HID_Host_t Mouse_HID_Host_Interface;
 
 	/* Function Prototypes: */
-		void MouseHostTask(void);
+		void MouseHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/DualRole/ClassDriver/MouseHostDevice/MouseHostDevice.c b/Demos/DualRole/ClassDriver/MouseHostDevice/MouseHostDevice.c
index 16c8953dc5589ee2d3c72b8d838e06b28025da2d..59c94df9b617332cad5f61eac9abec9f2a55d1c6 100644
--- a/Demos/DualRole/ClassDriver/MouseHostDevice/MouseHostDevice.c
+++ b/Demos/DualRole/ClassDriver/MouseHostDevice/MouseHostDevice.c
@@ -53,7 +53,7 @@ int main(void)
 		/* Determine which USB mode we are currently in */
 		if (USB_CurrentMode == USB_MODE_Host)
 		{
-			MouseHostTask();
+			MouseHost_Task();
 			HID_Host_USBTask(&Mouse_HID_Host_Interface);
 		}
 		else
diff --git a/Demos/Host/ClassDriver/AudioInputHost/AudioInputHost.c b/Demos/Host/ClassDriver/AudioInputHost/AudioInputHost.c
index 21bb9e16d7b0cf36ff4a33220fc3edbe70fbbeee..ab93721ae59977bbfcd2166ed1b926c8f41e093a 100644
--- a/Demos/Host/ClassDriver/AudioInputHost/AudioInputHost.c
+++ b/Demos/Host/ClassDriver/AudioInputHost/AudioInputHost.c
@@ -63,81 +63,6 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (Audio_Host_ConfigurePipes(&Microphone_Audio_Interface,
-				                              ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Audio Input Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (Audio_Host_StartStopStreaming(&Microphone_Audio_Interface, true) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Enabling Audio Stream.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-			
-				USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
-				if (Audio_Host_GetSetEndpointProperty(&Microphone_Audio_Interface, Microphone_Audio_Interface.Config.DataINPipeNumber,
-				                                      AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq,
-				                                      sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;				
-				}
-
-				/* Sample reload timer initialization */
-				TIMSK0  = (1 << OCIE0A);
-				OCR0A   = ((F_CPU / 8 / 48000) - 1);
-				TCCR0A  = (1 << WGM01);  // CTC mode
-				TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
-
-				/* Set speaker as output */
-				DDRC   |= (1 << 6);
-
-				/* PWM speaker timer initialization */
-				TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
-				TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, F_CPU speed
-
-				puts_P(PSTR("Audio Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				/* Do nothing - audio stream is handled by the timer interrupt routine */
-				break;
-		}
-
 		Audio_Host_USBTask(&Microphone_Audio_Interface);
 		USB_USBTask();
 	}
@@ -217,6 +142,65 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (Audio_Host_ConfigurePipes(&Microphone_Audio_Interface,
+	                              ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Audio Input Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (Audio_Host_StartStopStreaming(&Microphone_Audio_Interface, true) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Enabling Audio Stream.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
+	if (Audio_Host_GetSetEndpointProperty(&Microphone_Audio_Interface, Microphone_Audio_Interface.Config.DataINPipeNumber,
+	                                      AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq,
+	                                      sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Sample reload timer initialization */
+	TIMSK0  = (1 << OCIE0A);
+	OCR0A   = ((F_CPU / 8 / 48000) - 1);
+	TCCR0A  = (1 << WGM01);  // CTC mode
+	TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
+
+	/* Set speaker as output */
+	DDRC   |= (1 << 6);
+
+	/* PWM speaker timer initialization */
+	TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
+	TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, F_CPU speed
+
+	puts_P(PSTR("Audio Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/AudioOutputHost/AudioOutputHost.c b/Demos/Host/ClassDriver/AudioOutputHost/AudioOutputHost.c
index b4a7a3b2bb8f171704a10b32bceb86cf49c7d35d..c43b3ab3a3be00dc8992f95419d757e578b763ab 100644
--- a/Demos/Host/ClassDriver/AudioOutputHost/AudioOutputHost.c
+++ b/Demos/Host/ClassDriver/AudioOutputHost/AudioOutputHost.c
@@ -63,74 +63,6 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (Audio_Host_ConfigurePipes(&Speaker_Audio_Interface,
-				                              ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Audio Output Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (Audio_Host_StartStopStreaming(&Speaker_Audio_Interface, true) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Enabling Audio Stream.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-				
-				USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
-				if (Audio_Host_GetSetEndpointProperty(&Speaker_Audio_Interface, Speaker_Audio_Interface.Config.DataOUTPipeNumber,
-				                                      AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq,
-				                                      sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;				
-				}
-
-				/* Sample reload timer initialization */
-				TIMSK0  = (1 << OCIE0A);
-				OCR0A   = ((F_CPU / 8 / 48000) - 1);
-				TCCR0A  = (1 << WGM01);  // CTC mode
-				TCCR0B  = (1 << CS01);   // Fcpu/8 speed
-
-				puts_P(PSTR("Audio Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				/* Do nothing - audio stream is handled by the timer interrupt routine */
-				break;
-		}
-
 		Audio_Host_USBTask(&Speaker_Audio_Interface);
 		USB_USBTask();
 	}
@@ -218,6 +150,58 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (Audio_Host_ConfigurePipes(&Speaker_Audio_Interface,
+	                              ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Audio Output Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (Audio_Host_StartStopStreaming(&Speaker_Audio_Interface, true) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Enabling Audio Stream.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+	
+	USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
+	if (Audio_Host_GetSetEndpointProperty(&Speaker_Audio_Interface, Speaker_Audio_Interface.Config.DataOUTPipeNumber,
+	                                      AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq,
+	                                      sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Sample reload timer initialization */
+	TIMSK0  = (1 << OCIE0A);
+	OCR0A   = ((F_CPU / 8 / 48000) - 1);
+	TCCR0A  = (1 << WGM01);  // CTC mode
+	TCCR0B  = (1 << CS01);   // Fcpu/8 speed
+
+	puts_P(PSTR("Audio Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c
index 4ed0bfb8b8ac409a8b62c8269ce4895f41595548..e74dfe06fdb78c24f3ab193b31abe458784789cb 100644
--- a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c
+++ b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c
@@ -74,97 +74,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Joystick_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Joystick.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetReportProtocol(&Joystick_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Joystick.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Joystick Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (HID_Host_IsReportReceived(&Joystick_HID_Interface))
-				{
-					uint8_t JoystickReport[Joystick_HID_Interface.State.LargestReportSize];
-					HID_Host_ReceiveReport(&Joystick_HID_Interface, &JoystickReport);
-
-					uint8_t LEDMask = LEDS_NO_LEDS;
-
-					for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
-					{
-						HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
-
-						/* Update the report item value if it is contained within the current report */
-						if (!(USB_GetHIDReportItemInfo(JoystickReport, ReportItem)))
-						  continue;
-
-						/* Determine what report item is being tested, process updated value as needed */
-						if ((ReportItem->Attributes.Usage.Page        == USAGE_PAGE_BUTTON) &&
-							(ReportItem->ItemType                     == HID_REPORT_ITEM_In))
-						{
-							if (ReportItem->Value)
-							  LEDMask = LEDS_ALL_LEDS;
-						}
-						else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
-								 ((ReportItem->Attributes.Usage.Usage == USAGE_X)                  ||
-								  (ReportItem->Attributes.Usage.Usage == USAGE_Y))                 &&
-								 (ReportItem->ItemType                == HID_REPORT_ITEM_In))
-						{
-							int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
-
-							if (DeltaMovement)
-							{
-								if (ReportItem->Attributes.Usage.Usage == USAGE_X)
-								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
-								else
-								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
-							}
-						}
-					}
-
-					LEDs_SetAllLEDs(LEDMask);
-				}
-
-				break;
-		}
+		JoystickHost_Task();
 
 		HID_Host_USBTask(&Joystick_HID_Interface);
 		USB_USBTask();
@@ -190,6 +100,57 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB joystick once connected, to display movement
+ *  data as it is received.
+ */
+void JoystickHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	if (HID_Host_IsReportReceived(&Joystick_HID_Interface))
+	{
+		uint8_t JoystickReport[Joystick_HID_Interface.State.LargestReportSize];
+		HID_Host_ReceiveReport(&Joystick_HID_Interface, &JoystickReport);
+
+		uint8_t LEDMask = LEDS_NO_LEDS;
+
+		for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
+		{
+			HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
+
+			/* Update the report item value if it is contained within the current report */
+			if (!(USB_GetHIDReportItemInfo(JoystickReport, ReportItem)))
+			  continue;
+
+			/* Determine what report item is being tested, process updated value as needed */
+			if ((ReportItem->Attributes.Usage.Page        == USAGE_PAGE_BUTTON) &&
+			    (ReportItem->ItemType                     == HID_REPORT_ITEM_In))
+			{
+				if (ReportItem->Value)
+				  LEDMask = LEDS_ALL_LEDS;
+			}
+			else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
+			         ((ReportItem->Attributes.Usage.Usage == USAGE_X)                  ||
+			          (ReportItem->Attributes.Usage.Usage == USAGE_Y))                 &&
+			         (ReportItem->ItemType                == HID_REPORT_ITEM_In))
+			{
+				int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
+
+				if (DeltaMovement)
+				{
+					if (ReportItem->Attributes.Usage.Usage == USAGE_X)
+					  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
+					else
+					  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
+				}
+			}
+		}
+
+		LEDs_SetAllLEDs(LEDMask);
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -213,6 +174,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Joystick_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Joystick.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetReportProtocol(&Joystick_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Joystick.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Joystick Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.h b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.h
index fe6fae7d15012cb29356aa31658de6ca7a4503bb..b68c3729440ffe171f4b6664d2176bbce6e64311 100644
--- a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.h
+++ b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.h
@@ -80,6 +80,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void JoystickHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
index 38af3a7c53f0fa2d19a41e82838aa8070921e3f8..abc038e221dc836c4b36ccfadb4bad56137f8319 100644
--- a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
@@ -69,98 +69,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Keyboard Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
-				{
-					USB_KeyboardReport_Data_t KeyboardReport;
-					HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
-
-					LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0);
-
-					uint8_t KeyCode = KeyboardReport.KeyCode[0];
-
-					if (KeyCode)
-					{
-						char PressedKey = 0;
-
-						LEDs_ToggleLEDs(LEDS_LED2);
-
-						/* Retrieve pressed key character if alphanumeric */
-						if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
-						{
-							PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
-						}
-						else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-						         (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
-						{
-							PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
-						}
-						else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
-						{
-							PressedKey = '0';
-						}
-						else if (KeyCode == HID_KEYBOARD_SC_SPACE)
-						{
-							PressedKey = ' ';
-						}
-						else if (KeyCode == HID_KEYBOARD_SC_ENTER)
-						{
-							PressedKey = '\n';
-						}
-						
-						if (PressedKey)
-						  putchar(PressedKey);
-					}
-				}
-
-				break;
-		}
+		KeyboardHost_Task();
 
 		HID_Host_USBTask(&Keyboard_HID_Interface);
 		USB_USBTask();
@@ -186,6 +95,58 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB keyboard once connected, to display key state
+ *  data as it is received.
+ */
+void KeyboardHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
+	{
+		USB_KeyboardReport_Data_t KeyboardReport;
+		HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
+
+		LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0);
+
+		uint8_t KeyCode = KeyboardReport.KeyCode[0];
+
+		if (KeyCode)
+		{
+			char PressedKey = 0;
+
+			LEDs_ToggleLEDs(LEDS_LED2);
+
+			/* Retrieve pressed key character if alphanumeric */
+			if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
+			{
+				PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
+			}
+			else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
+			         (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+			{
+				PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+			}
+			else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+			{
+				PressedKey = '0';
+			}
+			else if (KeyCode == HID_KEYBOARD_SC_SPACE)
+			{
+				PressedKey = ' ';
+			}
+			else if (KeyCode == HID_KEYBOARD_SC_ENTER)
+			{
+				PressedKey = '\n';
+			}
+			
+			if (PressedKey)
+			  putchar(PressedKey);
+		}
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -209,6 +170,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Keyboard Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.h b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.h
index 52c63709ab1b6f770e10584274c8ef3b46469ed3..878e31b6a86e477f8845d34369fcdc8ccc20667a 100644
--- a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.h
+++ b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.h
@@ -65,6 +65,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void KeyboardHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
index d7df58f07f3bc2c102583ac997763f62ddd8eea6..273cdde676c5fa7d24508df26cad05e53b8beb2a 100644
--- a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -74,119 +74,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Keyboard Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
-				{
-					uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize];
-					HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
-
-					for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
-					{
-						HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
-
-						/* Update the report item value if it is contained within the current report */
-						if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem)))
-						  continue;
-
-						/* Determine what report item is being tested, process updated value as needed */
-						if ((ReportItem->Attributes.Usage.Page      == USAGE_PAGE_KEYBOARD) &&
-							(ReportItem->Attributes.BitSize         == 8)                   &&
-							(ReportItem->Attributes.Logical.Maximum > 1)                    &&
-							(ReportItem->ItemType                   == HID_REPORT_ITEM_In))
-						{
-							/* Key code is an unsigned char in length, cast to the appropriate type */
-							uint8_t KeyCode = (uint8_t)ReportItem->Value;
-
-							/* If scan-code is non-zero, a key is being pressed */
-							if (KeyCode)
-							{
-								/* Toggle status LED to indicate keypress */
-								LEDs_ToggleLEDs(LEDS_LED2);
-
-								char PressedKey = 0;
-
-								/* Convert scan-code to printable character if alphanumeric */
-								if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
-								{
-									PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
-								}
-								else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-										 (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
-								{
-									PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
-								}
-								else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
-								{
-									PressedKey = '0';
-								}
-								else if (KeyCode == HID_KEYBOARD_SC_SPACE)
-								{
-									PressedKey = ' ';
-								}
-								else if (KeyCode == HID_KEYBOARD_SC_ENTER)
-								{
-									PressedKey = '\n';
-								}
-
-								/* Print the pressed key character out through the serial port if valid */
-								if (PressedKey)
-								  putchar(PressedKey);
-							}
-
-							/* Once a scan-code is found, stop scanning through the report items */
-							break;
-						}
-					}
-				}
-
-				break;
-		}
+		KeyboardHost_Task();
 
 		HID_Host_USBTask(&Keyboard_HID_Interface);
 		USB_USBTask();
@@ -212,6 +100,79 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB keyboard once connected, to display key state
+ *  data as it is received.
+ */
+void KeyboardHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	
+	if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
+	{
+		uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize];
+		HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
+
+		for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
+		{
+			HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
+
+			/* Update the report item value if it is contained within the current report */
+			if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem)))
+			  continue;
+
+			/* Determine what report item is being tested, process updated value as needed */
+			if ((ReportItem->Attributes.Usage.Page      == USAGE_PAGE_KEYBOARD) &&
+				(ReportItem->Attributes.BitSize         == 8)                   &&
+				(ReportItem->Attributes.Logical.Maximum > 1)                    &&
+				(ReportItem->ItemType                   == HID_REPORT_ITEM_In))
+			{
+				/* Key code is an unsigned char in length, cast to the appropriate type */
+				uint8_t KeyCode = (uint8_t)ReportItem->Value;
+
+				/* If scan-code is non-zero, a key is being pressed */
+				if (KeyCode)
+				{
+					/* Toggle status LED to indicate keypress */
+					LEDs_ToggleLEDs(LEDS_LED2);
+
+					char PressedKey = 0;
+
+					/* Convert scan-code to printable character if alphanumeric */
+					if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
+					{
+						PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
+					}
+					else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
+							 (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+					{
+						PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+					}
+					else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+					{
+						PressedKey = '0';
+					}
+					else if (KeyCode == HID_KEYBOARD_SC_SPACE)
+					{
+						PressedKey = ' ';
+					}
+					else if (KeyCode == HID_KEYBOARD_SC_ENTER)
+					{
+						PressedKey = '\n';
+					}
+
+					/* Print the pressed key character out through the serial port if valid */
+					if (PressedKey)
+					  putchar(PressedKey);
+				}
+
+				/* Once a scan-code is found, stop scanning through the report items */
+				break;
+			}
+		}
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -235,6 +196,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Keyboard Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.h b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.h
index 94e653a5ffb20d770cb8854e87ac120a86105d2d..2eb974b08b6479e453172b367984026a29160f53 100644
--- a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.h
+++ b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.h
@@ -68,6 +68,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void KeyboardHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c
index b451362a19fcaf24c5ef2083009092b63a07a3f1..068730c8d0b1d1dcd20fed313b1f97d50c38488c 100644
--- a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c
+++ b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.c
@@ -67,63 +67,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (MIDI_Host_ConfigurePipes(&Keyboard_MIDI_Interface,
-				                             ConfigDescriptorSize, ConfigDescriptorData) != MIDI_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid MIDI Class Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("MIDI Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				CheckJoystickMovement();
-
-				MIDI_EventPacket_t MIDIEvent;
-				while (MIDI_Host_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent))
-				{
-					bool NoteOnEvent  = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON  >> 4));
-					bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
-
-					if (NoteOnEvent || NoteOffEvent)
-					{
-						printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
-																						       ((MIDIEvent.Data1 & 0x0F) + 1),
-																						       MIDIEvent.Data2, MIDIEvent.Data3);
-					}
-				}
-
-				break;
-		}
+		JoystickHost_Task();
 
 		MIDI_Host_USBTask(&Keyboard_MIDI_Interface);
 		USB_USBTask();
@@ -151,6 +95,35 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB MIDI device once connected, to display received
+ *  note events from the host and send note changes in response to tbe board's joystick.
+ */
+void JoystickHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	MIDI_EventPacket_t MIDIEvent;
+	while (MIDI_Host_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent))
+	{
+		bool NoteOnEvent  = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON  >> 4));
+		bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
+
+		/* Display note events from the host */
+		if (NoteOnEvent || NoteOffEvent)
+		{
+			printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
+																				   ((MIDIEvent.Data1 & 0x0F) + 1),
+																				   MIDIEvent.Data2, MIDIEvent.Data3);
+		}
+	}
+
+	CheckJoystickMovement();
+}
+
+/** Checks for movement of the board's joystick, and sends corresponding MIDI note on/off
+ *  messages to the host.
+ */
 void CheckJoystickMovement(void)
 {
 	static uint8_t PrevJoystickStatus;
@@ -170,26 +143,22 @@ void CheckJoystickMovement(void)
 		MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 		MIDIPitch   = 0x3C;
 	}
-
-	if (JoystickChanges & JOY_UP)
+	else if (JoystickChanges & JOY_UP)
 	{
 		MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 		MIDIPitch   = 0x3D;
 	}
-
-	if (JoystickChanges & JOY_RIGHT)
+	else if (JoystickChanges & JOY_RIGHT)
 	{
 		MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 		MIDIPitch   = 0x3E;
 	}
-
-	if (JoystickChanges & JOY_DOWN)
+	else if (JoystickChanges & JOY_DOWN)
 	{
 		MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 		MIDIPitch   = 0x3F;
 	}
-
-	if (JoystickChanges & JOY_PRESS)
+	else if (JoystickChanges & JOY_PRESS)
 	{
 		MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
 		MIDIPitch   = 0x3B;
@@ -237,6 +206,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (MIDI_Host_ConfigurePipes(&Keyboard_MIDI_Interface,
+	                             ConfigDescriptorSize, ConfigDescriptorData) != MIDI_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid MIDI Class Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("MIDI Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.h b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.h
index 2688500bcffc9e37a6e85545ecad4872ce7cd2e2..87110259466a030b8a216eb8d382d308730102b3 100644
--- a/Demos/Host/ClassDriver/MIDIHost/MIDIHost.h
+++ b/Demos/Host/ClassDriver/MIDIHost/MIDIHost.h
@@ -68,6 +68,7 @@
 	/* Function Prototypes: */
 		void SetupHardware(void);
 		void CheckJoystickMovement(void);
+		void JoystickHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
index dcbebcc4444325c463f7863ef37fc675a6b76589..5fc3fdfdbb90f1abc40bcb6796a3dd916d044434 100644
--- a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
+++ b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
@@ -67,166 +67,8 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,
-				                           ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Mass Storage Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Mass Storage Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
-				uint8_t MaxLUNIndex;
-				if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex))
-				{
-					puts_P(PSTR("Error retrieving max LUN index.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1));
-
-				if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))
-				{
-					puts_P(PSTR("Error resetting Mass Storage interface.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				SCSI_Request_Sense_Response_t SenseData;
-				if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0)
-				{
-					puts_P(PSTR("Error retrieving device sense.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true))
-				{
-					puts_P(PSTR("Error setting Prevent Device Removal bit.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				SCSI_Inquiry_Response_t InquiryData;
-				if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData))
-				{
-					puts_P(PSTR("Error retrieving device Inquiry data.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
-
-				puts_P(PSTR("Waiting until ready...\r\n"));
-
-				for (;;)
-				{
-					uint8_t ErrorCode = MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0);
-
-					if (!(ErrorCode))
-					  break;
-
-					/* Check if an error other than a logical command error (device busy) received */
-					if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED)
-					{
-						puts_P(PSTR("Error waiting for device to be ready.\r\n"));
-						LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-						USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-						break;
-					}
-				}
-
-				puts_P(PSTR("Retrieving Capacity...\r\n"));
-
-				SCSI_Capacity_t DiskCapacity;
-				if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))
-				{
-					puts_P(PSTR("Error retrieving device capacity.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
-
-				uint8_t BlockBuffer[DiskCapacity.BlockSize];
-
-				if (MS_Host_ReadDeviceBlocks(&FlashDisk_MS_Interface, 0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer))
-				{
-					puts_P(PSTR("Error reading device block.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("\r\nContents of first block:\r\n"));
-
-				for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
-				{
-					uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
-
-					/* Print out the 16 bytes of the chunk in HEX format */
-					for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
-					{
-						char CurrByte = *(ChunkPtr + ByteOffset);
-						printf_P(PSTR("%.2X "), CurrByte);
-					}
-
-					printf_P(PSTR("    "));
-
-					/* Print out the 16 bytes of the chunk in ASCII format */
-					for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
-					{
-						char CurrByte = *(ChunkPtr + ByteOffset);
-						putchar(isprint(CurrByte) ? CurrByte : '.');
-					}
-
-					printf_P(PSTR("\r\n"));
-				}
-
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-		}
-
+		MassStorageHost_Task();
+		
 		MS_Host_USBTask(&FlashDisk_MS_Interface);
 		USB_USBTask();
 	}
@@ -251,6 +93,87 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB Mass Storage device once connected, to print out
+ *  data from the device.
+ */
+void MassStorageHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+
+	puts_P(PSTR("Waiting until ready...\r\n"));
+
+	for (;;)
+	{
+		uint8_t ErrorCode = MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0);
+
+		if (!(ErrorCode))
+		  break;
+
+		/* Check if an error other than a logical command error (device busy) received */
+		if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED)
+		{
+			puts_P(PSTR("Error waiting for device to be ready.\r\n"));
+			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+			USB_Host_SetDeviceConfiguration(0);
+			return;
+		}
+	}
+
+	puts_P(PSTR("Retrieving Capacity...\r\n"));
+
+	SCSI_Capacity_t DiskCapacity;
+	if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))
+	{
+		puts_P(PSTR("Error retrieving device capacity.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
+
+	uint8_t BlockBuffer[DiskCapacity.BlockSize];
+
+	if (MS_Host_ReadDeviceBlocks(&FlashDisk_MS_Interface, 0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer))
+	{
+		puts_P(PSTR("Error reading device block.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("\r\nContents of first block:\r\n"));
+
+	for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
+	{
+		uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
+
+		/* Print out the 16 bytes of the chunk in HEX format */
+		for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
+		{
+			char CurrByte = *(ChunkPtr + ByteOffset);
+			printf_P(PSTR("%.2X "), CurrByte);
+		}
+
+		printf_P(PSTR("    "));
+
+		/* Print out the 16 bytes of the chunk in ASCII format */
+		for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
+		{
+			char CurrByte = *(ChunkPtr + ByteOffset);
+			putchar(isprint(CurrByte) ? CurrByte : '.');
+		}
+
+		printf_P(PSTR("\r\n"));
+	}
+
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -274,6 +197,82 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,
+	                           ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Mass Storage Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	uint8_t MaxLUNIndex;
+	if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex))
+	{
+		puts_P(PSTR("Error retrieving max LUN index.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1));
+
+	if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))
+	{
+		puts_P(PSTR("Error resetting Mass Storage interface.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	SCSI_Request_Sense_Response_t SenseData;
+	if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0)
+	{
+		puts_P(PSTR("Error retrieving device sense.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true))
+	{
+		puts_P(PSTR("Error setting Prevent Device Removal bit.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	SCSI_Inquiry_Response_t InquiryData;
+	if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData))
+	{
+		puts_P(PSTR("Error retrieving device Inquiry data.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
+
+	puts_P(PSTR("Mass Storage Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.h b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.h
index dfc6a8f9475de00352f95f8237d38ef4b525f75d..b4aa02ac9d05c551a895a7be4ee36f527e467d8c 100644
--- a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.h
+++ b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.h
@@ -69,7 +69,8 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-
+		void MassStorageHost_Task(void);
+		
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
 		void EVENT_USB_Host_DeviceUnattached(void);
diff --git a/Demos/Host/ClassDriver/MouseHost/MouseHost.c b/Demos/Host/ClassDriver/MouseHost/MouseHost.c
index e7c03ab4879fdc57c31be966727304846aa693b4..5c94ecda181780510246b062ad95209814eb0d77 100644
--- a/Demos/Host/ClassDriver/MouseHost/MouseHost.c
+++ b/Demos/Host/ClassDriver/MouseHost/MouseHost.c
@@ -69,81 +69,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetBootProtocol(&Mouse_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Mouse Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
-				{
-					uint8_t LEDMask  = LEDS_NO_LEDS;
-
-					USB_MouseReport_Data_t MouseReport;
-					HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
-
-					printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
-																  MouseReport.Y,
-																  MouseReport.Button);
-					if (MouseReport.X > 0)
-					  LEDMask |= LEDS_LED1;
-					else if (MouseReport.X < 0)
-					  LEDMask |= LEDS_LED2;
-
-					if (MouseReport.Y > 0)
-					  LEDMask |= LEDS_LED3;
-					else if (MouseReport.Y < 0)
-					  LEDMask |= LEDS_LED4;
-
-					if (MouseReport.Button)
-					  LEDMask  = LEDS_ALL_LEDS;
-
-					LEDs_SetAllLEDs(LEDMask);
-				}
-
-				break;
-		}
+		MouseHost_Task();
 
 		HID_Host_USBTask(&Mouse_HID_Interface);
 		USB_USBTask();
@@ -169,6 +95,41 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB mouse once connected, to display movement
+ *  data as it is received.
+ */
+void MouseHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	  
+	if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
+	{
+		uint8_t LEDMask = LEDS_NO_LEDS;
+
+		USB_MouseReport_Data_t MouseReport;
+		HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
+
+		printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
+		                                              MouseReport.Y,
+		                                              MouseReport.Button);
+		if (MouseReport.X > 0)
+		  LEDMask |= LEDS_LED1;
+		else if (MouseReport.X < 0)
+		  LEDMask |= LEDS_LED2;
+
+		if (MouseReport.Y > 0)
+		  LEDMask |= LEDS_LED3;
+		else if (MouseReport.Y < 0)
+		  LEDMask |= LEDS_LED4;
+
+		if (MouseReport.Button)
+		  LEDMask  = LEDS_ALL_LEDS;
+
+		LEDs_SetAllLEDs(LEDMask);
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -192,6 +153,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetBootProtocol(&Mouse_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Mouse Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/MouseHost/MouseHost.h b/Demos/Host/ClassDriver/MouseHost/MouseHost.h
index 6dee569a08263a9787359c0a10bd45fcfcbff5da..e0f9a13ab2298ad5c140de1ec432d3927f838a6b 100644
--- a/Demos/Host/ClassDriver/MouseHost/MouseHost.h
+++ b/Demos/Host/ClassDriver/MouseHost/MouseHost.h
@@ -65,6 +65,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void MouseHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c
index 8fd49f2a7d767992cfaf68f9645e7bd28c2617b5..b71554f48d3cdb7e35d27a69a6c8b9b4174adb7e 100644
--- a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c
+++ b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c
@@ -74,106 +74,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Mouse Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
-				{
-					uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize];
-					HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
-
-					uint8_t LEDMask = LEDS_NO_LEDS;
-
-					for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
-					{
-						HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
-
-						/* Update the report item value if it is contained within the current report */
-						if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
-						  continue;
-
-						/* Determine what report item is being tested, process updated value as needed */
-						if ((ReportItem->Attributes.Usage.Page        == USAGE_PAGE_BUTTON) &&
-							(ReportItem->ItemType                     == HID_REPORT_ITEM_In))
-						{
-							if (ReportItem->Value)
-							  LEDMask = LEDS_ALL_LEDS;
-						}
-						else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
-								 (ReportItem->Attributes.Usage.Usage  == USAGE_SCROLL_WHEEL)       &&
-								 (ReportItem->ItemType                == HID_REPORT_ITEM_In))
-						{
-							int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);
-
-							if (WheelDelta)
-							  LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
-						}
-						else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
-								 ((ReportItem->Attributes.Usage.Usage == USAGE_X)                  ||
-								  (ReportItem->Attributes.Usage.Usage == USAGE_Y))                 &&
-								 (ReportItem->ItemType                == HID_REPORT_ITEM_In))
-						{
-							int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
-
-							if (DeltaMovement)
-							{
-								if (ReportItem->Attributes.Usage.Usage == USAGE_X)
-								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
-								else
-								  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
-							}
-						}
-					}
-
-					LEDs_SetAllLEDs(LEDMask);
-				}
-
-				break;
-		}
+		MouseHost_Task();
 
 		HID_Host_USBTask(&Mouse_HID_Interface);
 		USB_USBTask();
@@ -199,6 +100,66 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB mouse once connected, to display movement
+ *  data as it is received.
+ */
+void MouseHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	
+	if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
+	{
+		uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize];
+		HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
+
+		uint8_t LEDMask = LEDS_NO_LEDS;
+
+		for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
+		{
+			HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
+
+			/* Update the report item value if it is contained within the current report */
+			if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
+			  continue;
+
+			/* Determine what report item is being tested, process updated value as needed */
+			if ((ReportItem->Attributes.Usage.Page        == USAGE_PAGE_BUTTON) &&
+			    (ReportItem->ItemType                     == HID_REPORT_ITEM_In))
+			{
+				if (ReportItem->Value)
+				  LEDMask = LEDS_ALL_LEDS;
+			}
+			else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
+			         (ReportItem->Attributes.Usage.Usage  == USAGE_SCROLL_WHEEL)       &&
+			         (ReportItem->ItemType                == HID_REPORT_ITEM_In))
+			{
+				int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);
+
+				if (WheelDelta)
+				  LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
+			}
+			else if ((ReportItem->Attributes.Usage.Page   == USAGE_PAGE_GENERIC_DCTRL) &&
+			         ((ReportItem->Attributes.Usage.Usage == USAGE_X)                  ||
+			          (ReportItem->Attributes.Usage.Usage == USAGE_Y))                 &&
+			         (ReportItem->ItemType                == HID_REPORT_ITEM_In))
+			{
+				int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
+
+				if (DeltaMovement)
+				{
+					if (ReportItem->Attributes.Usage.Usage == USAGE_X)
+					  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
+					else
+					  LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
+				}
+			}
+		}
+
+		LEDs_SetAllLEDs(LEDMask);
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -222,6 +183,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Mouse Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.h b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.h
index 8d90d5cf4e01fd8b692326150c4cde28197333f8..4e9587bd3210d358f16c210f21fe27a22c00ffa5 100644
--- a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.h
+++ b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.h
@@ -83,6 +83,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void MouseHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/PrinterHost/PrinterHost.c b/Demos/Host/ClassDriver/PrinterHost/PrinterHost.c
index 8d51165e661f67fe1c1b9ddd1725160995b61d6a..1233446aa8dd05303fcd4d0ad4595591b342a447 100644
--- a/Demos/Host/ClassDriver/PrinterHost/PrinterHost.c
+++ b/Demos/Host/ClassDriver/PrinterHost/PrinterHost.c
@@ -67,88 +67,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface,
-				                             ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Printer Class Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Bidirectional Mode.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Printer Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
-				puts_P(PSTR("Retrieving Device ID...\r\n"));
-
-				char DeviceIDString[300];
-				if (PRNT_Host_GetDeviceID(&Printer_PRNT_Interface, DeviceIDString,
-				                          sizeof(DeviceIDString)) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Getting Device ID.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("Device ID: %s.\r\n"), DeviceIDString);
-
-				char     TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
-				uint16_t TestPageLength = strlen(TestPageData);
-
-				printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
-
-				if (PRNT_Host_SendData(&Printer_PRNT_Interface, &TestPageData, TestPageLength) != PIPE_RWSTREAM_NoError)
-				{
-					puts_P(PSTR("Error Sending Page Data.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Test Page Sent.\r\n"));
-
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-		}
+		PrinterHost_Task();
 
 		PRNT_Host_USBTask(&Printer_PRNT_Interface);
 		USB_USBTask();
@@ -174,6 +93,49 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB printer once connected, to display device
+ *  information and print a test PCL page.
+ */
+void PrinterHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+
+	puts_P(PSTR("Retrieving Device ID...\r\n"));
+
+	char DeviceIDString[300];
+	if (PRNT_Host_GetDeviceID(&Printer_PRNT_Interface, DeviceIDString,
+	                          sizeof(DeviceIDString)) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Getting Device ID.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Device ID: %s.\r\n"), DeviceIDString);
+
+	char     TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
+	uint16_t TestPageLength = strlen(TestPageData);
+
+	printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
+
+	if (PRNT_Host_SendData(&Printer_PRNT_Interface, &TestPageData, TestPageLength) != PIPE_RWSTREAM_NoError)
+	{
+		puts_P(PSTR("Error Sending Page Data.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Test Page Sent.\r\n"));
+
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -197,6 +159,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface,
+	                             ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Printer Class Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Bidirectional Mode.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Printer Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/PrinterHost/PrinterHost.h b/Demos/Host/ClassDriver/PrinterHost/PrinterHost.h
index 0c0a8277a934ae78c4a6302ed75923c57b465e21..ef78dbba88a7540c4e8aa67b0aa7a2f24a0de9ce 100644
--- a/Demos/Host/ClassDriver/PrinterHost/PrinterHost.h
+++ b/Demos/Host/ClassDriver/PrinterHost/PrinterHost.h
@@ -68,6 +68,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void PrinterHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.c b/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.c
index d19e5a4f05f39b7a5124af6328c6be34fb8f302d..6e942964aac9ab9d48b61d5aaa1f90687de9808c 100644
--- a/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.c
+++ b/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.c
@@ -75,93 +75,21 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface,
-				                              ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid RNDIS Class Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Initializing Device.\r\n"));
-
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize);
-
-				uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
-				if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER,
-				                                &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Packet Filter.\r\n"));
-
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				uint32_t VendorID;
-				if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID,
-				                                  &VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Getting Vendor ID.\r\n"));
-
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
-
-				puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				PrintIncomingPackets();
-
-				break;
-		}
+		RNDISHost_Task();
 
 		RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface);
 		USB_USBTask();
 	}
 }
 
-/** Prints incoming packets from the attached RNDIS device to the serial port. */
-void PrintIncomingPackets(void)
+/** Task to manage an enumerated USB RNDIS device once connected, to display device
+ *  received data packets.
+ */
+void RNDISHost_Task(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	if (RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface))
 	{
 		LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
@@ -222,6 +150,70 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface,
+	                              ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid RNDIS Class Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Initializing Device.\r\n"));
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize);
+
+	uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
+	if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER,
+	                                &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Packet Filter.\r\n"));
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	uint32_t VendorID;
+	if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID,
+	                                  &VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Getting Vendor ID.\r\n"));
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
+
+	puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.h b/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.h
index f0ee56398c357e73c95f930923eead451a14aa65..f4aaa294ad8a16c6a06c7e2f8c496341d2c89ac8 100644
--- a/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.h
+++ b/Demos/Host/ClassDriver/RNDISEthernetHost/RNDISEthernetHost.h
@@ -68,7 +68,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-		void PrintIncomingPackets(void);
+		void RNDISHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
index 91c482af86180f81023373da4d41fb99f478f656..6dd7344018c9dbe082e1f59cf9b1c2553e46c0be 100644
--- a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
+++ b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
@@ -70,80 +70,8 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (SI_Host_ConfigurePipes(&DigitalCamera_SI_Interface,
-				                           ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid Still Image Class Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Still Image Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				puts_P(PSTR("Opening Session...\r\n"));
-
-				if (SI_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
-				{
-					puts_P(PSTR("Could not open PIMA session.\r\n"));
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Turning off Device...\r\n"));
-
-				SI_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL);
-				if (SI_Host_ReceiveResponse(&DigitalCamera_SI_Interface))
-				{
-					puts_P(PSTR("Could not turn off device.\r\n"));
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("Device Off.\r\n"));
-
-				puts_P(PSTR("Closing Session...\r\n"));
-
-				if (SI_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
-				{
-					puts_P(PSTR("Could not close PIMA session.\r\n"));
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-		}
-
+		StillImageHost_Task();
+		
 		SI_Host_USBTask(&DigitalCamera_SI_Interface);
 		USB_USBTask();
 	}
@@ -168,6 +96,48 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB Still Image device once connected, to manage a
+ *  new PIMA session in order to send commands to the attached device.
+ */
+void StillImageHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	puts_P(PSTR("Opening Session...\r\n"));
+
+	if (SI_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
+	{
+		puts_P(PSTR("Could not open PIMA session.\r\n"));
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Turning off Device...\r\n"));
+
+	SI_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL);
+	if (SI_Host_ReceiveResponse(&DigitalCamera_SI_Interface))
+	{
+		puts_P(PSTR("Could not turn off device.\r\n"));
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Device Off.\r\n"));
+
+	puts_P(PSTR("Closing Session...\r\n"));
+
+	if (SI_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
+	{
+		puts_P(PSTR("Could not close PIMA session.\r\n"));
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -191,6 +161,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (SI_Host_ConfigurePipes(&DigitalCamera_SI_Interface,
+	                           ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid Still Image Class Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Still Image Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.h b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.h
index 82bef4f40ea8d4f173235b9c1dd9540f601ebe14..a3c85ebe32fbc20a423815e40a6854c63f4ff9a8 100644
--- a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.h
+++ b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.h
@@ -65,6 +65,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void StillImageHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.c b/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.c
index 4668908521b98d94c1360853c30e07154a40b712..72d7e58347ff7abac7bc6898aa8e76b6e54d318e 100644
--- a/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.c
+++ b/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.c
@@ -70,55 +70,7 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid CDC Class Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("CDC Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface))
-				{
-					/* Echo received bytes from the attached device through the USART */
-					int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface);
-					if (!(ReceivedByte < 0))
-					  putchar(ReceivedByte);
-				}
-
-				break;
-		}
+		CDCHost_Task();
 
 		CDC_Host_USBTask(&VirtualSerial_CDC_Interface);
 		USB_USBTask();
@@ -144,6 +96,23 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to manage an enumerated USB CDC device once connected, to print received data
+ *  from the device to the serial port.
+ */
+void CDCHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface))
+	{
+		/* Echo received bytes from the attached device through the USART */
+		int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface);
+		if (!(ReceivedByte < 0))
+		  putchar(ReceivedByte);
+	}
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -167,6 +136,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid CDC Class Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("CDC Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.h b/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.h
index ee625d79c5405af783fe69801dd588bee1b18093..6a68a32c5fca929e1ffbb2b0baff86d3dab6e14c 100644
--- a/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.h
+++ b/Demos/Host/ClassDriver/VirtualSerialHost/VirtualSerialHost.h
@@ -65,6 +65,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void CDCHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.c b/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.c
index d4df9a11d96b27da7c43d9987e88104510b2bc03..44772fe8a5f979a24e2f275d0302445980c43e4b 100644
--- a/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.c
+++ b/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.c
@@ -50,7 +50,7 @@ int main(void)
 
 	for (;;)
 	{
-		Android_Host_Task();
+		AndroidHost_Task();
 		USB_USBTask();
 	}
 }
@@ -74,6 +74,53 @@ void SetupHardware(void)
 	Serial_CreateStream(NULL);
 }
 
+/** Task to set the configuration of the attached device after it has been enumerated. */
+void AndroidHost_Task(void)
+{
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;	
+
+	/* Select the data IN pipe */
+	Pipe_SelectPipe(ANDROID_DATA_IN_PIPE);
+	Pipe_Unfreeze();
+
+	/* Check to see if a packet has been received */
+	if (Pipe_IsINReceived())
+	{
+		/* Re-freeze IN pipe after the packet has been received */
+		Pipe_Freeze();
+
+		/* Check if data is in the pipe */
+		if (Pipe_IsReadWriteAllowed())
+		{
+			uint8_t NextReceivedByte = Pipe_BytesInPipe();
+			uint8_t LEDMask          = LEDS_NO_LEDS;
+
+			if (NextReceivedByte & 0x01)
+			  LEDMask |= LEDS_LED1;
+
+			if (NextReceivedByte & 0x02)
+			  LEDMask |= LEDS_LED2;
+
+			if (NextReceivedByte & 0x04)
+			  LEDMask |= LEDS_LED3;
+
+			if (NextReceivedByte & 0x08)
+			  LEDMask |= LEDS_LED4;
+
+			LEDs_SetAllLEDs(LEDMask);
+		}
+		else
+		{
+			/* Clear the pipe after all data in the packet has been read, ready for the next packet */
+			Pipe_ClearIN();
+		}
+	}
+
+	/* Re-freeze IN pipe after use */
+	Pipe_Freeze();
+}
+
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
  *  starts the library USB task to begin the enumeration and USB management process.
  */
@@ -97,6 +144,92 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Device Data.\r\n"));
+
+	/* Get and process the configuration descriptor data */
+	uint8_t ErrorCode = ProcessDeviceDescriptor();
+	
+	bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice);
+
+	/* Error out if the device is not an Android device or an error occurred */
+	if ((ErrorCode != AccessoryModeAndroidDevice) && !(RequiresModeSwitch))
+	{
+		if (ErrorCode == DevControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : ""));
+	
+	/* Check if a valid Android device was attached, but it is not current in Accessory mode */
+	if (RequiresModeSwitch)
+	{
+		uint16_t AndroidProtocol;
+	
+		/* Fetch the version of the Android Accessory Protocol supported by the device */
+		if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful)
+		{
+			printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n"
+			                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+			return;
+		}
+		
+		/* Validate the returned protocol version */
+		if (AndroidProtocol != ANDROID_PROTOCOL_Accessory)
+		{
+			puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported."));
+
+			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+			return;
+		}
+	
+		/* Send the device strings and start the Android Accessory Mode */
+		Android_SendString(ANDROID_STRING_Manufacturer, "Dean Camera");
+		Android_SendString(ANDROID_STRING_Model,        "LUFA Android Demo");
+		Android_SendString(ANDROID_STRING_Description,  "LUFA Android Demo");
+		Android_SendString(ANDROID_STRING_Version,      "1.0");
+		Android_SendString(ANDROID_STRING_URI,          "http://www.lufa-lib.org");
+		Android_SendString(ANDROID_STRING_Serial,       "0000000012345678");
+
+		Android_StartAccessoryMode();	
+		return;
+	}
+
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Accessory Mode Android Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,166 +259,3 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated. */
-void Android_Host_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Device Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			ErrorCode = ProcessDeviceDescriptor();
-			
-			bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice);
-
-			/* Error out if the device is not an Android device or an error occurred */
-			if ((ErrorCode != AccessoryModeAndroidDevice) && !(RequiresModeSwitch))
-			{
-				if (ErrorCode == DevControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : ""));
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-			
-			/* Check if a valid Android device was attached, but it is not current in Accessory mode */
-			if (RequiresModeSwitch)
-			{
-				uint16_t AndroidProtocol;
-			
-				/* Fetch the version of the Android Accessory Protocol supported by the device */
-				if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful)
-				{
-					printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n"
-					                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-					/* Indicate error via status LEDs */
-					LEDs_SetAllLEDs(LEDS_LED1);
-
-					/* Wait until USB device disconnected */
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-				
-				/* Validate the returned protocol version */
-				if (AndroidProtocol != ANDROID_PROTOCOL_Accessory)
-				{
-					puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported."));
-
-					/* Indicate error via status LEDs */
-					LEDs_SetAllLEDs(LEDS_LED1);
-
-					/* Wait until USB device disconnected */
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-			
-				/* Send the device strings and start the Android Accessory Mode */
-				Android_SendString(ANDROID_STRING_Manufacturer, "Dean Camera");
-				Android_SendString(ANDROID_STRING_Model,        "LUFA Android Demo");
-				Android_SendString(ANDROID_STRING_Description,  "LUFA Android Demo");
-				Android_SendString(ANDROID_STRING_Version,      "1.0");
-				Android_SendString(ANDROID_STRING_URI,          "http://www.lufa-lib.org");
-				Android_SendString(ANDROID_STRING_Serial,       "0000000012345678");
-				Android_StartAccessoryMode();
-			
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Accessory Mode Android Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Select the data IN pipe */
-			Pipe_SelectPipe(ANDROID_DATA_IN_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check to see if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Re-freeze IN pipe after the packet has been received */
-				Pipe_Freeze();
-
-				/* Check if data is in the pipe */
-				if (Pipe_IsReadWriteAllowed())
-				{
-					uint8_t NextReceivedByte = Pipe_BytesInPipe();
-					uint8_t LEDMask          = LEDS_NO_LEDS;
-
-					if (NextReceivedByte & 0x01)
-						LEDMask |= LEDS_LED1;
-
-					if (NextReceivedByte & 0x02)
-						LEDMask |= LEDS_LED2;
-
-					if (NextReceivedByte & 0x04)
-						LEDMask |= LEDS_LED3;
-
-					if (NextReceivedByte & 0x08)
-						LEDMask |= LEDS_LED4;
-
-					LEDs_SetAllLEDs(LEDMask);
-				}
-				else
-				{
-					/* Clear the pipe after all data in the packet has been read, ready for the next packet */
-					Pipe_ClearIN();
-				}
-			}
-
-			/* Re-freeze IN pipe after use */
-			Pipe_Freeze();
-			break;			
-	}
-}
-
diff --git a/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.h b/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.h
index 59f49c518524e98012f15996966992f1c3564ee6..6c8702fc5ac9e1ad0d2a6aeae848bc75c6f0340f 100644
--- a/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.h
+++ b/Demos/Host/Incomplete/AndroidAccessoryHost/AndroidAccessoryHost.h
@@ -70,6 +70,10 @@
 		/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
 		#define LEDMASK_USB_BUSY          LEDS_LED2
 
+	/* Function Prototypes: */
+		void SetupHardware(void);
+		void AndroidHost_Task(void);
+
 	/* Event Handlers: */
 		void EVENT_USB_Host_DeviceAttached(void);
 		void EVENT_USB_Host_DeviceUnattached(void);
@@ -78,9 +82,5 @@
 		void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 		                                            const uint8_t SubErrorCode);
 
-	/* Function Prototypes: */
-		void Android_Host_Task(void);
-		void SetupHardware(void);
-
 #endif
 
diff --git a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c
index af00cb3216f1e501b23fd40db3741538fbc299c5..c29e7e9d7e5e602b846c20c5f38cc812e2e3198e 100644
--- a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c
+++ b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.c
@@ -60,7 +60,6 @@ int main(void)
 	{
 		RFCOMM_ServiceChannels(SerialChannel_ACL);
 
-		Bluetooth_Host_Task();
 		Bluetooth_Stack_USBTask();
 		USB_USBTask();
 	}
@@ -108,6 +107,55 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Device Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
+	{
+		if (ErrorCode == DevControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+								 " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
+
+	/* Initialize the Bluetooth stack */
+	Bluetooth_Stack_Init();
+
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -137,77 +185,3 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated. */
-void Bluetooth_Host_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Device Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
-			{
-				if (ErrorCode == DevControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Bluetooth Dongle Detected.\r\n"));
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDS_LED1);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
-
-			/* Initialize the Bluetooth stack */
-			Bluetooth_Stack_Init();
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-	}
-}
-
diff --git a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.h b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.h
index b452271b513f4ff314a24105e141631a140c2c8d..30e2301b4d9895cfd72afe001490f42c8e528547 100644
--- a/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.h
+++ b/Demos/Host/Incomplete/BluetoothHost/BluetoothHost.h
@@ -80,7 +80,6 @@
 		                                            const uint8_t SubErrorCode);
 
 	/* Function Prototypes: */
-		void Bluetooth_Host_Task(void);
 		void SetupHardware(void);
 
 #endif
diff --git a/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.c b/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.c
index dac13746875ca3ced4205b2f6a30b3c35530be48..97a18a0f7c5ecb64d0730ba474c0fe6495fbe984 100644
--- a/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.c
+++ b/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.c
@@ -50,7 +50,6 @@ int main(void)
 
 	for (;;)
 	{
-		Audio_Task();
 		USB_USBTask();
 	}
 }
@@ -97,6 +96,81 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+	
+	if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
+	                                                 StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
+			.bRequest      = AUDIO_REQ_SetCurrent,
+			.wValue        = (AUDIO_EPCONTROL_SamplingFreq << 8),
+			.wIndex        = StreamingEndpointAddress,
+			.wLength       = sizeof(USB_Audio_SampleFreq_t),
+		};
+		
+	USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
+
+	/* Select the control pipe for the request transfer */
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	/* Set the sample rate on the streaming interface endpoint */
+	if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);		
+		return;
+	}
+
+	/* Sample reload timer initialization */
+	TIMSK0  = (1 << OCIE0A);
+	OCR0A   = ((F_CPU / 8 / 48000) - 1);
+	TCCR0A  = (1 << WGM01);  // CTC mode
+	TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
+
+	/* Set speaker as output */
+	DDRC   |= (1 << 6);
+
+	/* PWM speaker timer initialization */
+	TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
+	TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, F_CPU speed
+	
+	puts_P(PSTR("Microphone Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,109 +200,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-void Audio_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-			
-			if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
-			                                                 StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			USB_ControlRequest = (USB_Request_Header_t)
-				{
-					.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
-					.bRequest      = AUDIO_REQ_SetCurrent,
-					.wValue        = (AUDIO_EPCONTROL_SamplingFreq << 8),
-					.wIndex        = StreamingEndpointAddress,
-					.wLength       = sizeof(USB_Audio_SampleFreq_t),
-				};
-				
-			USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
-
-			/* Select the control pipe for the request transfer */
-			Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-			/* Set the sample rate on the streaming interface endpoint */
-			if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
-			{
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-	
-			/* Sample reload timer initialization */
-			TIMSK0  = (1 << OCIE0A);
-			OCR0A   = ((F_CPU / 8 / 48000) - 1);
-			TCCR0A  = (1 << WGM01);  // CTC mode
-			TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
-
-			/* Set speaker as output */
-			DDRC   |= (1 << 6);
-
-			/* PWM speaker timer initialization */
-			TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
-			TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, F_CPU speed
-			
-			puts_P(PSTR("Microphone Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Do nothing - audio stream is handled by the timer interrupt routine */
-			break;
-	}
-}
-
 /** ISR to handle the reloading of the PWM timer with the next sample. */
 ISR(TIMER0_COMPA_vect, ISR_BLOCK)
 {
diff --git a/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.h b/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.h
index f60f48ff8a7dbfee3da282e712a61e25cc362ad1..3e03f7f656cce88ed6cd125d6bce65b7288b1a72 100644
--- a/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.h
+++ b/Demos/Host/LowLevel/AudioInputHost/AudioInputHost.h
@@ -66,7 +66,6 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Audio_Task(void);
 		void SetupHardware(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
diff --git a/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.c b/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.c
index 3f0b4a32694f2a6299d487575b81dc98a0a0b119..4fdb661faddeec9ff47584517a78e709ea30b223 100644
--- a/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.c
+++ b/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.c
@@ -50,7 +50,6 @@ int main(void)
 
 	for (;;)
 	{
-		Audio_Task();
 		USB_USBTask();
 	}
 }
@@ -100,6 +99,73 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+	
+	if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
+	                                                 StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
+			.bRequest      = AUDIO_REQ_SetCurrent,
+			.wValue        = (AUDIO_EPCONTROL_SamplingFreq << 8),
+			.wIndex        = StreamingEndpointAddress,
+			.wLength       = sizeof(USB_Audio_SampleFreq_t),
+		};
+		
+	USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
+
+	/* Select the control pipe for the request transfer */
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	/* Set the sample rate on the streaming interface endpoint */
+	if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Sample reload timer initialization */
+	TIMSK0  = (1 << OCIE0A);
+	OCR0A   = ((F_CPU / 8 / 48000) - 1);
+	TCCR0A  = (1 << WGM01);  // CTC mode
+	TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
+	
+	puts_P(PSTR("Speaker Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -129,102 +195,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-void Audio_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-			
-			if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
-			                                                 StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			USB_ControlRequest = (USB_Request_Header_t)
-				{
-					.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
-					.bRequest      = AUDIO_REQ_SetCurrent,
-					.wValue        = (AUDIO_EPCONTROL_SamplingFreq << 8),
-					.wIndex        = StreamingEndpointAddress,
-					.wLength       = sizeof(USB_Audio_SampleFreq_t),
-				};
-				
-			USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
-
-			/* Select the control pipe for the request transfer */
-			Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-			/* Set the sample rate on the streaming interface endpoint */
-			if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
-			{
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-	
-			/* Sample reload timer initialization */
-			TIMSK0  = (1 << OCIE0A);
-			OCR0A   = ((F_CPU / 8 / 48000) - 1);
-			TCCR0A  = (1 << WGM01);  // CTC mode
-			TCCR0B  = (1 << CS01);   // Fcpu/8 speed	
-			
-			puts_P(PSTR("Speaker Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Do nothing - audio stream is handled by the timer interrupt routine */
-			break;
-	}
-}
-
 /** ISR to handle the reloading of the endpoint with the next sample. */
 ISR(TIMER0_COMPA_vect, ISR_BLOCK)
 {
diff --git a/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.h b/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.h
index d4c87e32f9ec9699b884d512ac2c3cd4dfe9e482..59e0fb7eb754848713f7794c5150f002cd15a510 100644
--- a/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.h
+++ b/Demos/Host/LowLevel/AudioOutputHost/AudioOutputHost.h
@@ -80,7 +80,6 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Audio_Task(void);
 		void SetupHardware(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
diff --git a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
index 671fa483320c9b4b1014845266b2e7a0bac3dcf6..720ad03e7d42302ba237088083f65788bedb5506 100644
--- a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
+++ b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		HID_Host_Task();
+		ReadNextReport();
+		
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("HID Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -131,6 +161,9 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
  */
 void ReadNextReport(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	/* Select and unfreeze HID data IN pipe */
 	Pipe_SelectPipe(HID_DATA_IN_PIPE);
 	Pipe_Unfreeze();
@@ -178,6 +211,9 @@ void WriteNextReport(uint8_t* ReportOUTData,
                      const uint8_t ReportType,
                      uint16_t ReportLength)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	/* Select the HID data OUT pipe */
 	Pipe_SelectPipe(HID_DATA_OUT_PIPE);
 
@@ -229,59 +265,3 @@ void WriteNextReport(uint8_t* ReportOUTData,
 	}
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  HID reports from the device and to send reports if desired.
- */
-void HID_Host_Task(void)
-{
-	uint8_t ErrorCode;
-
-	/* Switch to determine what user-application handled host state the host state machine is in */
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("HID Device Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			ReadNextReport();
-
-			break;
-	}
-}
-
diff --git a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.h b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.h
index 0caaae933fbfb6fea2f2b8d5bffa21e0fc05b824..0afaa4f4b57d4289898c598cc8702f5b1148144e 100644
--- a/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.h
+++ b/Demos/Host/LowLevel/GenericHIDHost/GenericHIDHost.h
@@ -76,8 +76,12 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-		void HID_Host_Task(void);
-
+		void ReadNextReport(void);
+		void WriteNextReport(uint8_t* ReportOUTData,
+		                     const uint8_t ReportIndex,
+		                     const uint8_t ReportType,
+		                     uint16_t ReportLength);
+		
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
 		void EVENT_USB_Host_DeviceUnattached(void);
@@ -85,11 +89,5 @@
 		                                            const uint8_t SubErrorCode);
 		void EVENT_USB_Host_DeviceEnumerationComplete(void);
 
-		void ReadNextReport(void);
-		void WriteNextReport(uint8_t* ReportOUTData,
-		                     const uint8_t ReportIndex,
-		                     const uint8_t ReportType,
-		                     uint16_t ReportLength);
-
 #endif
 
diff --git a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c
index 52ce8fea85342f67981aceeeafe61c8327259240..b38fcf07f544468e7cf336c3263641ca580d28e3 100644
--- a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c
+++ b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		Joystick_HID_Task();
+		JoystickHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+	
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
+
+	/* Get and process the device's first HID report descriptor */
+	if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
+	{
+		puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
+
+		if (!(HIDReportInfo.TotalReportItems))
+			puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
+		else
+			printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Joystick Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -125,104 +172,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
+/** Task to read and process the HID report descriptor and HID reports from the device
+ *  and display the results onto the board LEDs.
  */
-void Joystick_HID_Task(void)
+void JoystickHost_Task(void)
 {
-	uint8_t ErrorCode;
-
-	/* Switch to determine what user-application handled host state the host state machine is in */
-	switch (USB_HostState)
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	
+	/* Select and unfreeze joystick data pipe */
+	Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
+	Pipe_Unfreeze();
+
+	/* Check to see if a packet has been received */
+	if (Pipe_IsINReceived())
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
-
-			/* Get and process the device's first HID report descriptor */
-			if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
-			{
-				puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
-
-				if (!(HIDReportInfo.TotalReportItems))
-					puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
-				else
-					printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Joystick Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Select and unfreeze joystick data pipe */
-			Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check to see if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Check if data has been received from the attached joystick */
-				if (Pipe_IsReadWriteAllowed())
-				{
-					/* Create buffer big enough for the report */
-					uint8_t JoystickReport[Pipe_BytesInPipe()];
-
-					/* Load in the joystick report */
-					Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
+		/* Check if data has been received from the attached joystick */
+		if (Pipe_IsReadWriteAllowed())
+		{
+			/* Create buffer big enough for the report */
+			uint8_t JoystickReport[Pipe_BytesInPipe()];
 
-					/* Process the read in joystick report from the device */
-					ProcessJoystickReport(JoystickReport);
-				}
+			/* Load in the joystick report */
+			Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
 
-				/* Clear the IN endpoint, ready for next data packet */
-				Pipe_ClearIN();
-			}
+			/* Process the read in joystick report from the device */
+			ProcessJoystickReport(JoystickReport);
+		}
 
-			/* Freeze joystick data pipe */
-			Pipe_Freeze();
-			break;
+		/* Clear the IN endpoint, ready for next data packet */
+		Pipe_ClearIN();
 	}
+
+	/* Freeze joystick data pipe */
+	Pipe_Freeze();
 }
 
 /** Processes a read HID report from an attached joystick, extracting out elements via the HID parser results
diff --git a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.h b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.h
index 6bcc0613a7125734fdca2f361d316308e8758c2a..f909e66675ef44b38e8cd5739033c524b1158986 100644
--- a/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.h
+++ b/Demos/Host/LowLevel/JoystickHostWithParser/JoystickHostWithParser.h
@@ -67,8 +67,8 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
 	/* Function Prototypes: */
-		void Joystick_HID_Task(void);
 		void SetupHardware(void);
+		void JoystickHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
index 6df052d72040633cd6b289675f4ece320b43016f..92038de70fb139a3ed741e5dbe96b8559dc9650e 100644
--- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		Keyboard_HID_Task();
+		KeyboardHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* HID class request to set the keyboard protocol to the Boot Protocol */
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+			.bRequest      = HID_REQ_SetProtocol,
+			.wValue        = 0,
+			.wIndex        = 0,
+			.wLength       = 0,
+		};
+
+	/* Select the control pipe for the request transfer */
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	/* Send the request, display error and wait for device detach if request fails */
+	if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Keyboard Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,12 +180,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Reads in and processes the next report from the attached device, displaying the report
+/** Task to read in and processes the next report from the attached device, displaying the report
  *  contents on the board LEDs and via the serial port.
  */
-void ReadNextReport(void)
+void KeyboardHost_Task(void)
 {
-	USB_KeyboardReport_Data_t KeyboardReport;
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
 
 	/* Select keyboard data pipe */
 	Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
@@ -151,6 +206,8 @@ void ReadNextReport(void)
 	/* Ensure pipe contains data before trying to read from it */
 	if (Pipe_IsReadWriteAllowed())
 	{
+		USB_KeyboardReport_Data_t KeyboardReport;
+
 		/* Read in keyboard report data */
 		Pipe_Read_Stream_LE(&KeyboardReport, sizeof(KeyboardReport), NULL);
 
@@ -203,86 +260,3 @@ void ReadNextReport(void)
 	Pipe_Freeze();
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  HID reports from the device and display the results onto the board LEDs.
- */
-void Keyboard_HID_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* HID class request to set the keyboard protocol to the Boot Protocol */
-			USB_ControlRequest = (USB_Request_Header_t)
-				{
-					.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
-					.bRequest      = HID_REQ_SetProtocol,
-					.wValue        = 0,
-					.wIndex        = 0,
-					.wLength       = 0,
-				};
-
-			/* Select the control pipe for the request transfer */
-			Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-			/* Send the request, display error and wait for device detach if request fails */
-			if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Keyboard Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* If a report has been received, read and process it */
-			ReadNextReport();
-
-			break;
-	}
-}
-
diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.h b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.h
index bad76379d284d2aeb742a7f1fdc81f7875f4c083..c81433aca1c0fa72f58ac50779046be5190ef85c 100644
--- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.h
+++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.h
@@ -66,8 +66,8 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Keyboard_HID_Task(void);
 		void SetupHardware(void);
+		void KeyboardHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
@@ -76,7 +76,5 @@
 		                                            const uint8_t SubErrorCode);
 		void EVENT_USB_Host_DeviceEnumerationComplete(void);
 
-		void ReadNextReport(void);
-
 #endif
 
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
index ac709003d112ba7b3f80e187f134ce60e88fe407..4837076f2fdfe06df44faff0f21b42f5e1ac1793 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		Keyboard_HID_Task();
+		KeyboardHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,53 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+
+	{
+		puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
+
+	/* Get and process the device's first HID report descriptor */
+	if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
+	{
+		puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
+
+		if (!(HIDReportInfo.TotalReportItems))
+			puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
+		else
+			printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Keyboard Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,104 +174,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
+/** Task to read in and processes the next report from the attached device, displaying the report
+ *  contents on the board LEDs and via the serial port.
  */
-void Keyboard_HID_Task(void)
+void KeyboardHost_Task(void)
 {
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	
+	/* Select and unfreeze keyboard data pipe */
+	Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
+	Pipe_Unfreeze();
+
+	/* Check to see if a packet has been received */
+	if (Pipe_IsINReceived())
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-
-			{
-				puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
-
-			/* Get and process the device's first HID report descriptor */
-			if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
-			{
-				puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
-
-				if (!(HIDReportInfo.TotalReportItems))
-					puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
-				else
-					printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Keyboard Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Select and unfreeze keyboard data pipe */
-			Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check to see if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Check if data has been received from the attached keyboard */
-				if (Pipe_IsReadWriteAllowed())
-				{
-					/* Create buffer big enough for the report */
-					uint8_t KeyboardReport[Pipe_BytesInPipe()];
-
-					/* Load in the keyboard report */
-					Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
+		/* Check if data has been received from the attached keyboard */
+		if (Pipe_IsReadWriteAllowed())
+		{
+			/* Create buffer big enough for the report */
+			uint8_t KeyboardReport[Pipe_BytesInPipe()];
 
-					/* Process the read in keyboard report from the device */
-					ProcessKeyboardReport(KeyboardReport);
-				}
+			/* Load in the keyboard report */
+			Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
 
-				/* Clear the IN endpoint, ready for next data packet */
-				Pipe_ClearIN();
-			}
+			/* Process the read in keyboard report from the device */
+			ProcessKeyboardReport(KeyboardReport);
+		}
 
-			/* Freeze keyboard data pipe */
-			Pipe_Freeze();
-			break;
+		/* Clear the IN endpoint, ready for next data packet */
+		Pipe_ClearIN();
 	}
+
+	/* Freeze keyboard data pipe */
+	Pipe_Freeze();
 }
 
 /** Processes a read HID report from an attached keyboard, extracting out elements via the HID parser results
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.h b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.h
index f9df827435191f9aefbf2ba1155b5c0c0cf8e5b1..f8c38e910c48106f7004bdf4012ee932ba034ad6 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.h
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.h
@@ -62,8 +62,8 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Keyboard_HID_Task(void);
 		void SetupHardware(void);
+		void KeyboardHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/MIDIHost/MIDIHost.c b/Demos/Host/LowLevel/MIDIHost/MIDIHost.c
index 6924fd448a960163f13c4792e1f41530fcaa33b9..e89b261687e6265a2897173220dca3aab7b1dbcb 100644
--- a/Demos/Host/LowLevel/MIDIHost/MIDIHost.c
+++ b/Demos/Host/LowLevel/MIDIHost/MIDIHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		MIDI_Host_Task();
+		MIDIHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -99,6 +100,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("MIDI Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -128,147 +158,102 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read in
- *  note on/off messages from the attached MIDI device and print it to the serial port. When the board
- *  joystick or buttons are pressed, note on/off messages are sent to the attached device.
+/** Task to read in note on/off messages from the attached MIDI device and print it to the serial port.
+ *  When the board joystick or buttons are pressed, note on/off messages are sent to the attached device.
  */
-void MIDI_Host_Task(void)
+void MIDIHost_Task(void)
 {
-	uint8_t ErrorCode;
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+	  
+	Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
 
-	switch (USB_HostState)
+	if (Pipe_IsINReceived())
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
+		MIDI_EventPacket_t MIDIEvent;
 
-			puts_P(PSTR("MIDI Device Enumerated.\r\n"));
+		Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
 
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
+		if (!(Pipe_BytesInPipe()))
+		  Pipe_ClearIN();
 
-			if (Pipe_IsINReceived())
-			{
-				MIDI_EventPacket_t MIDIEvent;
+		bool NoteOnEvent  = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON  >> 4));
+		bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
 
-				Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
-
-				if (!(Pipe_BytesInPipe()))
-				  Pipe_ClearIN();
-
-				bool NoteOnEvent  = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON  >> 4));
-				bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
-
-				if (NoteOnEvent || NoteOffEvent)
-				{
-					printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
-				                                                                           ((MIDIEvent.Data1 & 0x0F) + 1),
-				                                                                           MIDIEvent.Data2, MIDIEvent.Data3);
-				}				
-			}
-
-			Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
-
-			if (Pipe_IsOUTReady())
-			{
-				uint8_t MIDICommand = 0;
-				uint8_t MIDIPitch;
-
-				static uint8_t PrevJoystickStatus;
-				uint8_t JoystickStatus  = Joystick_GetStatus();
-				uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
-
-				/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
-				uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
-
-				if (JoystickChanges & JOY_LEFT)
-				{
-					MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
-					MIDIPitch   = 0x3C;
-				}
-
-				if (JoystickChanges & JOY_UP)
-				{
-					MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
-					MIDIPitch   = 0x3D;
-				}
-
-				if (JoystickChanges & JOY_RIGHT)
-				{
-					MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
-					MIDIPitch   = 0x3E;
-				}
-
-				if (JoystickChanges & JOY_DOWN)
-				{
-					MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
-					MIDIPitch   = 0x3F;
-				}
+		if (NoteOnEvent || NoteOffEvent)
+		{
+			printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
+																				   ((MIDIEvent.Data1 & 0x0F) + 1),
+																				   MIDIEvent.Data2, MIDIEvent.Data3);
+		}				
+	}
 
-				if (JoystickChanges & JOY_PRESS)
-				{
-					MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
-					MIDIPitch   = 0x3B;
-				}
+	Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
 
-				/* Check if a MIDI command is to be sent */
-				if (MIDICommand)
+	if (Pipe_IsOUTReady())
+	{
+		uint8_t MIDICommand = 0;
+		uint8_t MIDIPitch;
+
+		static uint8_t PrevJoystickStatus;
+		uint8_t JoystickStatus  = Joystick_GetStatus();
+		uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
+
+		/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
+		uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
+
+		if (JoystickChanges & JOY_LEFT)
+		{
+			MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
+			MIDIPitch   = 0x3C;
+		}
+
+		if (JoystickChanges & JOY_UP)
+		{
+			MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
+			MIDIPitch   = 0x3D;
+		}
+
+		if (JoystickChanges & JOY_RIGHT)
+		{
+			MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
+			MIDIPitch   = 0x3E;
+		}
+
+		if (JoystickChanges & JOY_DOWN)
+		{
+			MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
+			MIDIPitch   = 0x3F;
+		}
+
+		if (JoystickChanges & JOY_PRESS)
+		{
+			MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
+			MIDIPitch   = 0x3B;
+		}
+
+		/* Check if a MIDI command is to be sent */
+		if (MIDICommand)
+		{
+			MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
 				{
-					MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
-						{
-							.CableNumber = 0,
-							.Command     = (MIDICommand >> 4),
-
-							.Data1       = MIDICommand | Channel,
-							.Data2       = MIDIPitch,
-							.Data3       = MIDI_STANDARD_VELOCITY,
-						};
+					.CableNumber = 0,
+					.Command     = (MIDICommand >> 4),
 
-					/* Write the MIDI event packet to the pipe */
-					Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
+					.Data1       = MIDICommand | Channel,
+					.Data2       = MIDIPitch,
+					.Data3       = MIDI_STANDARD_VELOCITY,
+				};
 
-					/* Send the data in the pipe to the device */
-					Pipe_ClearOUT();
-				}
+			/* Write the MIDI event packet to the pipe */
+			Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
 
-				/* Save previous joystick value for next joystick change detection */
-				PrevJoystickStatus = JoystickStatus;
-			}
+			/* Send the data in the pipe to the device */
+			Pipe_ClearOUT();
+		}
 
-			break;
+		/* Save previous joystick value for next joystick change detection */
+		PrevJoystickStatus = JoystickStatus;
 	}
 }
 
diff --git a/Demos/Host/LowLevel/MIDIHost/MIDIHost.h b/Demos/Host/LowLevel/MIDIHost/MIDIHost.h
index ded949e3c8662d6775c2227e85c495409d9a6eb1..e6486887569d00833d849e2f397a9434420ef129 100644
--- a/Demos/Host/LowLevel/MIDIHost/MIDIHost.h
+++ b/Demos/Host/LowLevel/MIDIHost/MIDIHost.h
@@ -69,7 +69,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-		void MIDI_Host_Task(void);
+		void MIDIHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
index dd085efab8eb033817a96ef277578623baf5b495..a1d39cbb353917e8fd05415d40cc2222c81e27e1 100644
--- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
+++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c
@@ -54,7 +54,8 @@ int main(void)
 
 	for (;;)
 	{
-		MassStorage_Task();
+		MassStorageHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -102,6 +103,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -134,240 +164,181 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 /** Task to set the configuration of the attached device after it has been enumerated, and to read in blocks from
  *  the device and print them to the serial port.
  */
-void MassStorage_Task(void)
+void MassStorageHost_Task(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	/* Indicate device busy via the status LEDs */
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+
 	uint8_t ErrorCode;
 
-	switch (USB_HostState)
+	/* Send the request, display error and wait for device detach if request fails */
+	if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
+	{
+		ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Print number of LUNs detected in the attached device */
+	printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
+
+	/* Reset the Mass Storage device interface, ready for use */
+	if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
+	{
+		ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Get sense data from the device - many devices will not accept any other commands until the sense data
+	 * is read - both on start-up and after a failed command */
+	SCSI_Request_Sense_Response_t SenseData;
+	if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
+	{
+		ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Set the prevent removal flag for the device, allowing it to be accessed */
+	if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
+	{
+		ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Get inquiry data from the device */
+	SCSI_Inquiry_Response_t InquiryData;
+	if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Indicate device busy via the status LEDs */
-			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
-			/* Send the request, display error and wait for device detach if request fails */
-			if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
-			{
-				ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Print number of LUNs detected in the attached device */
-			printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
-
-			/* Reset the Mass Storage device interface, ready for use */
-			if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
-			{
-				ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Get sense data from the device - many devices will not accept any other commands until the sense data
-			 * is read - both on start-up and after a failed command */
-			SCSI_Request_Sense_Response_t SenseData;
-			if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
-			{
-				ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the prevent removal flag for the device, allowing it to be accessed */
-			if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
-			{
-				ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Get inquiry data from the device */
-			SCSI_Inquiry_Response_t InquiryData;
-			if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
-			{
-				ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Print vendor and product names of attached device */
-			printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
-
-			/* Wait until disk ready */
-			puts_P(PSTR("Waiting until ready.."));
-
-			for (;;)
-			{
-				Serial_SendByte('.');
-
-				/* Abort if device removed */
-				if (USB_HostState == HOST_STATE_Unattached)
-				  break;
-
-				/* Check to see if the attached device is ready for new commands */
-				ErrorCode = MassStore_TestUnitReady(0);
-
-				/* If attached device is ready, abort the loop */
-				if (!(ErrorCode))
-				  break;
-
-				/* If an error other than a logical command failure (indicating device busy) returned, abort */
-				if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
-				{
-					ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
-
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-			}
-
-			puts_P(PSTR("\r\nRetrieving Capacity... "));
-
-			/* Create new structure for the disk's capacity in blocks and block size */
-			SCSI_Capacity_t DiskCapacity;
-
-			/* Retrieve disk capacity */
-			if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
-			{
-				ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Display the disk capacity in blocks * block size bytes */
-			printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
-
-			/* Create a new buffer capable of holding a single block from the device */
-			uint8_t BlockBuffer[DiskCapacity.BlockSize];
-
-			/* Read in the first 512 byte block from the device */
-			if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
-			{
-				ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("\r\nContents of first block:\r\n"));
-
-			/* Print out the first block in both HEX and ASCII, 16 bytes per line */
-			for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
-			{
-				/* Pointer to the start of the current 16-byte chunk in the read block of data */
-				uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
-
-				/* Print out the 16 bytes of the chunk in HEX format */
-				for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
-				{
-					char CurrByte = *(ChunkPtr + ByteOffset);
-
-					printf_P(PSTR("%.2X "), CurrByte);
-				}
-
-				puts_P(PSTR("    "));
-
-				/* Print out the 16 bytes of the chunk in ASCII format */
-				for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
-				{
-					char CurrByte = *(ChunkPtr + ByteOffset);
-
-					putchar(isprint(CurrByte) ? CurrByte : '.');
-				}
+		ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Print vendor and product names of attached device */
+	printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
+
+	/* Wait until disk ready */
+	puts_P(PSTR("Waiting until ready.."));
+
+	for (;;)
+	{
+		Serial_SendByte('.');
+
+		/* Abort if device removed */
+		if (USB_HostState == HOST_STATE_Unattached)
+		  break;
+
+		/* Check to see if the attached device is ready for new commands */
+		ErrorCode = MassStore_TestUnitReady(0);
+
+		/* If attached device is ready, abort the loop */
+		if (!(ErrorCode))
+		  break;
+
+		/* If an error other than a logical command failure (indicating device busy) returned, abort */
+		if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
+		{
+			ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
+			USB_Host_SetDeviceConfiguration(0);
+			return;
+		}
+	}
+
+	puts_P(PSTR("\r\nRetrieving Capacity... "));
+
+	/* Create new structure for the disk's capacity in blocks and block size */
+	SCSI_Capacity_t DiskCapacity;
+
+	/* Retrieve disk capacity */
+	if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
+	{
+		ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Display the disk capacity in blocks * block size bytes */
+	printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
+
+	/* Create a new buffer capable of holding a single block from the device */
+	uint8_t BlockBuffer[DiskCapacity.BlockSize];
 
-				puts_P(PSTR("\r\n"));
-			}
+	/* Read in the first 512 byte block from the device */
+	if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
+	{
+		ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("\r\nContents of first block:\r\n"));
+
+	/* Print out the first block in both HEX and ASCII, 16 bytes per line */
+	for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
+	{
+		/* Pointer to the start of the current 16-byte chunk in the read block of data */
+		uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
+
+		/* Print out the 16 bytes of the chunk in HEX format */
+		for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
+		{
+			char CurrByte = *(ChunkPtr + ByteOffset);
+
+			printf_P(PSTR("%.2X "), CurrByte);
+		}
 
-			puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
-
-			/* Wait for the board button to be pressed */
-			while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
-			{
-				/* Abort if device removed */
-				if (USB_HostState == HOST_STATE_Unattached)
-				  break;
-			}
+		puts_P(PSTR("    "));
 
-			/* Abort if device removed */
-			if (USB_HostState == HOST_STATE_Unattached)
-			  break;
+		/* Print out the 16 bytes of the chunk in ASCII format */
+		for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
+		{
+			char CurrByte = *(ChunkPtr + ByteOffset);
 
-			/* Print out the entire disk contents in ASCII format */
-			for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
-			{
-				/* Read in the next block of data from the device */
-				if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
-				{
-					ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
-
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				/* Send the ASCII data in the read in block to the serial port */
-				for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
-				{
-					char CurrByte = BlockBuffer[Byte];
+			putchar(isprint(CurrByte) ? CurrByte : '.');
+		}
 
-					putchar(isprint(CurrByte) ? CurrByte : '.');
-				}
-
-				/* Abort if device removed */
-				if (USB_HostState == HOST_STATE_Unattached)
-				  break;
-			}
+		puts_P(PSTR("\r\n"));
+	}
 
-			/* Indicate device no longer busy */
-			LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
 
-			/* Wait until USB device disconnected */
-			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-			break;
+	/* Wait for the board button to be pressed */
+	while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
+	{
+		/* Abort if device removed */
+		if (USB_HostState == HOST_STATE_Unattached)
+		  return;
 	}
+
+	/* Print out the entire disk contents in ASCII format */
+	for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
+	{
+		/* Read in the next block of data from the device */
+		if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
+		{
+			ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
+			USB_Host_SetDeviceConfiguration(0);
+			return;
+		}
+
+		/* Send the ASCII data in the read in block to the serial port */
+		for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
+		{
+			char CurrByte = BlockBuffer[Byte];
+
+			putchar(isprint(CurrByte) ? CurrByte : '.');
+		}
+	}
+
+	/* Indicate device no longer busy */
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
 }
 
 /** Indicates that a communication error has occurred with the attached Mass Storage Device,
diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.h b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.h
index 92bfb65b535f23a0fa0b5dac9bf61c096cbded03..0aec46fd062887f3e510928d6bbfd6ce69eb1ab6 100644
--- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.h
+++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.h
@@ -74,8 +74,8 @@
 		#define LEDMASK_USB_BUSY          LEDS_LED2
 
 	/* Function Prototypes: */
-		void MassStorage_Task(void);
 		void SetupHardware(void);
+		void MassStorageHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/MouseHost/MouseHost.c b/Demos/Host/LowLevel/MouseHost/MouseHost.c
index c2c900ac78fe8c814d1d4e723fd332b5799270b0..580565b35df992f50f101201a49230fa9617b90f 100644
--- a/Demos/Host/LowLevel/MouseHost/MouseHost.c
+++ b/Demos/Host/LowLevel/MouseHost/MouseHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		Mouse_HID_Task();
+		MouseHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* HID class request to set the mouse protocol to the Boot Protocol */
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+			.bRequest      = HID_REQ_SetProtocol,
+			.wValue        = 0,
+			.wIndex        = 0,
+			.wLength       = 0,
+		};
+
+	/* Select the control pipe for the request transfer */
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	/* Send the request, display error and wait for device detach if request fails */
+	if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
+								 " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Mouse Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -129,8 +183,11 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 /** Reads in and processes the next report from the attached device, displaying the report
  *  contents on the board LEDs and via the serial port.
  */
-void ReadNextReport(void)
+void MouseHost_Task(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	USB_MouseReport_Data_t MouseReport;
 	uint8_t                LEDMask = LEDS_NO_LEDS;
 
@@ -189,87 +246,3 @@ void ReadNextReport(void)
 	Pipe_Freeze();
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  HID reports from the device and display the results onto the board LEDs.
- */
-void Mouse_HID_Task(void)
-{
-	uint8_t ErrorCode;
-
-	/* Switch to determine what user-application handled host state the host state machine is in */
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* HID class request to set the mouse protocol to the Boot Protocol */
-			USB_ControlRequest = (USB_Request_Header_t)
-				{
-					.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
-					.bRequest      = HID_REQ_SetProtocol,
-					.wValue        = 0,
-					.wIndex        = 0,
-					.wLength       = 0,
-				};
-
-			/* Select the control pipe for the request transfer */
-			Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-			/* Send the request, display error and wait for device detach if request fails */
-			if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Mouse Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* If a report has been received, read and process it */
-			ReadNextReport();
-
-			break;
-	}
-}
-
diff --git a/Demos/Host/LowLevel/MouseHost/MouseHost.h b/Demos/Host/LowLevel/MouseHost/MouseHost.h
index 9b960bd7aa6a329f4d18a71eb4cb75ab75a9c11c..b2be102faf385b2c4e1bb925785886d411cc8ca6 100644
--- a/Demos/Host/LowLevel/MouseHost/MouseHost.h
+++ b/Demos/Host/LowLevel/MouseHost/MouseHost.h
@@ -66,8 +66,8 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Mouse_HID_Task(void);
 		void SetupHardware(void);
+		void MouseHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
index 0081096dd6dddb82c09508c53fc7add72e097972..188f72c005343d9c826122c0509506962d922c03 100644
--- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
+++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		Mouse_HID_Task();
+		MouseHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
+
+	/* Get and process the device's first HID report descriptor */
+	if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
+	{
+		puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
+
+		if (!(HIDReportInfo.TotalReportItems))
+			puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
+		else
+			printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Mouse Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,104 +173,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
+/** Task to read and process the HID report descriptor and HID reports from the device and display the
+ *  results onto the board LEDs.
  */
-void Mouse_HID_Task(void)
+void MouseHost_Task(void)
 {
-	uint8_t ErrorCode;
-
-	/* Switch to determine what user-application handled host state the host state machine is in */
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
 
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+	/* Select and unfreeze mouse data pipe */
+	Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
+	Pipe_Unfreeze();
 
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
-
-			/* Get and process the device's first HID report descriptor */
-			if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
-			{
-				puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
-
-				if (!(HIDReportInfo.TotalReportItems))
-					puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
-				else
-					printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Mouse Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Select and unfreeze mouse data pipe */
-			Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check to see if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Check if data has been received from the attached mouse */
-				if (Pipe_IsReadWriteAllowed())
-				{
-					/* Create buffer big enough for the report */
-					uint8_t MouseReport[Pipe_BytesInPipe()];
-
-					/* Load in the mouse report */
-					Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
+	/* Check to see if a packet has been received */
+	if (Pipe_IsINReceived())
+	{
+		/* Check if data has been received from the attached mouse */
+		if (Pipe_IsReadWriteAllowed())
+		{
+			/* Create buffer big enough for the report */
+			uint8_t MouseReport[Pipe_BytesInPipe()];
 
-					/* Process the read in mouse report from the device */
-					ProcessMouseReport(MouseReport);
-				}
+			/* Load in the mouse report */
+			Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
 
-				/* Clear the IN endpoint, ready for next data packet */
-				Pipe_ClearIN();
-			}
+			/* Process the read in mouse report from the device */
+			ProcessMouseReport(MouseReport);
+		}
 
-			/* Freeze mouse data pipe */
-			Pipe_Freeze();
-			break;
+		/* Clear the IN endpoint, ready for next data packet */
+		Pipe_ClearIN();
 	}
+
+	/* Freeze mouse data pipe */
+	Pipe_Freeze();
 }
 
 /** Processes a read HID report from an attached mouse, extracting out elements via the HID parser results
diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.h b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.h
index 1ccbedaadc28624f1c60d6a2b38e2e8d087ef7b7..3ef9e703e666abba32842e40145f751e30a436f7 100644
--- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.h
+++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.h
@@ -67,8 +67,8 @@
 		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
-		void Mouse_HID_Task(void);
 		void SetupHardware(void);
+		void MouseHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
index 6265eeeb93a7e0a1f4d1f53c45b462e8ab8a3121..59e239e0b4837712977f55daae164dd61b924b4f 100644
--- a/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
+++ b/Demos/Host/LowLevel/PrinterHost/PrinterHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		USB_Printer_Host();
+		PrinterHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,65 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
+	 * request to switch to the interface alternate setting with the Bidirectional protocol */
+	if (PrinterAltSetting)
+	{
+		if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
+		{
+			printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
+			                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+			USB_Host_SetDeviceConfiguration(0);
+			return;
+		}
+	}
+
+	puts_P(PSTR("Retrieving Device ID...\r\n"));
+
+	char DeviceIDString[300];
+	if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
+
+	puts_P(PSTR("Printer Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,122 +186,39 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to send some test page
- *  data to the attached printer.
+/** Task to manage an enumerated USB printer once connected, to display device
+ *  information and print a test PCL page.
  */
-void USB_Printer_Host(void)
+void PrinterHost_Task(void)
 {
-	uint8_t ErrorCode;
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
 
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Select the control pipe for the request transfer */
-			Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
-			 * request to switch to the interface alternate setting with the Bidirectional protocol */
-			if (PrinterAltSetting)
-			{
-				if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
-				{
-					printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
-					                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-					/* Indicate error via status LEDs */
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-					/* Wait until USB device disconnected */
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-			}
-
-			puts_P(PSTR("Retrieving Device ID...\r\n"));
-
-			char DeviceIDString[300];
-			if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
-
-			puts_P(PSTR("Printer Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Indicate device busy via the status LEDs */
-			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
-			char  TestPageData[]    = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
-			uint16_t TestPageLength = strlen(TestPageData);
+	uint8_t ErrorCode;
 
-			printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
+	/* Indicate device busy via the status LEDs */
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
 
-			if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
-			{
-				printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+	char  TestPageData[]    = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
+	uint16_t TestPageLength = strlen(TestPageData);
 
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+	printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
 
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
+	/* Send the test page to the attached printer */
+	if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
+	{
+		printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
 
-			puts_P(PSTR("Test Page Sent.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
 
-			/* Indicate device no longer busy */
-			LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	puts_P(PSTR("Test Page Sent.\r\n"));
 
-			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-			break;
-	}
+	/* Indicate device no longer busy */
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);	
+	USB_Host_SetDeviceConfiguration(0);
 }
 
diff --git a/Demos/Host/LowLevel/PrinterHost/PrinterHost.h b/Demos/Host/LowLevel/PrinterHost/PrinterHost.h
index efef07026692dd3ce650347dbf276f3bc8556aa2..4e813a93a9b0f0ca268093bbbb92c31155b62d8b 100644
--- a/Demos/Host/LowLevel/PrinterHost/PrinterHost.h
+++ b/Demos/Host/LowLevel/PrinterHost/PrinterHost.h
@@ -74,16 +74,15 @@
 		extern uint8_t PrinterInterfaceNumber;
 
 	/* Function Prototypes: */
+		void SetupHardware(void);
+		void PrinterHost_Task(void);
+
 		void EVENT_USB_Host_DeviceAttached(void);
 		void EVENT_USB_Host_DeviceUnattached(void);
 		void EVENT_USB_Host_DeviceEnumerationComplete(void);
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 		                                            const uint8_t SubErrorCode);
-
-		void SetupHardware(void);
-
-		void USB_Printer_Host(void);
-
+		
 #endif
 
diff --git a/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.c b/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.c
index 8e86f1bd9f13e2b8016c0e5c08174aadbe1832ce..339da06022e6b56c3f9abda3692a592add283a4f 100644
--- a/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.c
+++ b/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		RNDIS_Host_Task();
+		RNDISHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,75 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	uint16_t DeviceMaxPacketSize;
+	if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
+
+	/* We set the default filter to only receive packets we would be interested in */
+	uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
+	if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
+	                                        &PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	uint32_t VendorID;
+	if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
+	                                          &VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
+
+	puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,8 +196,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-void PrintIncomingPackets(void)
+/** Task to read in data received from the attached RNDIS device and print it to the serial port.
+ */
+void RNDISHost_Task(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	uint8_t ErrorCode;
 
 	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
@@ -136,7 +211,7 @@ void PrintIncomingPackets(void)
 	if ((ErrorCode = RNDIS_GetPacketLength(&PacketLength)) != HOST_SENDCONTROL_Successful)
 	{
 		printf_P(PSTR(ESC_FG_RED "Packet Reception Error.\r\n"
-								 " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
 		return;
 	}
 
@@ -170,107 +245,3 @@ void PrintIncomingPackets(void)
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read in
- *  data received from the attached RNDIS device and print it to the serial port.
- */
-void RNDIS_Host_Task(void)
-{
-	uint8_t ErrorCode;
-
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			uint16_t DeviceMaxPacketSize;
-			if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
-
-			/* We set the default filter to only receive packets we would be interested in */
-			uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
-			if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
-			                                        &PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			uint32_t VendorID;
-			if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
-			                                          &VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
-
-			puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			PrintIncomingPackets();
-
-			break;
-	}
-}
-
diff --git a/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.h b/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.h
index 0f36411e7b20917b58b790f439119b4318d0209e..e8fcf5a85e650ed3fa7edd40e92b3fc55bcfae1f 100644
--- a/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.h
+++ b/Demos/Host/LowLevel/RNDISEthernetHost/RNDISEthernetHost.h
@@ -72,8 +72,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-		void PrintIncomingPackets(void);
-		void RNDIS_Host_Task(void);
+		void RNDISHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
index f174f5302e78b2c1d65604b15f310d9312a57d3e..d2eecb403aa126a72a6c60545911295c6bc38a58 100644
--- a/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
+++ b/Demos/Host/LowLevel/StillImageHost/StillImageHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		StillImage_Task();
+		StillImageHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -98,6 +99,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("Still Image Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -127,214 +157,166 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to print device information
- *  through the serial port.
+/** Task to print device information through the serial port, and open/close a test PIMA session with the
+ *  attached Still Image device.
  */
-void StillImage_Task(void)
+void StillImageHost_Task(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	uint8_t ErrorCode;
 
-	switch (USB_HostState)
+	/* Indicate device busy via the status LEDs */
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+
+	puts_P(PSTR("Retrieving Device Info...\r\n"));
+
+	PIMA_SendBlock = (PIMA_Container_t)
+		{
+			.DataLength    = PIMA_COMMAND_SIZE(0),
+			.Type          = PIMA_CONTAINER_CommandBlock,
+			.Code          = PIMA_OPERATION_GETDEVICEINFO,
+			.TransactionID = 0x00000000,
+			.Params        = {},
+		};
+
+	/* Send the GETDEVICEINFO block */
+	SImage_SendBlockHeader();
+
+	/* Receive the response data block */
+	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
+	{
+		ShowCommandError(ErrorCode, false);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Calculate the size of the returned device info data structure */
+	uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
+
+	/* Create a buffer large enough to hold the entire device info */
+	uint8_t DeviceInfo[DeviceInfoSize];
+
+	/* Read in the data block data (containing device info) */
+	SImage_ReadData(DeviceInfo, DeviceInfoSize);
+
+	/* Once all the data has been read, the pipe must be cleared before the response can be sent */
+	Pipe_ClearIN();
+
+	/* Create a pointer for walking through the info dataset */
+	uint8_t* DeviceInfoPos = DeviceInfo;
+
+	/* Skip over the data before the unicode device information strings */
+	DeviceInfoPos +=  8;                                          // Skip to VendorExtensionDesc String
+	DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
+	DeviceInfoPos +=  2;                                          // Skip over FunctionalMode
+	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Operations Array
+	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Events Array
+	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Device Properties Array
+	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Capture Formats Array
+	DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Image Formats Array
+
+	/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
+	char Manufacturer[*DeviceInfoPos];
+	UnicodeToASCII(DeviceInfoPos, Manufacturer);
+	printf_P(PSTR("   Manufacturer: %s\r\n"), Manufacturer);
+
+	DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Manufacturer String
+
+	/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
+	char Model[*DeviceInfoPos];
+	UnicodeToASCII(DeviceInfoPos, Model);
+	printf_P(PSTR("   Model: %s\r\n"), Model);
+
+	DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Model String
+
+	/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
+	char DeviceVersion[*DeviceInfoPos];
+	UnicodeToASCII(DeviceInfoPos, DeviceVersion);
+	printf_P(PSTR("   Device Version: %s\r\n"), DeviceVersion);
+
+	/* Receive the final response block from the device */
+	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
+	{
+		ShowCommandError(ErrorCode, false);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Verify that the command completed successfully */
+	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
+	{
+		ShowCommandError(PIMA_ReceivedBlock.Code, true);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Opening Session...\r\n"));
+
+	PIMA_SendBlock = (PIMA_Container_t)
+		{
+			.DataLength    = PIMA_COMMAND_SIZE(1),
+			.Type          = PIMA_CONTAINER_CommandBlock,
+			.Code          = PIMA_OPERATION_OPENSESSION,
+			.TransactionID = 0x00000000,
+			.Params        = {0x00000001},
+		};
+
+	/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
+	SImage_SendBlockHeader();
+
+	/* Receive the response block from the device */
+	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
+	{
+		ShowCommandError(ErrorCode, false);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Verify that the command completed successfully */
+	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
+	{
+		ShowCommandError(PIMA_ReceivedBlock.Code, true);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("Closing Session...\r\n"));
+
+	PIMA_SendBlock = (PIMA_Container_t)
+		{
+			.DataLength    = PIMA_COMMAND_SIZE(1),
+			.Type          = PIMA_CONTAINER_CommandBlock,
+			.Code          = PIMA_OPERATION_CLOSESESSION,
+			.TransactionID = 0x00000001,
+			.Params        = {0x00000001},
+		};
+
+	/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
+	SImage_SendBlockHeader();
+
+	/* Receive the response block from the device */
+	if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
+	{
+		ShowCommandError(ErrorCode, false);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	/* Verify that the command completed successfully */
+	if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Still Image Device Enumerated.\r\n"));
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Indicate device busy via the status LEDs */
-			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-
-			puts_P(PSTR("Retrieving Device Info...\r\n"));
-
-			PIMA_SendBlock = (PIMA_Container_t)
-				{
-					.DataLength    = PIMA_COMMAND_SIZE(0),
-					.Type          = PIMA_CONTAINER_CommandBlock,
-					.Code          = PIMA_OPERATION_GETDEVICEINFO,
-					.TransactionID = 0x00000000,
-					.Params        = {},
-				};
-
-			/* Send the GETDEVICEINFO block */
-			SImage_SendBlockHeader();
-
-			/* Receive the response data block */
-			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
-			{
-				ShowCommandError(ErrorCode, false);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Calculate the size of the returned device info data structure */
-			uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
-
-			/* Create a buffer large enough to hold the entire device info */
-			uint8_t DeviceInfo[DeviceInfoSize];
-
-			/* Read in the data block data (containing device info) */
-			SImage_ReadData(DeviceInfo, DeviceInfoSize);
-
-			/* Once all the data has been read, the pipe must be cleared before the response can be sent */
-			Pipe_ClearIN();
-
-			/* Create a pointer for walking through the info dataset */
-			uint8_t* DeviceInfoPos = DeviceInfo;
-
-			/* Skip over the data before the unicode device information strings */
-			DeviceInfoPos +=  8;                                          // Skip to VendorExtensionDesc String
-			DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
-			DeviceInfoPos +=  2;                                          // Skip over FunctionalMode
-			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Operations Array
-			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Events Array
-			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Supported Device Properties Array
-			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Capture Formats Array
-			DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1));      // Skip over Image Formats Array
-
-			/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
-			char Manufacturer[*DeviceInfoPos];
-			UnicodeToASCII(DeviceInfoPos, Manufacturer);
-			printf_P(PSTR("   Manufacturer: %s\r\n"), Manufacturer);
-
-			DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Manufacturer String
-
-			/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
-			char Model[*DeviceInfoPos];
-			UnicodeToASCII(DeviceInfoPos, Model);
-			printf_P(PSTR("   Model: %s\r\n"), Model);
-
-			DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos);   // Skip over Model String
-
-			/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
-			char DeviceVersion[*DeviceInfoPos];
-			UnicodeToASCII(DeviceInfoPos, DeviceVersion);
-			printf_P(PSTR("   Device Version: %s\r\n"), DeviceVersion);
-
-			/* Receive the final response block from the device */
-			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
-			{
-				ShowCommandError(ErrorCode, false);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Verify that the command completed successfully */
-			if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
-			{
-				ShowCommandError(PIMA_ReceivedBlock.Code, true);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Opening Session...\r\n"));
-
-			PIMA_SendBlock = (PIMA_Container_t)
-				{
-					.DataLength    = PIMA_COMMAND_SIZE(1),
-					.Type          = PIMA_CONTAINER_CommandBlock,
-					.Code          = PIMA_OPERATION_OPENSESSION,
-					.TransactionID = 0x00000000,
-					.Params        = {0x00000001},
-				};
-
-			/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
-			SImage_SendBlockHeader();
-
-			/* Receive the response block from the device */
-			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
-			{
-				ShowCommandError(ErrorCode, false);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Verify that the command completed successfully */
-			if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
-			{
-				ShowCommandError(PIMA_ReceivedBlock.Code, true);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Closing Session...\r\n"));
-
-			PIMA_SendBlock = (PIMA_Container_t)
-				{
-					.DataLength    = PIMA_COMMAND_SIZE(1),
-					.Type          = PIMA_CONTAINER_CommandBlock,
-					.Code          = PIMA_OPERATION_CLOSESESSION,
-					.TransactionID = 0x00000001,
-					.Params        = {0x00000001},
-				};
-
-			/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
-			SImage_SendBlockHeader();
-
-			/* Receive the response block from the device */
-			if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
-			{
-				ShowCommandError(ErrorCode, false);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Verify that the command completed successfully */
-			if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
-			{
-				ShowCommandError(PIMA_ReceivedBlock.Code, true);
-
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("Done.\r\n"));
-
-			/* Indicate device no longer busy */
-			LEDs_SetAllLEDs(LEDMASK_USB_READY);
-
-			USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-			break;
+		ShowCommandError(PIMA_ReceivedBlock.Code, true);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
 	}
+
+	puts_P(PSTR("Done.\r\n"));
+
+	/* Indicate device no longer busy */
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
 }
 
 /** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode
diff --git a/Demos/Host/LowLevel/StillImageHost/StillImageHost.h b/Demos/Host/LowLevel/StillImageHost/StillImageHost.h
index bcb5e6bbc8bdd8708d8ee5caeb98a1603acd4fd3..9f53f0c63d5cd2da73e055dee3d8c54f8866edb1 100644
--- a/Demos/Host/LowLevel/StillImageHost/StillImageHost.h
+++ b/Demos/Host/LowLevel/StillImageHost/StillImageHost.h
@@ -69,8 +69,8 @@
 		#define LEDMASK_USB_BUSY          LEDS_LED2
 
 	/* Function Prototypes: */
-		void StillImage_Task(void);
 		void SetupHardware(void);
+		void StillImageHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.c b/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.c
index 8987747bff465af58bc6938543131a999a3f448c..d98a733272f5e4c9068b61b22b1bbbff21855971 100644
--- a/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.c
+++ b/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.c
@@ -50,7 +50,8 @@ int main(void)
 
 	for (;;)
 	{
-		CDC_Host_Task();
+		CDCHost_Task();
+
 		USB_USBTask();
 	}
 }
@@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	puts_P(PSTR("Getting Config Data.\r\n"));
+
+	uint8_t ErrorCode;
+
+	/* Get and process the configuration descriptor data */
+	if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
+	{
+		if (ErrorCode == ControlError)
+		  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
+		else
+		  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
+
+		printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
+	{
+		printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
+		                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	puts_P(PSTR("CDC Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -126,102 +156,57 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 	LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read in
- *  data received from the attached CDC device and print it to the serial port.
+/** Task to read in data received from the attached CDC device and print it to the serial port.
  */
-void CDC_Host_Task(void)
+void CDCHost_Task(void)
 {
-	uint8_t ErrorCode;
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
+	/* Select the data IN pipe */
+	Pipe_SelectPipe(CDC_DATA_IN_PIPE);
+	Pipe_Unfreeze();
+
+	/* Check to see if a packet has been received */
+	if (Pipe_IsINReceived())
+	{
+		/* Re-freeze IN pipe after the packet has been received */
+		Pipe_Freeze();
+
+		/* Check if data is in the pipe */
+		if (Pipe_IsReadWriteAllowed())
+		{
+			/* Get the length of the pipe data, and create a new buffer to hold it */
+			uint16_t BufferLength = Pipe_BytesInPipe();
+			uint8_t  Buffer[BufferLength];
+
+			/* Read in the pipe data to the temporary buffer */
+			Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
+
+			/* Print out the buffer contents to the USART */
+			for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
+			  putchar(Buffer[BufferByte]);
+		}
+
+		/* Clear the pipe after it is read, ready for the next packet */
+		Pipe_ClearIN();
+	}
+
+	/* Re-freeze IN pipe after use */
+	Pipe_Freeze();
 
-	switch (USB_HostState)
+	/* Select and unfreeze the notification pipe */
+	Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
+	Pipe_Unfreeze();
+
+	/* Check if a packet has been received */
+	if (Pipe_IsINReceived())
 	{
-		case HOST_STATE_Addressed:
-			puts_P(PSTR("Getting Config Data.\r\n"));
-
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				if (ErrorCode == ControlError)
-				  puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
-				else
-				  puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
-
-				printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
-				                         " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
-
-				/* Indicate error via status LEDs */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			puts_P(PSTR("CDC Device Enumerated.\r\n"));
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			/* Select the data IN pipe */
-			Pipe_SelectPipe(CDC_DATA_IN_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check to see if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Re-freeze IN pipe after the packet has been received */
-				Pipe_Freeze();
-
-				/* Check if data is in the pipe */
-				if (Pipe_IsReadWriteAllowed())
-				{
-					/* Get the length of the pipe data, and create a new buffer to hold it */
-					uint16_t BufferLength = Pipe_BytesInPipe();
-					uint8_t  Buffer[BufferLength];
-
-					/* Read in the pipe data to the temporary buffer */
-					Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
-
-					/* Print out the buffer contents to the USART */
-					for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
-					  putchar(Buffer[BufferByte]);
-				}
-
-				/* Clear the pipe after it is read, ready for the next packet */
-				Pipe_ClearIN();
-			}
-
-			/* Re-freeze IN pipe after use */
-			Pipe_Freeze();
-
-			/* Select and unfreeze the notification pipe */
-			Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
-			Pipe_Unfreeze();
-
-			/* Check if a packet has been received */
-			if (Pipe_IsINReceived())
-			{
-				/* Discard the unused event notification */
-				Pipe_ClearIN();
-			}
-
-			/* Freeze notification IN pipe after use */
-			Pipe_Freeze();
-
-			break;
+		/* Discard the unused event notification */
+		Pipe_ClearIN();
 	}
+
+	/* Freeze notification IN pipe after use */
+	Pipe_Freeze();
 }
 
diff --git a/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.h b/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.h
index e513b29268f202d81723887812c022a59870f21d..b8436d76da8d8f88f878c4c31499dc68b0942639 100644
--- a/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.h
+++ b/Demos/Host/LowLevel/VirtualSerialHost/VirtualSerialHost.h
@@ -67,7 +67,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
-		void CDC_Host_Task(void);
+		void CDCHost_Task(void);
 
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
diff --git a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
index 9899251ee7a241bccd4a9b98ce76dada0cebf6a2..b5dc7e439aa26038f817700cc237f1bdef6b4706 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h
@@ -132,8 +132,8 @@
 			 *  \note This macro should only be used if the device has indicated to the host that it
 			 *        supports the Remote Wakeup feature in the device descriptors, and should only be
 			 *        issued if the host is currently allowing remote wakeup events from the device (i.e.,
-			 *        the \ref USB_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP compile
-			 *        time option is used, this macro is unavailable.
+			 *        the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP
+			 *        compile time option is used, this macro is unavailable.
 			 *        \n\n
 			 *
 			 *  \note The USB clock must be running for this function to operate. If the stack is initialized with
diff --git a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c
index 2ec49a5d50a73cedda7e93e5c9a160e3368f261d..6d4df036bf2905fb88492d651bbad1c6f2fb21ef 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c
@@ -36,7 +36,7 @@
 #include "../Endpoint.h"
 
 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
-uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
+uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
 bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
diff --git a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h
index 7868ac36a8188af0fe1bbb39bef2976053c8a6eb..8611dd63861e027daee281044083902305ca4085 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h
@@ -846,9 +846,9 @@
 			 *        changed in value.
 			 */
 			#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
-				extern uint8_t USB_ControlEndpointSize;
+				extern uint8_t USB_Device_ControlEndpointSize;
 			#else
-				#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
+				#define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
 			#endif
 
 		/* Function Prototypes: */
diff --git a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
index 5f475a1cc02d308a262111b1180400883002ba66..55cd8f99115a313b747f85e7cc85a6bc9d01a15e 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c
@@ -137,7 +137,7 @@ void USB_Host_ProcessNextHostState(void)
 				break;
 			}
 
-			USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
+			USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
 
 			USB_Host_ResetDevice();
 
@@ -146,7 +146,7 @@ void USB_Host_ProcessNextHostState(void)
 		case HOST_STATE_Default_PostReset:
 			Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
 			                   PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
-			                   USB_ControlPipeSize, PIPE_BANK_SINGLE);
+			                   USB_Host_ControlPipeSize, PIPE_BANK_SINGLE);
 
 			if (!(Pipe_IsConfigured()))
 			{
@@ -175,8 +175,9 @@ void USB_Host_ProcessNextHostState(void)
 		case HOST_STATE_Default_PostAddressSet:
 			USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
 
-			EVENT_USB_Host_DeviceEnumerationComplete();
 			USB_HostState = HOST_STATE_Addressed;
+
+			EVENT_USB_Host_DeviceEnumerationComplete();
 			break;
 	}
 
@@ -253,6 +254,8 @@ static void USB_Host_ResetDevice(void)
 	USB_Host_ResetBus();
 	while (!(USB_Host_IsBusResetComplete()));
 	USB_Host_ResumeBus();
+	
+	USB_Host_ConfigurationNumber = 0;
 
 	bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
 
@@ -285,88 +288,5 @@ static void USB_Host_ResetDevice(void)
 	USB_INT_Enable(USB_INT_DDISCI);
 }
 
-uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_SetConfiguration,
-			.wValue        = ConfigNumber,
-			.wIndex        = 0,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
-uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_GetDescriptor,
-			.wValue        = (DTYPE_Device << 8),
-			.wIndex        = 0,
-			.wLength       = sizeof(USB_Descriptor_Device_t),
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(DeviceDescriptorPtr);
-}
-
-uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
-                                           void* const Buffer,
-                                           const uint8_t BufferLength)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_GetDescriptor,
-			.wValue        = (DTYPE_String << 8) | Index,
-			.wIndex        = 0,
-			.wLength       = BufferLength,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(Buffer);
-}
-
-uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
-			.bRequest      = REQ_ClearFeature,
-			.wValue        = FEATURE_SEL_EndpointHalt,
-			.wIndex        = EndpointNum,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
-uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
-                                        const uint8_t AltSetting)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
-			.bRequest      = REQ_SetInterface,
-			.wValue        = AltSetting,
-			.wIndex        = InterfaceIndex,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
 #endif
 
diff --git a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h
index 6854128d3ffa782e302d382052cdc5fffc710bf9..1b34801d47e78bbc787bb95251e8b82f0f428e09 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h
@@ -207,6 +207,9 @@
 			/** Suspends the USB bus, preventing any communications from occurring between the host and attached
 			 *  device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
 			 *  messages to the device.
+			 *
+			 *  \note While the USB bus is suspended, all USB interrupt sources are also disabled; this means that
+			 *        some events (such as device disconnections) will not fire until the bus is resumed.
 			 */
 			static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
 			static inline void USB_Host_SuspendBus(void)
@@ -276,73 +279,6 @@
 				return ((UHCON & (1 << RESUME)) ? false : true);
 			}
 
-		/* Function Prototypes: */
-			/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
-			 *  device, with the given configuration index. This can be used to easily set the device
-			 *  configuration without creating and sending the request manually.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] ConfigNumber  Configuration index to send to the device.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
-
-			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
-			 *  device, requesting the device descriptor. This can be used to easily retrieve information
-			 *  about the device such as its VID, PID and power requirements.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[out] DeviceDescriptorPtr  Pointer to the destination device descriptor structure where
-			 *                                   the read data is to be stored.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
-
-			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
-			 *  device, requesting the string descriptor of the specified index. This can be used to easily
-			 *  retrieve string descriptors from the device by index, after the index is obtained from the
-			 *  Device or Configuration descriptors.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in]  Index        Index of the string index to retrieve.
-			 *  \param[out] Buffer       Pointer to the destination buffer where the retrieved string descriptor is
-			 *                           to be stored.
-			 *  \param[in] BufferLength  Maximum size of the string descriptor which can be stored into the buffer.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
-			                                           void* const Buffer,
-			                                           const uint8_t BufferLength);
-
-			/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] EndpointIndex  Index of the endpoint to clear, including the endpoint's direction.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
-
-			/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
-			 *  the attached device.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] InterfaceIndex  Index of the interface whose alternative setting is to be altered.
-			 *  \param[in] AltSetting      Index of the interface's alternative setting which is to be selected.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
-													const uint8_t AltSetting);
-
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Macros: */
diff --git a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c
index e93b256c6844c135d2541e4d3713fd5758197e90..5d7c8ac1bf7ba9761ae728bccb2024ccf99694d3 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c
@@ -35,7 +35,7 @@
 
 #include "../Pipe.h"
 
-uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
+uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
 
 bool Pipe_ConfigurePipe(const uint8_t Number,
                         const uint8_t Type,
diff --git a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h
index 1939d3906e42826855ebf85a499137b894e5055d..efe0ef1ba181d6f8c5b52c2c8f2b09e6d8cc7700 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h
+++ b/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h
@@ -804,7 +804,7 @@
 			 *  \note This variable should be treated as read-only in the user application, and never manually
 			 *        changed in value.
 			 */
-			extern uint8_t USB_ControlPipeSize;
+			extern uint8_t USB_Host_ControlPipeSize;
 
 		/* Function Prototypes: */
 			/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
diff --git a/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c
index 1d6361fb824ea44f557812b8ed43898766c51c55..5d4fc42f2a2482f972adeabe990d63c04bb6fca6 100644
--- a/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c
+++ b/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c
@@ -58,7 +58,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 		{
 			uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint();
 
-			while (Length && (BytesInEndpoint < USB_ControlEndpointSize))
+			while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize))
 			{
 				TEMPLATE_TRANSFER_BYTE(DataStream);
 				TEMPLATE_BUFFER_MOVE(DataStream, 1);
@@ -66,7 +66,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 				BytesInEndpoint++;
 			}
 
-			LastPacketFull = (BytesInEndpoint == USB_ControlEndpointSize);
+			LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize);
 			Endpoint_ClearIN();
 		}
 	}
diff --git a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c
index 4802463f00b4670c62c3ed59b53582d67f610e43..571ab6c8a64859f733827f58bade897e79a5c85d 100644
--- a/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c
@@ -178,15 +178,15 @@ void USB_ResetInterface(void)
 #if defined(USB_CAN_BE_DEVICE)
 static void USB_Init_Device(void)
 {
-	USB_DeviceState          = DEVICE_STATE_Unattached;
-	USB_ConfigurationNumber  = 0;
+	USB_DeviceState                 = DEVICE_STATE_Unattached;
+	USB_Device_ConfigurationNumber  = 0;
 
 	#if !defined(NO_DEVICE_REMOTE_WAKEUP)
-	USB_RemoteWakeupEnabled  = false;
+	USB_Device_RemoteWakeupEnabled  = false;
 	#endif
 
 	#if !defined(NO_DEVICE_SELF_POWER)
-	USB_CurrentlySelfPowered = false;
+	USB_Device_CurrentlySelfPowered = false;
 	#endif
 
 	#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
@@ -199,21 +199,21 @@ static void USB_Init_Device(void)
 	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR)
 	{
 		if (DescriptorAddressSpace == MEMSPACE_FLASH)
-		  USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
+		  USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
 		else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
-		  USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
+		  USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
 		else
-		  USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
+		  USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
 	}
 	#else
 	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
 	{
 		#if defined(USE_RAM_DESCRIPTORS)
-		USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
+		USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
 		#elif defined(USE_EEPROM_DESCRIPTORS)
-		USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
+		USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
 		#else
-		USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
+		USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
 		#endif
 	}	
 	#endif
@@ -229,7 +229,7 @@ static void USB_Init_Device(void)
 	#endif
 
 	Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
-							   ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
+							   ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
 							   ENDPOINT_BANK_SINGLE);
 
 	USB_INT_Clear(USB_INT_SUSPI);
@@ -243,8 +243,9 @@ static void USB_Init_Device(void)
 #if defined(USB_CAN_BE_HOST)
 static void USB_Init_Host(void)
 {
-	USB_HostState       = HOST_STATE_Unattached;
-	USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
+	USB_HostState                = HOST_STATE_Unattached;
+	USB_Host_ConfigurationNumber = 0;
+	USB_Host_ControlPipeSize     = PIPE_CONTROLPIPE_DEFAULT_SIZE;
 
 	USB_Host_HostMode_On();
 
@@ -254,7 +255,7 @@ static void USB_Init_Host(void)
 
 	USB_INT_Enable(USB_INT_SRPI);
 	USB_INT_Enable(USB_INT_BCERRI);
-
+	
 	USB_Attach();
 }
 #endif
diff --git a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
index 4939ec2edf3ab6cc07322c67abceb78f2235448d..328017ef3cbb37acc86b5cc42afc842e45f2d0f7 100644
--- a/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
+++ b/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c
@@ -144,7 +144,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 		USB_INT_Disable(USB_INT_WAKEUPI);
 		USB_INT_Enable(USB_INT_SUSPI);
 
-		if (USB_ConfigurationNumber)
+		if (USB_Device_ConfigurationNumber)
 		  USB_DeviceState = DEVICE_STATE_Configured;
 		else
 		  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
@@ -160,15 +160,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 	{
 		USB_INT_Clear(USB_INT_EORSTI);
 
-		USB_DeviceState         = DEVICE_STATE_Default;
-		USB_ConfigurationNumber = 0;
+		USB_DeviceState                = DEVICE_STATE_Default;
+		USB_Device_ConfigurationNumber = 0;
 
 		USB_INT_Clear(USB_INT_SUSPI);
 		USB_INT_Disable(USB_INT_SUSPI);
 		USB_INT_Enable(USB_INT_WAKEUPI);
 
 		Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
-		                           ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
+		                           ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
 		                           ENDPOINT_BANK_SINGLE);
 
 		#if defined(INTERRUPT_CONTROL_ENDPOINT)
diff --git a/LUFA/Drivers/USB/Core/DeviceStandardReq.c b/LUFA/Drivers/USB/Core/DeviceStandardReq.c
index f9c64b6f8977af522d4f2b3235511a7b22c56768..c3a111e351caa5d29845b3ead9d9cb520c5516ff 100644
--- a/LUFA/Drivers/USB/Core/DeviceStandardReq.c
+++ b/LUFA/Drivers/USB/Core/DeviceStandardReq.c
@@ -36,14 +36,14 @@
 #define  __INCLUDE_FROM_DEVICESTDREQ_C
 #include "DeviceStandardReq.h"
 
-uint8_t USB_ConfigurationNumber;
+uint8_t USB_Device_ConfigurationNumber;
 
 #if !defined(NO_DEVICE_SELF_POWER)
-bool    USB_CurrentlySelfPowered;
+bool    USB_Device_CurrentlySelfPowered;
 #endif
 
 #if !defined(NO_DEVICE_REMOTE_WAKEUP)
-bool    USB_RemoteWakeupEnabled;
+bool    USB_Device_RemoteWakeupEnabled;
 #endif
 
 void USB_Device_ProcessControlRequest(void)
@@ -184,11 +184,11 @@ static void USB_Device_SetConfiguration(void)
 
 	Endpoint_ClearSETUP();
 
-	USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
+	USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
 
 	Endpoint_ClearStatusStage();
 
-	if (USB_ConfigurationNumber)
+	if (USB_Device_ConfigurationNumber)
 	  USB_DeviceState = DEVICE_STATE_Configured;
 	else
 	  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
@@ -200,7 +200,7 @@ static void USB_Device_GetConfiguration(void)
 {
 	Endpoint_ClearSETUP();
 
-	Endpoint_Write_8(USB_ConfigurationNumber);
+	Endpoint_Write_8(USB_Device_ConfigurationNumber);
 	Endpoint_ClearIN();
 
 	Endpoint_ClearStatusStage();
@@ -285,12 +285,12 @@ static void USB_Device_GetStatus(void)
 		#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
 		case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
 			#if !defined(NO_DEVICE_SELF_POWER)
-			if (USB_CurrentlySelfPowered)
+			if (USB_Device_CurrentlySelfPowered)
 			  CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
 			#endif
 
 			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
-			if (USB_RemoteWakeupEnabled)
+			if (USB_Device_RemoteWakeupEnabled)
 			  CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
 			#endif
 			break;
@@ -324,7 +324,7 @@ static void USB_Device_ClearSetFeature(void)
 		#if !defined(NO_DEVICE_REMOTE_WAKEUP)
 		case REQREC_DEVICE:
 			if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
-			  USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
+			  USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
 			else
 			  return;
 
diff --git a/LUFA/Drivers/USB/Core/DeviceStandardReq.h b/LUFA/Drivers/USB/Core/DeviceStandardReq.h
index 24b3e60dad6014ef8bc943089fc90fbe0f73bf1b..f47d8f644cbca8193eee0f2d10ea8e092021617e 100644
--- a/LUFA/Drivers/USB/Core/DeviceStandardReq.h
+++ b/LUFA/Drivers/USB/Core/DeviceStandardReq.h
@@ -91,7 +91,7 @@
 			 *
 			 *  \ingroup Group_Device
 			 */
-			extern uint8_t USB_ConfigurationNumber;
+			extern uint8_t USB_Device_ConfigurationNumber;
 
 			#if !defined(NO_DEVICE_REMOTE_WAKEUP)
 				/** Indicates if the host is currently allowing the device to issue remote wakeup events. If this
@@ -108,7 +108,7 @@
 				 *
 				 *  \ingroup Group_Device
 				 */
-				extern bool USB_RemoteWakeupEnabled;
+				extern bool USB_Device_RemoteWakeupEnabled;
 			#endif
 
 			#if !defined(NO_DEVICE_SELF_POWER)
@@ -118,7 +118,7 @@
 				 *
 				 *  \ingroup Group_Device
 				 */
-				extern bool USB_CurrentlySelfPowered;
+				extern bool USB_Device_CurrentlySelfPowered;
 			#endif
 
 	/* Private Interface - For use in library only: */
diff --git a/LUFA/Drivers/USB/Core/Events.h b/LUFA/Drivers/USB/Core/Events.h
index 2ea14bf10a7edb92bbbd08e9b519e8abe72206c1..8afd3b53cc8178a3ebd4dd20d05b3936e526d816 100644
--- a/LUFA/Drivers/USB/Core/Events.h
+++ b/LUFA/Drivers/USB/Core/Events.h
@@ -249,7 +249,7 @@
 			 *  This event is time-critical; exceeding OS-specific delays within this event handler (typically of around
 			 *  one second) will prevent the device from enumerating correctly.
 			 *
-			 *  This event fires after the value of \ref USB_ConfigurationNumber has been changed.
+			 *  This event fires after the value of \ref USB_Device_ConfigurationNumber has been changed.
 			 *
 			 *  \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see
 			 *        \ref Group_USBManagement documentation).
diff --git a/LUFA/Drivers/USB/Core/Host.h b/LUFA/Drivers/USB/Core/Host.h
index 53a6b9a6ccae49d4468d5c2642dc1d507ff295e0..6bd7fab20d98623413526f97e32cb36456f7453d 100644
--- a/LUFA/Drivers/USB/Core/Host.h
+++ b/LUFA/Drivers/USB/Core/Host.h
@@ -65,8 +65,7 @@
 
 	/* Public Interface - May be used in end-application: */
 		/* Enums: */
-			/** Enum for the various states of the USB Host state machine. Only some states are
-			 *  implemented in the LUFA library - other states are left to the user to implement.
+			/** Enum for the various states of the USB Host state machine.
 			 *
 			 *  For information on each possible USB host state, refer to the USB 2.0 specification.
 			 *  Several of the USB host states are broken up further into multiple smaller sub-states,
@@ -76,94 +75,49 @@
 			 */
 			enum USB_Host_States_t
 			{
-				HOST_STATE_WaitForDeviceRemoval         = 0,  /**< Internally implemented by the library. This state can be
-				                                               *   used by the library to wait until the attached device is
-				                                               *   removed by the user - useful for when an error occurs or
-				                                               *   further communication with the device is not needed. This
-				                                               *   allows for other code to run while the state machine is
-				                                               *   effectively disabled.
+				HOST_STATE_WaitForDevice                = 0,  /**< This state indicates that the stack is waiting for an interval
+				                                               *   to elapse before continuing with the next step of the device
+				                                               *   enumeration process.
 				                                               */
-				HOST_STATE_WaitForDevice                = 1,  /**< Internally implemented by the library. This state indicates
-				                                               *   that the stack is waiting for an interval to elapse before
-				                                               *   continuing with the next step of the device enumeration
-				                                               *   process.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
-				                                               */
-				HOST_STATE_Unattached                   = 2,  /**< Internally implemented by the library. This state indicates
-				                                               *   that the host state machine is waiting for a device to be
-				                                               *   attached so that it can start the enumeration process.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
+				HOST_STATE_Unattached                   = 1,  /**< This state indicates that the host state machine is waiting for
+				                                               *   a device to be attached so that it can start the enumeration process.
 				                                               */
-				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_Powered                      = 2,  /**< This state indicates that a device has been attached, and the
+				                                               *   library's internals are being configured to begin the enumeration
+				                                               *   process.
 				                                               */
-				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_Powered_WaitForDeviceSettle  = 3,  /**< This state indicates that the stack is waiting for the initial
+				                                               *   settling period to elapse before beginning the enumeration process.
 				                                               */
-				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_Powered_WaitForConnect       = 4,  /**< 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.
 				                                               */
-				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_DoReset              = 5,  /**< This state indicates that a valid USB device has been attached, and that
+				                                               *   it will now be reset to ensure it is ready for enumeration.
 				                                               */
-				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.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
+				HOST_STATE_Powered_ConfigPipe           = 6,  /**< This state indicates that the attached device is currently powered and
+				                                               *   reset, and that the control pipe is now being configured by the stack.
 				                                               */
-				HOST_STATE_Default                      = 8,  /**< Internally implemented by the library. This state indicates
-				                                               *   that the stack is currently retrieving the control endpoint's
-				                                               *   size from the device, so that the control pipe can be altered
+				HOST_STATE_Default                      = 7,  /**< This state indicates that the stack is currently retrieving the control
+				                                               *   endpoint's size from the device, so that the control pipe can be altered
 				                                               *   to match.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
-				                                               */
-				HOST_STATE_Default_PostReset            = 9,  /**< Internally implemented by the library. This state indicates that
-				                                               *   the control pipe is being reconfigured to match the retrieved
-				                                               *   control endpoint size from the device, and the device's USB bus
-				                                               *   address is being set.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
 				                                               */
-				HOST_STATE_Default_PostAddressSet       = 10, /**< Internally implemented by the library. This state indicates that
-				                                               *   the device's address has now been set, and the stack is has now
-				                                               *   completed the device enumeration process. This state causes the
-				                                               *   stack to change the current USB device address to that set for
-				                                               *   the connected device, before progressing to the user-implemented
-				                                               *   \ref HOST_STATE_Addressed state for further communications.
-				                                               *
-				                                               *   \note Do not manually change to this state in the user code.
+				HOST_STATE_Default_PostReset            = 8,  /**< This state indicates that the control pipe is being reconfigured to match
+				                                               *   the retrieved control endpoint size from the device, and the device's USB
+				                                               *   bus address is being set.
 				                                               */
-				HOST_STATE_Addressed                    = 11, /**< May be implemented by the user project. This state should
-				                                               *   set the device configuration before progressing to the
-				                                               *   \ref HOST_STATE_Configured state. Other processing (such as the
-				                                               *   retrieval and processing of the device descriptor) should also
-				                                               *   be placed in this state.
+				HOST_STATE_Default_PostAddressSet       = 9,  /**< This state indicates that the device's address has now been set, and the
+				                                               *   stack is has now completed the device enumeration process. This state causes 
+				                                               *   the stack to change the current USB device address to that set for the
+				                                               *   connected device, before progressing to the \ref HOST_STATE_Addressed state
+				                                               *   ready for use in the user application.
 				                                               */
-				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
-				                                               *   \ref HOST_STATE_Suspended or \ref HOST_STATE_WaitForDeviceRemoval states as needed.
+				HOST_STATE_Addressed                    = 10, /**< Indicates that the device has been enumerated and addressed, and is now waiting
+				                                               *   for the user application to configure the device ready for use.				
 				                                               */
-				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 \ref HOST_STATE_Configured
-				                                               *   (after resuming the bus with the USB_Host_ResumeBus() macro) or the
-				                                               *   \ref HOST_STATE_WaitForDeviceRemoval states as needed.
+				HOST_STATE_Configured                   = 11, /**< Indicates that the device has been configured into a valid device configuration,
+				                                               *   ready for general use by the user application.				
 				                                               */
 			};
 
diff --git a/LUFA/Drivers/USB/Core/HostStandardReq.c b/LUFA/Drivers/USB/Core/HostStandardReq.c
index 412ac8968c5a8e34e0abff3dc2f5c21a37754039..a9451ff16e93f699f6c60d2e930f16d4c71d13c1 100644
--- a/LUFA/Drivers/USB/Core/HostStandardReq.c
+++ b/LUFA/Drivers/USB/Core/HostStandardReq.c
@@ -36,6 +36,8 @@
 #define  __INCLUDE_FROM_HOSTSTDREQ_C
 #include "HostStandardReq.h"
 
+uint8_t USB_Host_ConfigurationNumber;
+
 uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
 {
 	uint8_t* DataStream   = (uint8_t*)BufferPtr;
@@ -119,7 +121,7 @@ uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
 				if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
 				  goto End_Of_Control_Send;
 
-				while (DataLen && (Pipe_BytesInPipe() < USB_ControlPipeSize))
+				while (DataLen && (Pipe_BytesInPipe() < USB_Host_ControlPipeSize))
 				{
 					Pipe_Write_8(*(DataStream++));
 					DataLen--;
@@ -178,5 +180,96 @@ static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType)
 	return HOST_SENDCONTROL_Successful;
 }
 
+uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
+{
+	uint8_t ErrorCode;
+
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
+			.bRequest      = REQ_SetConfiguration,
+			.wValue        = ConfigNumber,
+			.wIndex        = 0,
+			.wLength       = 0,
+		};
+
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+	
+	if ((ErrorCode = USB_Host_SendControlRequest(NULL)) == HOST_SENDCONTROL_Successful)
+	{
+		USB_Host_ConfigurationNumber = ConfigNumber;
+		USB_HostState                = (ConfigNumber) ? HOST_STATE_Configured : HOST_STATE_Addressed;
+	}
+
+	return ErrorCode;
+}
+
+uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
+{
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
+			.bRequest      = REQ_GetDescriptor,
+			.wValue        = (DTYPE_Device << 8),
+			.wIndex        = 0,
+			.wLength       = sizeof(USB_Descriptor_Device_t),
+		};
+
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	return USB_Host_SendControlRequest(DeviceDescriptorPtr);
+}
+
+uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
+                                           void* const Buffer,
+                                           const uint8_t BufferLength)
+{
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
+			.bRequest      = REQ_GetDescriptor,
+			.wValue        = (DTYPE_String << 8) | Index,
+			.wIndex        = 0,
+			.wLength       = BufferLength,
+		};
+
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	return USB_Host_SendControlRequest(Buffer);
+}
+
+uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
+{
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
+			.bRequest      = REQ_ClearFeature,
+			.wValue        = FEATURE_SEL_EndpointHalt,
+			.wIndex        = EndpointNum,
+			.wLength       = 0,
+		};
+
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	return USB_Host_SendControlRequest(NULL);
+}
+
+uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
+                                        const uint8_t AltSetting)
+{
+	USB_ControlRequest = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
+			.bRequest      = REQ_SetInterface,
+			.wValue        = AltSetting,
+			.wIndex        = InterfaceIndex,
+			.wLength       = 0,
+		};
+
+	Pipe_SelectPipe(PIPE_CONTROLPIPE);
+
+	return USB_Host_SendControlRequest(NULL);
+}
+
 #endif
 
diff --git a/LUFA/Drivers/USB/Core/HostStandardReq.h b/LUFA/Drivers/USB/Core/HostStandardReq.h
index 46822221cae548746e406c1f568e29380186ba93..b74aa3a3eaeb6b806e9397318a6618b2ef541d9d 100644
--- a/LUFA/Drivers/USB/Core/HostStandardReq.h
+++ b/LUFA/Drivers/USB/Core/HostStandardReq.h
@@ -77,6 +77,19 @@
 				HOST_SENDCONTROL_SoftwareTimeOut    = 4, /**< The request or data transfer timed out. */
 			};
 
+		/* Global Variables: */
+			/** Indicates the currently set configuration number of the attached device. This indicates the currently
+			 *  selected configuration value if one has been set sucessfully, or 0 if no configuration has been selected.
+			 *
+			 *  To set a device configuration, call the \ref USB_Host_SetDeviceConfiguration() function.
+			 *
+			 *  \note This variable should be treated as read-only in the user application, and never manually
+			 *        changed in value.
+			 *
+			 *  \ingroup Group_Host
+			 */
+			extern uint8_t USB_Host_ConfigurationNumber;
+			
 		/* Function Prototypes: */
 			/** Sends the request stored in the \ref USB_ControlRequest global structure to the attached device,
 			 *  and transfers the data stored in the buffer to the device, or from the device to the buffer
@@ -91,6 +104,85 @@
 			 */
 			uint8_t USB_Host_SendControlRequest(void* const BufferPtr);
 
+			/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
+			 *  device, with the given configuration index. This can be used to easily set the device
+			 *  configuration without creating and sending the request manually.
+			 *
+			 *  This routine will automatically update the \ref USB_HostState and \ref USB_Host_ConfigurationNumber
+			 *  state variables according to the given function parameters and the result of the request.
+			 *
+			 *  \note After this routine returns, the control pipe will be selected.
+			 *
+			 *  \ingroup Group_PipeControlReq
+			 *
+			 *  \param[in] ConfigNumber  Configuration index to send to the device.
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
+			 */
+			uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
+
+			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
+			 *  device, requesting the device descriptor. This can be used to easily retrieve information
+			 *  about the device such as its VID, PID and power requirements.
+			 *
+			 *  \note After this routine returns, the control pipe will be selected.
+			 *
+			 *  \ingroup Group_PipeControlReq
+			 *
+			 *  \param[out] DeviceDescriptorPtr  Pointer to the destination device descriptor structure where
+			 *                                   the read data is to be stored.
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
+			 */
+			uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
+
+			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
+			 *  device, requesting the string descriptor of the specified index. This can be used to easily
+			 *  retrieve string descriptors from the device by index, after the index is obtained from the
+			 *  Device or Configuration descriptors.
+			 *
+			 *  \note After this routine returns, the control pipe will be selected.
+			 *
+			 *  \ingroup Group_PipeControlReq
+			 *
+			 *  \param[in]  Index        Index of the string index to retrieve.
+			 *  \param[out] Buffer       Pointer to the destination buffer where the retrieved string descriptor is
+			 *                           to be stored.
+			 *  \param[in] BufferLength  Maximum size of the string descriptor which can be stored into the buffer.
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
+			 */
+			uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
+			                                           void* const Buffer,
+			                                           const uint8_t BufferLength);
+
+			/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
+			 *
+			 *  \note After this routine returns, the control pipe will be selected.
+			 *
+			 *  \ingroup Group_PipeControlReq
+			 *
+			 *  \param[in] EndpointIndex  Index of the endpoint to clear, including the endpoint's direction.
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
+			 */
+			uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
+
+			/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
+			 *  the attached device.
+			 *
+			 *  \note After this routine returns, the control pipe will be selected.
+			 *
+			 *  \ingroup Group_PipeControlReq
+			 *
+			 *  \param[in] InterfaceIndex  Index of the interface whose alternative setting is to be altered.
+			 *  \param[in] AltSetting      Index of the interface's alternative setting which is to be selected.
+			 *
+			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
+			 */
+			uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
+													const uint8_t AltSetting);
+
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Enums: */
diff --git a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
index f5a89221f1fee5497ebfb6576db29ce0efe36108..5ed86612bd92f512658533181ea35fd2dcb7ab4e 100644
--- a/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/Device_UC3.h
@@ -122,8 +122,8 @@
 			 *  \note This macro should only be used if the device has indicated to the host that it
 			 *        supports the Remote Wakeup feature in the device descriptors, and should only be
 			 *        issued if the host is currently allowing remote wakeup events from the device (i.e.,
-			 *        the \ref USB_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP compile
-			 *        time option is used, this macro is unavailable.
+			 *        the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP
+			 *        compile time option is used, this macro is unavailable.
 			 *        \n\n
 			 *
 			 *  \note The USB clock must be running for this function to operate. If the stack is initialized with
diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c
index 9c7d6b62d4664feacd033b1910bb28849874bfee..3337c7d5ccf1a9debedb7302077150f6bf93e779 100644
--- a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c
@@ -36,7 +36,7 @@
 #include "../Endpoint.h"
 
 #if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
-uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
+uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
 #endif
 
 volatile uint32_t USB_SelectedEndpoint = ENDPOINT_CONTROLEP;
diff --git a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h
index 98067e63559e52b63d5b9d3adc965dfbf8524ffe..2ed7b5d806215ccc791115fe8594269c05394bf9 100644
--- a/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h
@@ -830,9 +830,9 @@
 			 *        changed in value.
 			 */
 			#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
-				extern uint8_t USB_ControlEndpointSize;
+				extern uint8_t USB_Device_ControlEndpointSize;
 			#else
-				#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
+				#define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
 			#endif
 
 		/* Function Prototypes: */
diff --git a/LUFA/Drivers/USB/Core/UC3/Host_UC3.c b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
index 1dd2b578be2c4b53107a263d418167a658f26acb..a56ef48193176afae86cacea92b3102baae81b5b 100644
--- a/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/Host_UC3.c
@@ -137,7 +137,7 @@ void USB_Host_ProcessNextHostState(void)
 				break;
 			}
 
-			USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
+			USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
 
 			USB_Host_ResetDevice();
 
@@ -146,7 +146,7 @@ void USB_Host_ProcessNextHostState(void)
 		case HOST_STATE_Default_PostReset:
 			Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
 			                   PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
-			                   USB_ControlPipeSize, PIPE_BANK_SINGLE);
+			                   USB_Host_ControlPipeSize, PIPE_BANK_SINGLE);
 
 			if (!(Pipe_IsConfigured()))
 			{
@@ -175,8 +175,9 @@ void USB_Host_ProcessNextHostState(void)
 		case HOST_STATE_Default_PostAddressSet:
 			USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
 
-			EVENT_USB_Host_DeviceEnumerationComplete();
 			USB_HostState = HOST_STATE_Addressed;
+
+			EVENT_USB_Host_DeviceEnumerationComplete();
 			break;
 	}
 
@@ -253,6 +254,8 @@ static void USB_Host_ResetDevice(void)
 	USB_Host_ResetBus();
 	while (!(USB_Host_IsBusResetComplete()));
 	USB_Host_ResumeBus();
+	
+	USB_Host_ConfigurationNumber = 0;
 
 	bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
 
@@ -285,88 +288,5 @@ static void USB_Host_ResetDevice(void)
 	USB_INT_Enable(USB_INT_DDISCI);
 }
 
-uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_SetConfiguration,
-			.wValue        = ConfigNumber,
-			.wIndex        = 0,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
-uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_GetDescriptor,
-			.wValue        = (DTYPE_Device << 8),
-			.wIndex        = 0,
-			.wLength       = sizeof(USB_Descriptor_Device_t),
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(DeviceDescriptorPtr);
-}
-
-uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
-                                           void* const Buffer,
-                                           const uint8_t BufferLength)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
-			.bRequest      = REQ_GetDescriptor,
-			.wValue        = (DTYPE_String << 8) | Index,
-			.wIndex        = 0,
-			.wLength       = BufferLength,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(Buffer);
-}
-
-uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
-			.bRequest      = REQ_ClearFeature,
-			.wValue        = FEATURE_SEL_EndpointHalt,
-			.wIndex        = EndpointNum,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
-uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
-                                        const uint8_t AltSetting)
-{
-	USB_ControlRequest = (USB_Request_Header_t)
-		{
-			.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
-			.bRequest      = REQ_SetInterface,
-			.wValue        = AltSetting,
-			.wIndex        = InterfaceIndex,
-			.wLength       = 0,
-		};
-
-	Pipe_SelectPipe(PIPE_CONTROLPIPE);
-
-	return USB_Host_SendControlRequest(NULL);
-}
-
 #endif
 
diff --git a/LUFA/Drivers/USB/Core/UC3/Host_UC3.h b/LUFA/Drivers/USB/Core/UC3/Host_UC3.h
index 7fd46a3139d9a7fc951ca8fcacec98e092e7703a..4bcba566bb8e551e3d28e1708654c12d2caae5c9 100644
--- a/LUFA/Drivers/USB/Core/UC3/Host_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/Host_UC3.h
@@ -208,6 +208,9 @@
 			/** Suspends the USB bus, preventing any communications from occurring between the host and attached
 			 *  device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
 			 *  messages to the device.
+			 *
+			 *  \note While the USB bus is suspended, all USB interrupt sources are also disabled; this means that
+			 *        some events (such as device disconnections) will not fire until the bus is resumed.
 			 */
 			static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
 			static inline void USB_Host_SuspendBus(void)
@@ -277,73 +280,6 @@
 				return AVR32_USBB.UHCON.resume;
 			}
 
-		/* Function Prototypes: */
-			/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
-			 *  device, with the given configuration index. This can be used to easily set the device
-			 *  configuration without creating and sending the request manually.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] ConfigNumber  Configuration index to send to the device.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
-
-			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
-			 *  device, requesting the device descriptor. This can be used to easily retrieve information
-			 *  about the device such as its VID, PID and power requirements.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[out] DeviceDescriptorPtr  Pointer to the destination device descriptor structure where
-			 *                                   the read data is to be stored.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
-
-			/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
-			 *  device, requesting the string descriptor of the specified index. This can be used to easily
-			 *  retrieve string descriptors from the device by index, after the index is obtained from the
-			 *  Device or Configuration descriptors.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in]  Index        Index of the string index to retrieve.
-			 *  \param[out] Buffer       Pointer to the destination buffer where the retrieved string descriptor is
-			 *                           to be stored.
-			 *  \param[in] BufferLength  Maximum size of the string descriptor which can be stored into the buffer.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
-			                                           void* const Buffer,
-			                                           const uint8_t BufferLength);
-
-			/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] EndpointIndex  Index of the endpoint to clear, including the endpoint's direction.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
-
-			/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
-			 *  the attached device.
-			 *
-			 *  \note After this routine returns, the control pipe will be selected.
-			 *
-			 *  \param[in] InterfaceIndex  Index of the interface whose alternative setting is to be altered.
-			 *  \param[in] AltSetting      Index of the interface's alternative setting which is to be selected.
-			 *
-			 *  \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
-			 */
-			uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
-													const uint8_t AltSetting);
-
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
 		/* Macros: */
diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c
index 4e67f9691f61b5a3d5076174bcf41d27e740fea0..83d3fd6adf42c5e8883150b2f876f05b8fe63d27 100644
--- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c
@@ -35,7 +35,7 @@
 
 #include "../Pipe.h"
 
-uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
+uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
 
 volatile uint32_t USB_SelectedPipe = PIPE_CONTROLPIPE;
 volatile uint8_t* USB_PipeFIFOPos[PIPE_TOTAL_PIPES];
diff --git a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h
index 2444a2c63afa8dfb647f7d42e64fb4e1c4142dd6..c9f9eaac2a8f4de2100dcff7d5d9f77c91d9408e 100644
--- a/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h
+++ b/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h
@@ -804,7 +804,7 @@
 			 *  \note This variable should be treated as read-only in the user application, and never manually
 			 *        changed in value.
 			 */
-			extern uint8_t USB_ControlPipeSize;
+			extern uint8_t USB_Host_ControlPipeSize;
 
 		/* Function Prototypes: */
 			/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
diff --git a/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c b/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c
index 1d6361fb824ea44f557812b8ed43898766c51c55..5d4fc42f2a2482f972adeabe990d63c04bb6fca6 100644
--- a/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c
+++ b/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c
@@ -58,7 +58,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 		{
 			uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint();
 
-			while (Length && (BytesInEndpoint < USB_ControlEndpointSize))
+			while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize))
 			{
 				TEMPLATE_TRANSFER_BYTE(DataStream);
 				TEMPLATE_BUFFER_MOVE(DataStream, 1);
@@ -66,7 +66,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
 				BytesInEndpoint++;
 			}
 
-			LastPacketFull = (BytesInEndpoint == USB_ControlEndpointSize);
+			LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize);
 			Endpoint_ClearIN();
 		}
 	}
diff --git a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c
index 0b0d04d63adfb55a461410cc9bfe07e27f8a9718..7cfa28ededb8389bd949d9278b54db8143c0dd57 100644
--- a/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c
@@ -147,22 +147,22 @@ void USB_ResetInterface(void)
 #if defined(USB_CAN_BE_DEVICE)
 static void USB_Init_Device(void)
 {
-	USB_DeviceState          = DEVICE_STATE_Unattached;
-	USB_ConfigurationNumber  = 0;
+	USB_DeviceState                 = DEVICE_STATE_Unattached;
+	USB_Device_ConfigurationNumber  = 0;
 
 	#if !defined(NO_DEVICE_REMOTE_WAKEUP)
-	USB_RemoteWakeupEnabled  = false;
+	USB_Device_RemoteWakeupEnabled  = false;
 	#endif
 
 	#if !defined(NO_DEVICE_SELF_POWER)
-	USB_CurrentlySelfPowered = false;
+	USB_Device_CurrentlySelfPowered = false;
 	#endif
 
 	#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
 	USB_Descriptor_Device_t* DeviceDescriptorPtr;
 
 	if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
-	  USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
+	  USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
 	#endif
 
 	if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
@@ -173,7 +173,7 @@ static void USB_Init_Device(void)
 	USB_INT_Enable(USB_INT_VBUSTI);
 
 	Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
-							   ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
+							   ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
 							   ENDPOINT_BANK_SINGLE);
 
 	USB_INT_Clear(USB_INT_SUSPI);
@@ -187,8 +187,9 @@ static void USB_Init_Device(void)
 #if defined(USB_CAN_BE_HOST)
 static void USB_Init_Host(void)
 {
-	USB_HostState       = HOST_STATE_Unattached;
-	USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
+	USB_HostState                = HOST_STATE_Unattached;
+	USB_Host_ConfigurationNumber = 0;
+	USB_Host_ControlPipeSize     = PIPE_CONTROLPIPE_DEFAULT_SIZE;
 
 	USB_Host_HostMode_On();
 
diff --git a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
index 5191ee67f0aab8e93650edcbac75fee312df07d0..7a9c148856d3b8c1a78ef5a214fd5fa0628a6682 100644
--- a/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
+++ b/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c
@@ -97,7 +97,7 @@ ISR(USB_GEN_vect)
 		USB_INT_Disable(USB_INT_WAKEUPI);
 		USB_INT_Enable(USB_INT_SUSPI);
 
-		if (USB_ConfigurationNumber)
+		if (USB_Device_ConfigurationNumber)
 		  USB_DeviceState = DEVICE_STATE_Configured;
 		else
 		  USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
@@ -109,8 +109,8 @@ ISR(USB_GEN_vect)
 	{
 		USB_INT_Clear(USB_INT_EORSTI);
 
-		USB_DeviceState         = DEVICE_STATE_Default;
-		USB_ConfigurationNumber = 0;
+		USB_DeviceState                = DEVICE_STATE_Default;
+		USB_Device_ConfigurationNumber = 0;
 
 		USB_INT_Clear(USB_INT_SUSPI);
 		USB_INT_Disable(USB_INT_SUSPI);
@@ -118,7 +118,7 @@ ISR(USB_GEN_vect)
 
 		USB_Device_SetDeviceAddress(0);
 		Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
-		                           ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
+		                           ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
 		                           ENDPOINT_BANK_SINGLE);
 
 		EVENT_USB_Device_Reset();
diff --git a/LUFA/Drivers/USB/Core/USBTask.h b/LUFA/Drivers/USB/Core/USBTask.h
index 30231bf16ce5e5279d52ea591421167710d959aa..586ce6ed2a920ec994a1d3102070c7d5254c30f2 100644
--- a/LUFA/Drivers/USB/Core/USBTask.h
+++ b/LUFA/Drivers/USB/Core/USBTask.h
@@ -93,9 +93,8 @@
 					/** 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.
 					 *
-					 *  This value may be altered by the user application to implement the \ref HOST_STATE_Addressed,
-					 *  \ref HOST_STATE_Configured and \ref HOST_STATE_Suspended states which are not implemented by
-					 *  the library internally.
+					 *  This value should not be altered by the user application as it is handled automatically by the
+					 *  library.
 					 *
 					 *  To reduce program size and speed up checks of this global on the AVR8 architecture, it can be
 					 *  placed into one of the AVR's \c GPIOR hardware registers instead of RAM by defining the
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 9b473114f485551ffa5954f4a4771b03a3f605bd..74bbbc2eb5be0159601688a2afc4d68c7949322e 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -23,6 +23,7 @@
   *   - Added board hardware driver support for the EVK1100 board
   *   - Added board hardware driver support for the EVK1104 board
   *   - Added new HID_Host_SetIdlePeriod() function to the HID Host Class driver
+  *   - Added new USB_Host_ConfigurationNumber global variable to indicate the selected configuration in an attached device
   *  - Library Applications:
   *   - Added RNDIS device mode to the Webserver project
   *   - Added new incomplete AndroidAccessoryHost Host LowLevel demo
@@ -41,8 +42,14 @@
   *     continuous sample rates
   *   - Pipe_BoundEndpointNumber() has been renamed to Pipe_GetBoundEndpointAddress(), and now returns the correct endpoint direction
   *     as part of the endpoint address
+  *   - Renamed global state variables that are specific to a certain USB mode to clearly indicate which mode the variable relates to,
+  *     by changing the USB_* prefix to USB_Device_* or USB_Host_*
+  *   - Removed the HOST_STATE_WaitForDeviceRemoval and HOST_STATE_Suspended host state machine states, as these are no longer required
+  *   - Altered the USB_Host_SetDeviceConfiguration() function to update the new USB_Host_ConfigurationNumber global as required
   *  - Library Applications:
   *   - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates
+  *   - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration
+  *     instead of manual host state machine manipulations in the main application task
   *
   *  <b>Fixed:</b>
   *  - Core:
diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt
index 2d067ba6314357f29423c0d39d588ef7c646bd56..c640b10b5e8eeed51c0d6a3876cace73853f66a2 100644
--- a/LUFA/ManPages/CompileTimeTokens.txt
+++ b/LUFA/ManPages/CompileTimeTokens.txt
@@ -179,8 +179,8 @@
  *
  *  <b>NO_DEVICE_SELF_POWER</b> - (\ref Group_Device) - <i>All Architectures</i> \n
  *  USB devices may be bus powered, self powered, or a combination of both. When a device can be both bus powered and self powered, the host may
- *  query the device to determine the current power source, via \ref USB_CurrentlySelfPowered. For solely bus powered devices, this global and the
- *  code required to manage it may be disabled by passing this token to the library via the -D switch.
+ *  query the device to determine the current power source, via \ref USB_Device_CurrentlySelfPowered. For solely bus powered devices, this global
+ *  and the code required to manage it may be disabled by passing this token to the library via the -D switch.
  *
  *
  *  \section Sec_SummaryUSBHostTokens USB Host Mode Driver Related Tokens
diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt
index be3de49d227cac8b1a3cc9a3bc36a6aa094a3990..8f7e98ceddc30ab4fdd6f24fb86d27b9774f3bc6 100644
--- a/LUFA/ManPages/FutureChanges.txt
+++ b/LUFA/ManPages/FutureChanges.txt
@@ -24,7 +24,8 @@
   *      -# Abstract out Mass Storage byte send/receive to prevent low level API use in projects
   *      -# Consider switch from endpoint numbers to full endpoint addresses to ease future architecture expansion
   *      -# Fix HID report parser usage support for array types
-  *      -# Remove need for direct user Host State Machine interaction in the Host mode applications
+  *      -# Mass Storage Host demo incompatibilities with some devices
+  *      -# Add additional standard request helper functions to host mode
   *  - Documentation/Support
   *      -# Add detailed overviews of how each demo works
   *      -# Add board overviews
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index 390dd88469b66cb049d53b59cc402f9724944d13..d5f680eef94bd3abc5b385b89ef33254e7f5bc4c 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -20,6 +20,19 @@
  *    - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetEndpointProperty().
  *      Existing applications must implement this new callback, however if multiple sample rates or pitch control is not used,
  *      this function may be hard-coded to always return false for previous behaviour to be retained.
+ *    - The \c USB_ConfigurationNumber, \c USB_RemoteWakeupEnabled and \c USB_CurrentlySelfPowered globals have been renamed to
+ *      \ref USB_Device_ConfigurationNumber, \ref USB_Device_RemoteWakeupEnabled and \ref USB_Device_CurrentlySelfPowered to clearly indicate
+ *      the USB mode they relate to. Existing applications using these variables should rename all references to the previous names.
+ *
+ *  <b>Host Mode</b>
+ *    - The USB_Host_SetDeviceConfiguration() function now automatically sets the USB Host state machine to the \ref HOST_STATE_Configured
+ *      state if a non-zero configuration is set sucessfully, or the \ref HOST_STATE_Addressed if a zero-index configuration is specified. Existing
+ *      applications should no longer manually alter the \ref USB_HostState global, and should instead call this function to configure and
+ *      unconfigure an attached device.
+ *    - The \c HOST_STATE_WaitForDeviceRemoval and \c HOST_STATE_Suspended host state machine states have been removed; these are replaced by
+ *      unconfiguring the attached device via a call to \ref USB_Host_SetDeviceConfiguration() and a test of \ref USB_Host_IsBusSuspended() instead.
+ *    - It is highly recommended that the EVENT_USB_Host_DeviceEnumerationComplete() event callback now be used for initial device configuration,
+ *      rather than a switch on the USB host state machine state for readability.
  *
  *  \section Sec_Migration110528 Migrating from 101122 to 110528
  *  <b>Non-USB Library Components</b>
diff --git a/Projects/HIDReportViewer/HIDReportViewer.c b/Projects/HIDReportViewer/HIDReportViewer.c
index 49f81f2a64c98d9cfd78056f429a2098a7420d69..c7a73e761d2fb04bc077fa9bf5b2bf4dd9d5d32f 100644
--- a/Projects/HIDReportViewer/HIDReportViewer.c
+++ b/Projects/HIDReportViewer/HIDReportViewer.c
@@ -74,68 +74,30 @@ int main(void)
 
 	for (;;)
 	{
-		switch (USB_HostState)
-		{
-			case HOST_STATE_Addressed:
-				LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-				uint16_t ConfigDescriptorSize;
-				uint8_t  ConfigDescriptorData[512];
-
-				if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-				                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-				{
-					puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_ConfigurePipes(&Device_HID_Interface,
-				                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
-				{
-					puts_P(PSTR("Attached Device Not a Valid HID Device.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-				{
-					puts_P(PSTR("Error Setting Device Configuration.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				if (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
-				{
-					puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
-					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-					USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-					break;
-				}
-
-				puts_P(PSTR("HID Device Enumerated.\r\n"));
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_Configured;
-				break;
-			case HOST_STATE_Configured:
-				LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
-				
-				OutputReportSizes();
-				OutputParsedReportItems();
-				
-				LEDs_SetAllLEDs(LEDMASK_USB_READY);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-		}
-
+		RetrieveDeviceData();
+		
 		HID_Host_USBTask(&Device_HID_Interface);
 		USB_USBTask();
 	}
 }
 
+/** Task to retrieve the HID device information from an attached device, and output
+ *  the relevant data to the serial port for analysis.
+ */
+void RetrieveDeviceData(void)
+{
+	if (USB_CurrentMode != USB_MODE_Host)
+	  return;
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+	
+	OutputReportSizes();
+	OutputParsedReportItems();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	USB_Host_SetDeviceConfiguration(0);
+}
+
 /** Prints a summary of the device's HID report sizes from the HID parser output to the serial port
  *  for display to the user.
  */
@@ -276,6 +238,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_ConfigurePipes(&Device_HID_Interface,
+	                            ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
+	{
+		puts_P(PSTR("Attached Device Not a Valid HID Device.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		puts_P(PSTR("Error Setting Device Configuration.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
+	{
+		puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		USB_Host_SetDeviceConfiguration(0);
+		return;
+	}
+
+	puts_P(PSTR("HID Device Enumerated.\r\n"));
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
diff --git a/Projects/HIDReportViewer/HIDReportViewer.h b/Projects/HIDReportViewer/HIDReportViewer.h
index ff2512b90d37f9af587d619f6efd82e41aa331ce..ea8b6b93828743bb4b5f140ddc5318ae10043863 100644
--- a/Projects/HIDReportViewer/HIDReportViewer.h
+++ b/Projects/HIDReportViewer/HIDReportViewer.h
@@ -69,6 +69,7 @@
 
 	/* Function Prototypes: */
 		void SetupHardware(void);
+		void RetrieveDeviceData(void);
 		void OutputReportSizes(void);
 		void OutputParsedReportItems(void);
 		void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath);
diff --git a/Projects/MissileLauncher/MissileLauncher.c b/Projects/MissileLauncher/MissileLauncher.c
index 6a98b54596360b16578f4cf7e9b0d4d2b6b8cf9c..e143bec72ce7c634c847d653130e271fa54db53c 100644
--- a/Projects/MissileLauncher/MissileLauncher.c
+++ b/Projects/MissileLauncher/MissileLauncher.c
@@ -103,8 +103,8 @@ int main(void)
 	for (;;)
 	{
 		Read_Joystick_Status();
-
-		HID_Host_Task();
+		DiscardNextReport();
+		
 		USB_USBTask();
 	}
 }
@@ -198,6 +198,22 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	/* Get and process the configuration descriptor data */
+	if (ProcessConfigurationDescriptor() != SuccessfulConfigRead)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
@@ -222,6 +238,9 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
 /** Reads in and discards the next report from the attached device. */
 void DiscardNextReport(void)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	/* Select and unfreeze HID data IN pipe */
 	Pipe_SelectPipe(HID_DATA_IN_PIPE);
 	Pipe_Unfreeze();
@@ -250,6 +269,9 @@ void DiscardNextReport(void)
 void WriteNextReport(uint8_t* const ReportOUTData,
                      const uint16_t ReportLength)
 {
+	if (USB_HostState != HOST_STATE_Configured)
+	  return;
+
 	/* Select and unfreeze HID data OUT pipe */
 	Pipe_SelectPipe(HID_DATA_OUT_PIPE);
 
@@ -297,45 +319,3 @@ void WriteNextReport(uint8_t* const ReportOUTData,
 	}
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
- *  HID reports from the device and to send reports if desired.
- */
-void HID_Host_Task(void)
-{
-	uint8_t ErrorCode;
-
-	/* Switch to determine what user-application handled host state the host state machine is in */
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			/* Get and process the configuration descriptor data */
-			if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
-			{
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
-			if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
-			{
-				/* Indicate error status */
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-				/* Wait until USB device disconnected */
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			DiscardNextReport();
-
-			break;
-	}
-}
-
diff --git a/Projects/MissileLauncher/MissileLauncher.h b/Projects/MissileLauncher/MissileLauncher.h
index 7363f0fabc416688cf6b126403b1bb1e9551440c..0cdd1a2f813424557841f382c9619fcd080ba507 100644
--- a/Projects/MissileLauncher/MissileLauncher.h
+++ b/Projects/MissileLauncher/MissileLauncher.h
@@ -77,8 +77,6 @@
 		                         const uint16_t ReportSize);
         void Send_Command(const uint8_t* const Command);
 
-		void HID_Host_Task(void);
-
 		void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
 		void EVENT_USB_Host_DeviceAttached(void);
 		void EVENT_USB_Host_DeviceUnattached(void);
diff --git a/Projects/Webserver/Lib/uIPManagement.c b/Projects/Webserver/Lib/uIPManagement.c
index c0ffcd4a32422f4e07359bf50b99303a35af9083..5e0a3082e428bda1af758bc9745428ef211e69e4 100644
--- a/Projects/Webserver/Lib/uIPManagement.c
+++ b/Projects/Webserver/Lib/uIPManagement.c
@@ -113,7 +113,7 @@ void uIPManagement_Init(void)
  */
 void uIPManagement_ManageNetwork(void)
 {
-	if (((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) ||
+	if (((USB_CurrentMode == USB_MODE_Host)   && (USB_HostState   == HOST_STATE_Configured)) ||
 	    ((USB_CurrentMode == USB_MODE_Device) && (USB_DeviceState == DEVICE_STATE_Configured)))
 	{
 		uIPManagement_ProcessIncomingPacket();
diff --git a/Projects/Webserver/USBHostMode.c b/Projects/Webserver/USBHostMode.c
index 1fcec3491b14e2c1b76a13e0cd868276ab76c472..98467a1bb5f94e639811fad136fbf17397ea127f 100644
--- a/Projects/Webserver/USBHostMode.c
+++ b/Projects/Webserver/USBHostMode.c
@@ -66,73 +66,8 @@ void USBHostMode_USBTask(void)
 	if (USB_CurrentMode != USB_MODE_Host)
 	  return;
 
-	switch (USB_HostState)
-	{
-		case HOST_STATE_Addressed:
-			LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-
-			uint16_t ConfigDescriptorSize;
-			uint8_t  ConfigDescriptorData[512];
-
-			if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
-												   sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
-										  ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
-			if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
-											&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
-											  &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
-			{
-				LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-				break;
-			}
-
-			/* Initialize uIP stack */
-			uIPManagement_Init();
-
-			LEDs_SetAllLEDs(LEDMASK_USB_READY);
-			USB_HostState = HOST_STATE_Configured;
-			break;
-		case HOST_STATE_Configured:
-			uIPManagement_ManageNetwork();
-
-			break;
-	}
-
+	uIPManagement_ManageNetwork();
+	
 	RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface_Host);
 }
 
@@ -157,6 +92,55 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+
+	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+
+	if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+	                                       sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
+	                              ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
+	if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
+	                                &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
+	                                  &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
+	{
+		LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+		return;
+	}
+
+	/* Initialize uIP stack */
+	uIPManagement_Init();
+
 	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }