From d1e52660368d34d693131f6aff3c8fd8584162e5 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Mon, 1 Jun 2009 11:03:39 +0000
Subject: [PATCH] Commit of new class abstraction APIs for all device demos
 other than the MIDI demo - not documented yet.

Removed scheduler and memory allocation libraries.

Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated).

Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt.
---
 Bootloaders/CDC/makefile                      |   1 -
 Bootloaders/DFU/makefile                      |   1 -
 Bootloaders/TeensyHID/makefile                |   1 -
 Demos/Device/AudioInput/AudioInput.c          | 188 ++------
 Demos/Device/AudioInput/AudioInput.h          |  36 +-
 Demos/Device/AudioInput/makefile              |   3 +-
 Demos/Device/AudioOutput/AudioOutput.c        | 277 ++++-------
 Demos/Device/AudioOutput/AudioOutput.h        |  33 +-
 Demos/Device/AudioOutput/makefile             |   5 +-
 Demos/Device/CDC/CDC.c                        | 317 +++---------
 Demos/Device/CDC/CDC.h                        | 139 +-----
 Demos/Device/CDC/Descriptors.h                |  22 +-
 Demos/Device/CDC/makefile                     |   5 +-
 Demos/Device/DualCDC/Descriptors.h            |  20 +-
 Demos/Device/DualCDC/DualCDC.c                | 370 ++++----------
 Demos/Device/DualCDC/DualCDC.h                |  75 +--
 Demos/Device/DualCDC/makefile                 |   5 +-
 Demos/Device/GenericHID/Descriptors.h         |  32 +-
 Demos/Device/GenericHID/GenericHID.c          | 243 ++--------
 Demos/Device/GenericHID/GenericHID.h          |  40 +-
 Demos/Device/GenericHID/makefile              |   5 +-
 Demos/Device/Joystick/Descriptors.h           |  30 +-
 Demos/Device/Joystick/Joystick.c              | 211 ++------
 Demos/Device/Joystick/Joystick.h              |  40 +-
 Demos/Device/Joystick/makefile                |   5 +-
 Demos/Device/Keyboard/Descriptors.h           |  30 +-
 Demos/Device/Keyboard/Keyboard.c              | 437 +++--------------
 Demos/Device/Keyboard/Keyboard.h              |  60 +--
 Demos/Device/Keyboard/makefile                |   5 +-
 Demos/Device/KeyboardMouse/Descriptors.h      |  30 +-
 Demos/Device/KeyboardMouse/KeyboardMouse.c    | 353 ++++----------
 Demos/Device/KeyboardMouse/KeyboardMouse.h    |  47 +-
 Demos/Device/KeyboardMouse/makefile           |   5 +-
 Demos/Device/MIDI/makefile                    |   2 +-
 .../Device/MassStorage/Lib/DataflashManager.c |  18 +-
 .../Device/MassStorage/Lib/DataflashManager.h |   4 +-
 Demos/Device/MassStorage/Lib/SCSI.c           | 116 ++---
 Demos/Device/MassStorage/Lib/SCSI.h           |  25 +-
 Demos/Device/MassStorage/MassStorage.c        | 331 ++-----------
 Demos/Device/MassStorage/MassStorage.h        | 103 +---
 Demos/Device/MassStorage/makefile             |   4 +-
 Demos/Device/Mouse/Descriptors.h              |  30 +-
 Demos/Device/Mouse/Mouse.c                    | 309 ++----------
 Demos/Device/Mouse/Mouse.h                    |  58 +--
 Demos/Device/Mouse/makefile                   |   5 +-
 Demos/Device/RNDISEthernet/Lib/ARP.h          |   4 +-
 Demos/Device/RNDISEthernet/Lib/Ethernet.c     |  32 +-
 Demos/Device/RNDISEthernet/Lib/Ethernet.h     |  24 +-
 .../RNDISEthernet/Lib/EthernetProtocols.h     |   8 +-
 Demos/Device/RNDISEthernet/Lib/ICMP.c         |   4 +-
 Demos/Device/RNDISEthernet/Lib/ICMP.h         |   2 +-
 Demos/Device/RNDISEthernet/Lib/IP.c           |   5 +-
 Demos/Device/RNDISEthernet/Lib/IP.h           |   2 +-
 Demos/Device/RNDISEthernet/Lib/RNDIS.c        | 394 ---------------
 Demos/Device/RNDISEthernet/Lib/TCP.c          |  22 +-
 Demos/Device/RNDISEthernet/Lib/TCP.h          |   8 +-
 Demos/Device/RNDISEthernet/RNDISEthernet.c    | 322 ++-----------
 Demos/Device/RNDISEthernet/RNDISEthernet.h    |  56 +--
 Demos/Device/RNDISEthernet/makefile           |   6 +-
 Demos/Device/USBtoSerial/Descriptors.h        |  20 +-
 Demos/Device/USBtoSerial/USBtoSerial.c        | 346 +++----------
 Demos/Device/USBtoSerial/USBtoSerial.h        | 142 +-----
 Demos/Device/USBtoSerial/makefile             |   5 +-
 Demos/Host/GenericHIDHost/makefile            |   2 +-
 .../MassStorageHost/Lib/MassStoreCommands.c   |   4 +-
 .../StillImageHost/Lib/StillImageCommands.c   |   4 +-
 Demos/OTG/TestApp/TestApp.h                   |   1 -
 Demos/OTG/TestApp/makefile                    |   3 -
 LUFA.pnproj                                   |   2 +-
 LUFA/ChangeLog.txt                            |  10 +
 LUFA/DirectorySummaries.txt                   |  13 -
 LUFA/Drivers/USB/Class/Device/Audio.c         | 154 ++++++
 LUFA/Drivers/USB/Class/Device/Audio.h         |  70 +++
 LUFA/Drivers/USB/Class/Device/CDC.c           | 185 +++++++
 LUFA/Drivers/USB/Class/Device/CDC.h           | 188 ++++++++
 LUFA/Drivers/USB/Class/Device/HID.c           | 211 ++++++++
 LUFA/Drivers/USB/Class/Device/HID.h           | 115 +++++
 LUFA/Drivers/USB/Class/Device/MassStorage.c   | 208 ++++++++
 LUFA/Drivers/USB/Class/Device/MassStorage.h   | 127 +++++
 LUFA/Drivers/USB/Class/Device/RNDIS.c         | 456 ++++++++++++++++++
 .../Drivers/USB/Class/Device}/RNDIS.h         |  94 ++--
 .../USB/Class/Device}/RNDISConstants.h        |   0
 LUFA/Drivers/USB/Class/{ => Host}/HIDParser.c |   0
 LUFA/Drivers/USB/Class/{ => Host}/HIDParser.h |   2 +-
 .../USB/Class/{ => Host}/HIDReportData.h      |   0
 LUFA/Drivers/USB/HighLevel/Events.h           |   6 +
 LUFA/Drivers/USB/HighLevel/USBInterrupt.c     |  18 +
 LUFA/Drivers/USB/HighLevel/USBTask.c          |   2 +-
 LUFA/Drivers/USB/HighLevel/USBTask.h          |   7 +-
 LUFA/Drivers/USB/LowLevel/Endpoint.c          |   6 +-
 LUFA/Drivers/USB/LowLevel/Host.c              |  12 +-
 LUFA/Drivers/USB/LowLevel/LowLevel.c          |   8 +
 LUFA/Drivers/USB/LowLevel/LowLevel.h          |   3 +
 LUFA/Drivers/USB/LowLevel/Pipe.c              |   6 +-
 LUFA/Drivers/USB/USB.h                        |   2 -
 LUFA/MemoryAllocator/DynAlloc.c               | 226 ---------
 LUFA/MemoryAllocator/DynAlloc.h               | 198 --------
 LUFA/Scheduler/Scheduler.c                    |  95 ----
 LUFA/Scheduler/Scheduler.h                    | 285 -----------
 LUFA/SchedulerOverview.txt                    |  31 --
 LUFA/makefile                                 |   6 +-
 Projects/Magstripe/Descriptors.c              |   2 +-
 Projects/Magstripe/Descriptors.h              |  36 +-
 Projects/Magstripe/Magstripe.c                | 422 ++++------------
 Projects/Magstripe/Magstripe.h                |  47 +-
 Projects/Magstripe/makefile                   |   3 +-
 106 files changed, 3030 insertions(+), 5718 deletions(-)
 delete mode 100644 Demos/Device/RNDISEthernet/Lib/RNDIS.c
 create mode 100644 LUFA/Drivers/USB/Class/Device/Audio.c
 create mode 100644 LUFA/Drivers/USB/Class/Device/Audio.h
 create mode 100644 LUFA/Drivers/USB/Class/Device/CDC.c
 create mode 100644 LUFA/Drivers/USB/Class/Device/CDC.h
 create mode 100644 LUFA/Drivers/USB/Class/Device/HID.c
 create mode 100644 LUFA/Drivers/USB/Class/Device/HID.h
 create mode 100644 LUFA/Drivers/USB/Class/Device/MassStorage.c
 create mode 100644 LUFA/Drivers/USB/Class/Device/MassStorage.h
 create mode 100644 LUFA/Drivers/USB/Class/Device/RNDIS.c
 rename {Demos/Device/RNDISEthernet/Lib => LUFA/Drivers/USB/Class/Device}/RNDIS.h (65%)
 rename {Demos/Device/RNDISEthernet/Lib => LUFA/Drivers/USB/Class/Device}/RNDISConstants.h (100%)
 rename LUFA/Drivers/USB/Class/{ => Host}/HIDParser.c (100%)
 rename LUFA/Drivers/USB/Class/{ => Host}/HIDParser.h (97%)
 rename LUFA/Drivers/USB/Class/{ => Host}/HIDReportData.h (100%)
 delete mode 100644 LUFA/MemoryAllocator/DynAlloc.c
 delete mode 100644 LUFA/MemoryAllocator/DynAlloc.h
 delete mode 100644 LUFA/Scheduler/Scheduler.c
 delete mode 100644 LUFA/Scheduler/Scheduler.h
 delete mode 100644 LUFA/SchedulerOverview.txt

diff --git a/Bootloaders/CDC/makefile b/Bootloaders/CDC/makefile
index bc8e2ca1a..e3d8e5c51 100644
--- a/Bootloaders/CDC/makefile
+++ b/Bootloaders/CDC/makefile
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Bootloaders/DFU/makefile b/Bootloaders/DFU/makefile
index 4e51e299c..b3eb1b0a1 100644
--- a/Bootloaders/DFU/makefile
+++ b/Bootloaders/DFU/makefile
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
 
  
 # List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Bootloaders/TeensyHID/makefile b/Bootloaders/TeensyHID/makefile
index de929edfb..68b016022 100644
--- a/Bootloaders/TeensyHID/makefile
+++ b/Bootloaders/TeensyHID/makefile
@@ -124,7 +124,6 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Device/AudioInput/AudioInput.c b/Demos/Device/AudioInput/AudioInput.c
index ecd8cdda8..bcfb04be1 100644
--- a/Demos/Device/AudioInput/AudioInput.c
+++ b/Demos/Device/AudioInput/AudioInput.c
@@ -28,26 +28,32 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the Audio Input demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
 #include "AudioInput.h"
 
-/* Scheduler Task List */
-TASK_LIST
+USB_ClassInfo_Audio_t Microphone_Audio_Interface =
+	{
+		.InterfaceNumber      = 0,
+
+		.DataINEndpointNumber = AUDIO_STREAM_EPNUM,
+		.DataINEndpointSize   = AUDIO_STREAM_EPSIZE,
+	};
+		
+int main(void)
 {
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Audio_Task       , .TaskStatus = TASK_STOP },
-};
+	SetupHardware();
 
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+	
+	for (;;)
+	{
+		if (Microphone_Audio_Interface.InterfaceEnabled)
+		  ProcessNextSample();
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
-int main(void)
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -58,35 +64,35 @@ int main(void)
 	
 	/* Hardware Initialization */
 	LEDs_Init();
+	USB_Init();
 	ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
 	ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
 	
 	/* Start the ADC conversion in free running mode */
 	ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_CHANNEL);
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
+}
 
-	/* Initialize USB Subsystem */
-	USB_Init();
+void ProcessNextSample(void)
+{
+	if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsReadyForNextSample(&Microphone_Audio_Interface))
+	{
+		TIFR0 |= (1 << OCF0A);
+
+		/* Audio sample is ADC value scaled to fit the entire range */
+		int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
+		
+#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
+		/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
+		AudioSample -= (SAMPLE_MAX_RANGE / 2));
+#endif
 
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
+		USB_Audio_WriteSample16(AudioSample);
+	}
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and
- *  configures the sample update and PWM timers.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 
 	/* Sample reload timer initialization */
 	OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
@@ -94,127 +100,23 @@ void EVENT_USB_Connect(void)
 	TCCR0B  = (1 << CS00);   // Fcpu speed
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
- */
 void EVENT_USB_Disconnect(void)
 {
 	/* Stop the sample reload timer */
 	TCCR0B = 0;
 
-	/* Stop running audio and USB management tasks */
-	Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup audio stream endpoint */
-	Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,
-		                       ENDPOINT_DIR_IN, AUDIO_STREAM_EPSIZE,
-	                           ENDPOINT_BANK_DOUBLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the Audio class-specific
- *  requests) so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
-	/* Process General and Audio specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_SetInterface:
-			/* Set Interface is not handled by the library, as its function is application-specific */
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
-				if (USB_ControlRequest.wValue)
-				{
-					/* Start audio task */
-					Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);
-				}
-				else
-				{
-					/* Stop audio task */
-					Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);				
-				}
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-
-			break;
-	}
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the AudioInput_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
+	if (!(USB_Audio_ConfigureEndpoints(&Microphone_Audio_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to manage the Audio interface, reading in ADC samples from the microphone, and them to the host. */
-TASK(USB_Audio_Task)
+void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Select the audio stream endpoint */
-	Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
-	
-	/* Check if the current endpoint can be written to and that the next sample should be stored */
-	if (Endpoint_IsINReady() && (TIFR0 & (1 << OCF0A)))
-	{
-		/* Clear the sample reload timer */
-		TIFR0 |= (1 << OCF0A);
-
-		/* Audio sample is ADC value scaled to fit the entire range */
-		int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
-		
-#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
-		/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
-		AudioSample -= (SAMPLE_MAX_RANGE / 2));
-#endif
-
-		/* Write the sample to the buffer */
-		Endpoint_Write_Word_LE(AudioSample);
-
-		/* Check to see if the bank is now full */
-		if (!(Endpoint_IsReadWriteAllowed()))
-		{
-			/* Send the full packet to the host */
-			Endpoint_ClearIN();
-		}
-	}
+	USB_Audio_ProcessControlPacket(&Microphone_Audio_Interface);
 }
diff --git a/Demos/Device/AudioInput/AudioInput.h b/Demos/Device/AudioInput/AudioInput.h
index a394492f0..e9f56b30a 100644
--- a/Demos/Device/AudioInput/AudioInput.h
+++ b/Demos/Device/AudioInput/AudioInput.h
@@ -43,12 +43,13 @@
 
 		#include "Descriptors.h"
 				
-		#include <LUFA/Version.h>                      // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>              // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>           // LEDs driver
-		#include <LUFA/Drivers/Peripheral/ADC.h>       // ADC driver
-		#include <LUFA/Scheduler/Scheduler.h>          // Simple scheduler for task management
-
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Peripheral/ADC.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/Audio.h>
+		
 	/* Macros: */
 		/** ADC channel number for the microphone input. */
 		#define MIC_IN_ADC_CHANNEL               2
@@ -59,24 +60,19 @@
 		/** Maximum ADC range for the microphone input. */
 		#define ADC_MAX_RANGE                    0x3FF
 
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum AudioInput_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-
-	/* Task Definitions: */
-		TASK(USB_Audio_Task);
-
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
+		
 	/* Function Prototypes: */
+		void SetupHardware(void);
+		void ProcessNextSample(void);
+		
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		void UpdateStatus(uint8_t CurrentStatus);
-		
 #endif
diff --git a/Demos/Device/AudioInput/makefile b/Demos/Device/AudioInput/makefile
index c70e98e04..9d3adff69 100644
--- a/Demos/Device/AudioInput/makefile
+++ b/Demos/Device/AudioInput/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/Audio.c          \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Device/AudioOutput/AudioOutput.c b/Demos/Device/AudioOutput/AudioOutput.c
index 40e376b52..0f193567a 100644
--- a/Demos/Device/AudioOutput/AudioOutput.c
+++ b/Demos/Device/AudioOutput/AudioOutput.c
@@ -28,26 +28,32 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the Audio Output demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
- 
 #include "AudioOutput.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Audio_Task       , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_Audio_t Speaker_Audio_Interface =
+	{
+		.InterfaceNumber       = 0,
 
+		.DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
+		.DataOUTEndpointSize   = AUDIO_STREAM_EPSIZE,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
 int main(void)
+{
+	SetupHardware();
+
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+	
+	for (;;)
+	{
+		if (Speaker_Audio_Interface.InterfaceEnabled)
+		  ProcessNextSample();
+
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -58,186 +64,19 @@ int main(void)
 
 	/* Hardware Initialization */
 	LEDs_Init();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs, and
- *  configures the sample update and PWM timers.
- */
-void EVENT_USB_Connect(void)
-{
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-	
-	/* Sample reload timer initialization */
-	OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
-	TCCR0A  = (1 << WGM01);  // CTC mode
-	TCCR0B  = (1 << CS00);   // Fcpu speed
-			
-#if defined(AUDIO_OUT_MONO)
-	/* Set speaker as output */
-	DDRC   |= (1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
-	/* Set speakers as outputs */
-	DDRC   |= ((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
-	/* Set PORTC as outputs */
-	DDRC   |= 0xFF;
-#endif
-
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
-	/* PWM speaker timer initialization */
-	TCCRxA  = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)
-							| (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP
-	TCCRxB  = ((1 << WGMx2) | (1 << CSx0));  // Fast 8-Bit PWM, Fcpu speed
-#endif	
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
-	/* Stop the timers */
-	TCCR0B = 0;
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
-	TCCRxB = 0;
-#endif		
-
-#if defined(AUDIO_OUT_MONO)
-	/* Set speaker as input to reduce current draw */
-	DDRC   &= ~(1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
-	/* Set speakers as inputs to reduce current draw */
-	DDRC   &= ~((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
-	/* Set PORTC low */
-	PORTC  = 0x00;
-#endif
-
-	/* Stop running audio and USB management tasks */
-	Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
-	/* Setup audio stream endpoint */
-	Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,
-		                       ENDPOINT_DIR_OUT, AUDIO_STREAM_EPSIZE,
-	                           ENDPOINT_BANK_DOUBLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the Audio class-specific
- *  requests) so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
+void ProcessNextSample(void)
 {
-	/* Process General and Audio specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_SetInterface:
-			/* Set Interface is not handled by the library, as its function is application-specific */
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
-				if (USB_ControlRequest.wValue)
-				{
-					/* Start audio task */
-					Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);
-				}
-				else
-				{
-					/* Stop audio task */
-					Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);				
-				}
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-
-			break;
-	}
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the AudioOutput_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the Audio interface, reading in audio samples from the host, and outputting them to the speakers/LEDs as
- *  desired.
- */
-TASK(USB_Audio_Task)
-{
-	/* Select the audio stream endpoint */
-	Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
-	
-	/* Check if the current endpoint can be read from (contains a packet) and that the next sample should be read */
-	if (Endpoint_IsOUTReceived() && (TIFR0 & (1 << OCF0A)))
+	if ((TIFR0 & (1 << OCF0A)) && USB_Audio_IsSampleReceived(&Speaker_Audio_Interface))
 	{
 		/* Clear the sample reload timer */
 		TIFR0 |= (1 << OCF0A);
 
 		/* Retrieve the signed 16-bit left and right audio samples */
-		int16_t LeftSample_16Bit  = (int16_t)Endpoint_Read_Word_LE();
-		int16_t RightSample_16Bit = (int16_t)Endpoint_Read_Word_LE();
-
-		/* Check to see if the bank is now empty */
-		if (!(Endpoint_IsReadWriteAllowed()))
-		{
-			/* Acknowledge the packet, clear the bank ready for the next packet */
-			Endpoint_ClearOUT();
-		}
+		int16_t LeftSample_16Bit  = (int16_t)USB_Audio_ReadSample16();
+		int16_t RightSample_16Bit = (int16_t)USB_Audio_ReadSample16();
 
 		/* Massage signed 16-bit left and right audio samples into signed 8-bit */
 		int8_t  LeftSample_8Bit   = (LeftSample_16Bit  >> 8);
@@ -289,3 +128,69 @@ TASK(USB_Audio_Task)
 #endif
 	}
 }
+
+void EVENT_USB_Connect(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+	
+	/* Sample reload timer initialization */
+	OCR0A   = (F_CPU / AUDIO_SAMPLE_FREQUENCY) - 1;
+	TCCR0A  = (1 << WGM01);  // CTC mode
+	TCCR0B  = (1 << CS00);   // Fcpu speed
+
+#if defined(AUDIO_OUT_MONO)
+	/* Set speaker as output */
+	DDRC   |= (1 << 6);
+#elif defined(AUDIO_OUT_STEREO)
+	/* Set speakers as outputs */
+	DDRC   |= ((1 << 6) | (1 << 5));
+#elif defined(AUDIO_OUT_PORTC)
+	/* Set PORTC as outputs */
+	DDRC   |= 0xFF;
+#endif
+
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+	/* PWM speaker timer initialization */
+	TCCRxA  = ((1 << WGMx0) | (1 << COMxA1) | (1 << COMxA0)
+							| (1 << COMxB1) | (1 << COMxB0)); // Set on match, clear on TOP
+	TCCRxB  = ((1 << WGMx2) | (1 << CSx0));  // Fast 8-Bit PWM, Fcpu speed
+#endif	
+}
+
+/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
+ *  the status LEDs, disables the sample update and PWM output timers and stops the USB and Audio management tasks.
+ */
+void EVENT_USB_Disconnect(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+	/* Stop the timers */
+	TCCR0B = 0;
+#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+	TCCRxB = 0;
+#endif		
+
+#if defined(AUDIO_OUT_MONO)
+	/* Set speaker as input to reduce current draw */
+	DDRC   &= ~(1 << 6);
+#elif defined(AUDIO_OUT_STEREO)
+	/* Set speakers as inputs to reduce current draw */
+	DDRC   &= ~((1 << 6) | (1 << 5));
+#elif defined(AUDIO_OUT_PORTC)
+	/* Set PORTC low */
+	PORTC  = 0x00;
+#endif
+}
+
+void EVENT_USB_ConfigurationChanged(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
+	
+	if (!(USB_Audio_ConfigureEndpoints(&Speaker_Audio_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
+
+void EVENT_USB_UnhandledControlPacket(void)
+{
+	USB_Audio_ProcessControlPacket(&Speaker_Audio_Interface);
+}
diff --git a/Demos/Device/AudioOutput/AudioOutput.h b/Demos/Device/AudioOutput/AudioOutput.h
index d8725a07b..7d112db88 100644
--- a/Demos/Device/AudioOutput/AudioOutput.h
+++ b/Demos/Device/AudioOutput/AudioOutput.h
@@ -43,10 +43,12 @@
 
 		#include "Descriptors.h"
 		
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Peripheral/ADC.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/Audio.h>
 	
 	/* Macros: */
 		#if defined(USB_FULL_CONTROLLER) || defined(USB_MODIFIED_FULL_CONTROLLER)
@@ -96,24 +98,19 @@
 			#define CSx0            CS10
 		#endif
 		
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum AudioOutput_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-
-	/* Task Definitions: */
-		TASK(USB_Audio_Task);
-	
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
+		
 	/* Function Prototypes: */
+		void SetupHardware(void);
+		void ProcessNextSample(void);
+		
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-		
-		void UpdateStatus(uint8_t CurrentStatus);
 
 #endif
diff --git a/Demos/Device/AudioOutput/makefile b/Demos/Device/AudioOutput/makefile
index 28f038f49..8ad1def4d 100644
--- a/Demos/Device/AudioOutput/makefile
+++ b/Demos/Device/AudioOutput/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/Audio.c          \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -186,7 +185,7 @@ CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
-CDEFS += -DAUDIO_OUT_STEREO
+CDEFS += -DAUDIO_OUT_MONO
 
 # Place -D or -U options here for ASM sources
 ADEFS = -DF_CPU=$(F_CPU)
diff --git a/Demos/Device/CDC/CDC.c b/Demos/Device/CDC/CDC.c
index d7ebb9e6b..e6bc1a455 100644
--- a/Demos/Device/CDC/CDC.c
+++ b/Demos/Device/CDC/CDC.c
@@ -28,54 +28,42 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the CDC demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
 #include "CDC.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = CDC_Task             , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
+	{
+		.ControlInterfaceNumber     = 0,
 
-/* Globals: */
-/** Contains the current baud rate and other settings of the virtual serial port. While this demo does not use
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host
- *  upon request or the host will assume the device is non-functional.
- *
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- *  serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
-                                 .CharFormat  = OneStopBit,
-                                 .ParityType  = Parity_None,
-                                 .DataBits    = 8            };
+		.DataINEndpointNumber       = CDC_TX_EPNUM,
+		.DataINEndpointSize         = CDC_TXRX_EPSIZE,
 
-/** String to print through the virtual serial port when the joystick is pressed upwards. */
-char JoystickUpString[]      = "Joystick Up\r\n";
+		.DataOUTEndpointNumber      = CDC_RX_EPNUM,
+		.DataOUTEndpointSize        = CDC_TXRX_EPSIZE,
 
-/** String to print through the virtual serial port when the joystick is pressed downward. */
-char JoystickDownString[]    = "Joystick Down\r\n";
+		.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+		.NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,
+	};
 
-/** String to print through the virtual serial port when the joystick is pressed left. */
-char JoystickLeftString[]    = "Joystick Left\r\n";
+int main(void)
+{
+	SetupHardware();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 
-/** String to print through the virtual serial port when the joystick is pressed right. */
-char JoystickRightString[]   = "Joystick Right\r\n";
+	for (;;)
+	{
+		CheckJoystickMovement();
+		
+		uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface);
+		while (BytesToDiscard--)
+		  USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface);
 
-/** String to print through the virtual serial port when the joystick is pressed inwards. */
-char JoystickPressedString[] = "Joystick Pressed\r\n";
+		USB_CDC_USBTask(&VirtualSerial_CDC_Interface);
+		USB_USBTask();
+	}
+}
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -87,235 +75,64 @@ int main(void)
 	/* Hardware Initialization */
 	Joystick_Init();
 	LEDs_Init();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
-void EVENT_USB_Connect(void)
-{
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-}
-
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management and CDC management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
-	/* Stop running CDC and USB management tasks */
-	Scheduler_SetTaskMode(CDC_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management task started.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
-	/* Setup CDC Notification, Rx and Tx Endpoints */
-	Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-	
-	/* Start CDC task */
-	Scheduler_SetTaskMode(CDC_Task, TASK_RUN);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the CDC control commands,
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
-	uint8_t* LineCodingData = (uint8_t*)&LineCoding;
-
-	/* Process CDC specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{	
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Write the line coding data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Read the line coding data in from the host into the global struct */
-				Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
-				/* Finalize the stream transfer to clear the last packet from the host */
-				Endpoint_ClearIN();
-			}
-	
-			break;
-		case REQ_SetControlLineState:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-				
-				/* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
-				         lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
-						 CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
-				*/
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-	
-			break;
-	}
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the CDC_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CheckJoystickMovement(void)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
+	uint8_t     JoyStatus_LCL = Joystick_GetStatus();
+	char*       ReportString  = NULL;
+	static bool ActionSent = false;
 	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Function to manage CDC data transmission and reception to and from the host. */
-TASK(CDC_Task)
-{
-	char*       ReportString    = NULL;
-	uint8_t     JoyStatus_LCL   = Joystick_GetStatus();
-	static bool ActionSent      = false;
-	
-#if 0
-	/* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232
-	         handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:
-	*/
-	USB_Notification_Header_t Notification = (USB_Notification_Header_t)
+	char* JoystickStrings[] =
 		{
-			.NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
-			.Notification     = NOTIF_SerialState,
-			.wValue           = 0,
-			.wIndex           = 0,
-			.wLength          = sizeof(uint16_t),
+			"Joystick Up\r\n",
+			"Joystick Down\r\n",
+			"Joystick Left\r\n",
+			"Joystick Right\r\n",
+			"Joystick Pressed\r\n",
 		};
-		
-	uint16_t LineStateMask;
-	
-	// Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host
-	
-	Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
-	Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
-	Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
-	Endpoint_ClearIN();
-#endif
 
-	/* Determine if a joystick action has occurred */
 	if (JoyStatus_LCL & JOY_UP)
-	  ReportString = JoystickUpString;
+	  ReportString = JoystickStrings[0];
 	else if (JoyStatus_LCL & JOY_DOWN)
-	  ReportString = JoystickDownString;
+	  ReportString = JoystickStrings[1];
 	else if (JoyStatus_LCL & JOY_LEFT)
-	  ReportString = JoystickLeftString;
+	  ReportString = JoystickStrings[2];
 	else if (JoyStatus_LCL & JOY_RIGHT)
-	  ReportString = JoystickRightString;
+	  ReportString = JoystickStrings[3];
 	else if (JoyStatus_LCL & JOY_PRESS)
-	  ReportString = JoystickPressedString;
-
-	/* Flag management - Only allow one string to be sent per action */
-	if (ReportString == NULL)
-	{
-		ActionSent = false;
-	}
-	else if (ActionSent == false)
+	  ReportString = JoystickStrings[4];
+	else
+	  ActionSent = false;
+	  
+	if ((ReportString != NULL) && (ActionSent == false))
 	{
 		ActionSent = true;
+		
+		USB_CDC_SendString(&VirtualSerial_CDC_Interface, ReportString, strlen(ReportString));		
+	}
+}
 
-		/* Select the Serial Tx Endpoint */
-		Endpoint_SelectEndpoint(CDC_TX_EPNUM);
+void EVENT_USB_Connect(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
 
-		/* Write the String to the Endpoint */
-		Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));
-		
-		/* Remember if the packet to send completely fills the endpoint */
-		bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);
+void EVENT_USB_Disconnect(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
 
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
+void EVENT_USB_ConfigurationChanged(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-		/* If the last packet filled the endpoint, send an empty packet to release the buffer on 
-		 * the receiver (otherwise all data will be cached until a non-full packet is received) */
-		if (IsFull)
-		{
-			/* Wait until the endpoint is ready for another packet */
-			while (!(Endpoint_IsINReady()));
-			
-			/* Send an empty packet to ensure that the host does not buffer data sent to it */
-			Endpoint_ClearIN();
-		}
-	}
+	if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
 
-	/* Select the Serial Rx Endpoint */
-	Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-	
-	/* Throw away any received data from the host */
-	if (Endpoint_IsOUTReceived())
-	  Endpoint_ClearOUT();
+void EVENT_USB_UnhandledControlPacket(void)
+{
+	USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);
 }
diff --git a/Demos/Device/CDC/CDC.h b/Demos/Device/CDC/CDC.h
index 4c4ca74d5..b487813b0 100644
--- a/Demos/Device/CDC/CDC.h
+++ b/Demos/Device/CDC/CDC.h
@@ -44,139 +44,26 @@
 
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                        // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>                // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>         // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>             // LEDs driver
-		#include <LUFA/Scheduler/Scheduler.h>            // Simple scheduler for task management
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
 
 	/* Macros: */
-		/** CDC Class specific request to get the current virtual serial port configuration settings. */
-		#define REQ_GetLineEncoding          0x21
-
-		/** CDC Class specific request to set the current virtual serial port configuration settings. */
-		#define REQ_SetLineEncoding          0x20
-
-		/** CDC Class specific request to set the current virtual serial port handshake line states. */
-		#define REQ_SetControlLineState      0x22
-		
-		/** Notification type constant for a change in the virtual serial port handshake line states, for
-		 *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC 
-		 *  notification endpoint.
-		 */
-		#define NOTIF_SerialState            0x20
-
-		/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
-		 *  from the host, to indicate that the DTR line state should be high.
-		 */
-		#define CONTROL_LINE_OUT_DTR         (1 << 0)
-
-		/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
-		 *  from the host, to indicate that theRTS line state should be high.
-		 */
-		#define CONTROL_LINE_OUT_RTS         (1 << 1)
-		
-		/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the DCD line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_DCD          (1 << 0)
-
-		/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the DSR line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_DSR          (1 << 1)
-
-		/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the BREAK line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_BREAK        (1 << 2)
-
-		/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the RING line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_RING         (1 << 3)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a framing error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a parity error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_PARITYERROR  (1 << 5)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a data overrun error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
-		
-	/* Type Defines: */
-		/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
-		 *  as set by the host via a class specific request.
-		 */
-		typedef struct
-		{
-			uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
-			uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the
-			                      *   CDCDevice_CDC_LineCodingFormats_t enum
-			                      */
-			uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the
-			                      *   CDCDevice_LineCodingParity_t enum
-			                      */
-			uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */
-		} CDC_Line_Coding_t;
-		
-		/** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
-		 *  change in the device state asynchronously.
-		 */
-		typedef struct
-		{
-			uint8_t  NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
-			                            *   from the library StdRequestType.h header
-			                            */
-			uint8_t  Notification; /**< Notification value, a NOTIF_* constant */
-			uint16_t wValue; /**< Notification wValue, notification-specific */
-			uint16_t wIndex; /**< Notification wIndex, notification-specific */
-			uint16_t wLength; /**< Notification wLength, notification-specific */
-		} USB_Notification_Header_t;
-		
-	/* Enums: */
-		/** Enum for the possible line encoding formats of a virtual serial port. */
-		enum CDCDevice_CDC_LineCodingFormats_t
-		{
-			OneStopBit          = 0, /**< Each frame contains one stop bit */
-			OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
-			TwoStopBits         = 2, /**< Each frame contains two stop bits */
-		};
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
-		/** Enum for the possible line encoding parity settings of a virtual serial port. */
-		enum CDCDevice_LineCodingParity_t
-		{
-			Parity_None         = 0, /**< No parity bit mode on each frame */
-			Parity_Odd          = 1, /**< Odd parity bit mode on each frame */
-			Parity_Even         = 2, /**< Even parity bit mode on each frame */
-			Parity_Mark         = 3, /**< Mark parity bit mode on each frame */
-			Parity_Space        = 4, /**< Space parity bit mode on each frame */
-		};
-
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum CDC_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-		
-	/* Tasks: */
-		TASK(CDC_Task);
-
 	/* Function Prototypes: */
+		void SetupHardware(void);
+		void CheckJoystickMovement(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-
-		void UpdateStatus(uint8_t CurrentStatus);
+		void EVENT_USB_StartOfFrame(void);
 
 #endif
diff --git a/Demos/Device/CDC/Descriptors.h b/Demos/Device/CDC/Descriptors.h
index 41b44300a..1a9dbb5bf 100644
--- a/Demos/Device/CDC/Descriptors.h
+++ b/Demos/Device/CDC/Descriptors.h
@@ -37,26 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Macros: */
-		/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
-		 *  uniform structure but variable sized data payloads, thus cannot be represented accurately by
-		 *  a single typedef struct. A macro is used instead so that functional descriptors can be created
-		 *  easily by specifying the size of the payload. This allows sizeof() to work correctly.
-		 *
-		 *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload
-		 */
-		#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \
-		     struct                                        \
-		     {                                             \
-		          USB_Descriptor_Header_t Header;          \
-			      uint8_t                 SubType;         \
-		          uint8_t                 Data[DataSize];  \
-		     }
-			 
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
+
+	/* Macros: */			 
 		/** Endpoint number of the CDC device-to-host notification IN endpoint. */
 		#define CDC_NOTIFICATION_EPNUM         2
 
diff --git a/Demos/Device/CDC/makefile b/Demos/Device/CDC/makefile
index bc22be5c0..bd4ff36b9 100644
--- a/Demos/Device/CDC/makefile
+++ b/Demos/Device/CDC/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/DualCDC/Descriptors.h b/Demos/Device/DualCDC/Descriptors.h
index 2c2311b9c..97165e5de 100644
--- a/Demos/Device/DualCDC/Descriptors.h
+++ b/Demos/Device/DualCDC/Descriptors.h
@@ -37,26 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Macros: */
-		/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
-		 *  uniform structure but variable sized data payloads, thus cannot be represented accurately by
-		 *  a single typedef struct. A macro is used instead so that functional descriptors can be created
-		 *  easily by specifying the size of the payload. This allows sizeof() to work correctly.
-		 *
-		 *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload
-		 */
-		#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \
-		     struct                                        \
-		     {                                             \
-		          USB_Descriptor_Header_t Header;          \
-			      uint8_t                 SubType;         \
-		          uint8_t                 Data[DataSize];  \
-		     }
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
 
+	/* Macros: */
 		/** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
 		#define CDC1_NOTIFICATION_EPNUM        3
 
diff --git a/Demos/Device/DualCDC/DualCDC.c b/Demos/Device/DualCDC/DualCDC.c
index 34d772ff0..26947f433 100644
--- a/Demos/Device/DualCDC/DualCDC.c
+++ b/Demos/Device/DualCDC/DualCDC.c
@@ -27,69 +27,62 @@
   arising out of or in connection with the use or performance of
   this software.
 */
-
-/** \file
- *
- *  Main source file for the DualCDC demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
  
 #include "DualCDC.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = CDC1_Task            , .TaskStatus = TASK_STOP },
-	{ .Task = CDC2_Task            , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_CDC_t VirtualSerial1_CDC_Interface =
+	{
+		.ControlInterfaceNumber     = 0,
 
-/* Globals: */
-/** Contains the current baud rate and other settings of the first virtual serial port. While this demo does not use
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host
- *  upon request or the host will assume the device is non-functional.
- *
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- *  serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding1 = { .BaudRateBPS = 9600,
-                                  .CharFormat  = OneStopBit,
-                                  .ParityType  = Parity_None,
-                                  .DataBits    = 8            };
+		.DataINEndpointNumber       = CDC1_TX_EPNUM,
+		.DataINEndpointSize         = CDC_TXRX_EPSIZE,
 
-/** Contains the current baud rate and other settings of the second virtual serial port. While this demo does not use
- *  the physical USART and thus does not use these settings, they must still be retained and returned to the host
- *  upon request or the host will assume the device is non-functional.
- *
- *  These values are set by the host via a class-specific request, however they are not required to be used accurately.
- *  It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
- *  serial link characteristics and instead sends and receives data in endpoint streams.
- */
-CDC_Line_Coding_t LineCoding2 = { .BaudRateBPS = 9600,
-                                  .CharFormat  = OneStopBit,
-                                  .ParityType  = Parity_None,
-                                  .DataBits    = 8            };
-								  
-/** String to print through the first virtual serial port when the joystick is pressed upwards. */
-char JoystickUpString[]      = "Joystick Up\r\n";
+		.DataOUTEndpointNumber      = CDC1_RX_EPNUM,
+		.DataOUTEndpointSize        = CDC_TXRX_EPSIZE,
 
-/** String to print through the first virtual serial port when the joystick is pressed downward. */
-char JoystickDownString[]    = "Joystick Down\r\n";
+		.NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
+		.NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,
+	};
+
+USB_ClassInfo_CDC_t VirtualSerial2_CDC_Interface =
+	{
+		.ControlInterfaceNumber     = 0,
 
-/** String to print through the first virtual serial port when the joystick is pressed left. */
-char JoystickLeftString[]    = "Joystick Left\r\n";
+		.DataINEndpointNumber       = CDC2_TX_EPNUM,
+		.DataINEndpointSize         = CDC_TXRX_EPSIZE,
 
-/** String to print through the first virtual serial port when the joystick is pressed right. */
-char JoystickRightString[]   = "Joystick Right\r\n";
+		.DataOUTEndpointNumber      = CDC2_RX_EPNUM,
+		.DataOUTEndpointSize        = CDC_TXRX_EPSIZE,
 
-/** String to print through the first virtual serial port when the joystick is pressed inwards. */
-char JoystickPressedString[] = "Joystick Pressed\r\n";
+		.NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
+		.NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
 int main(void)
+{
+	SetupHardware();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+	for (;;)
+	{
+		CheckJoystickMovement();
+
+		uint16_t BytesToDiscard = USB_CDC_BytesReceived(&VirtualSerial1_CDC_Interface);
+		while (BytesToDiscard--)
+		  USB_CDC_ReceiveByte(&VirtualSerial1_CDC_Interface);
+
+		uint16_t BytesToEcho = USB_CDC_BytesReceived(&VirtualSerial2_CDC_Interface);
+		while (BytesToEcho--)
+		  USB_CDC_SendByte(&VirtualSerial2_CDC_Interface, USB_CDC_ReceiveByte(&VirtualSerial2_CDC_Interface));
+		  
+		USB_CDC_USBTask(&VirtualSerial1_CDC_Interface);
+		USB_CDC_USBTask(&VirtualSerial2_CDC_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -101,257 +94,68 @@ int main(void)
 	/* Hardware Initialization */
 	Joystick_Init();
 	LEDs_Init();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
-}
-
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
-void EVENT_USB_Connect(void)
-{
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-}
-
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management and CDC management tasks.
- */
-void EVENT_USB_Disconnect(void)
-{
-	/* Stop running CDC and USB management tasks */
-	Scheduler_SetTaskMode(CDC1_Task, TASK_STOP);
-	Scheduler_SetTaskMode(CDC2_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-}
-
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management tasks are started.
- */
-void EVENT_USB_ConfigurationChanged(void)
-{
-	/* Setup CDC Notification, Rx and Tx Endpoints for the first CDC */
-	Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC1_TX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC1_RX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Setup CDC Notification, Rx and Tx Endpoints for the second CDC */
-	Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC2_TX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC2_RX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-							   
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-	
-	/* Start CDC tasks */
-	Scheduler_SetTaskMode(CDC1_Task, TASK_RUN);
-	Scheduler_SetTaskMode(CDC2_Task, TASK_RUN);
-}
-
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the CDC control commands,
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
-void EVENT_USB_UnhandledControlPacket(void)
-{
-	/* Determine which interface's Line Coding data is being set from the wIndex parameter */
-	uint8_t* LineCodingData = (USB_ControlRequest.wIndex == 0) ? (uint8_t*)&LineCoding1 : (uint8_t*)&LineCoding2;
-
-	/* Process CDC specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{	
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Write the line coding data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Read the line coding data in from the host into the global struct */
-				Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(CDC_Line_Coding_t));
-
-				/* Finalize the stream transfer to clear the last packet from the host */
-				Endpoint_ClearIN();
-			}
-	
-			break;
-		case REQ_SetControlLineState:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-	
-			break;
-	}
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the DualCDC_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
 }
 
-/** Function to manage CDC data transmission and reception to and from the host for the first CDC interface, which sends joystick
- *  movements to the host as ASCII strings.
- */
-TASK(CDC1_Task)
+void CheckJoystickMovement(void)
 {
-	char*       ReportString    = NULL;
-	uint8_t     JoyStatus_LCL   = Joystick_GetStatus();
-	static bool ActionSent      = false;
+	uint8_t     JoyStatus_LCL = Joystick_GetStatus();
+	char*       ReportString  = NULL;
+	static bool ActionSent = false;
+
+	char* JoystickStrings[] =
+		{
+			"Joystick Up\r\n",
+			"Joystick Down\r\n",
+			"Joystick Left\r\n",
+			"Joystick Right\r\n",
+			"Joystick Pressed\r\n",
+		};
 
-	/* Determine if a joystick action has occurred */
 	if (JoyStatus_LCL & JOY_UP)
-	  ReportString = JoystickUpString;
+	  ReportString = JoystickStrings[0];
 	else if (JoyStatus_LCL & JOY_DOWN)
-	  ReportString = JoystickDownString;
+	  ReportString = JoystickStrings[1];
 	else if (JoyStatus_LCL & JOY_LEFT)
-	  ReportString = JoystickLeftString;
+	  ReportString = JoystickStrings[2];
 	else if (JoyStatus_LCL & JOY_RIGHT)
-	  ReportString = JoystickRightString;
+	  ReportString = JoystickStrings[3];
 	else if (JoyStatus_LCL & JOY_PRESS)
-	  ReportString = JoystickPressedString;
-
-	/* Flag management - Only allow one string to be sent per action */
-	if (ReportString == NULL)
-	{
-		ActionSent = false;
-	}
-	else if (ActionSent == false)
+	  ReportString = JoystickStrings[4];
+	else
+	  ActionSent = false;
+	  
+	if ((ReportString != NULL) && (ActionSent == false))
 	{
 		ActionSent = true;
 		
-		/* Select the Serial Tx Endpoint */
-		Endpoint_SelectEndpoint(CDC1_TX_EPNUM);
-
-		/* Write the String to the Endpoint */
-		Endpoint_Write_Stream_LE(ReportString, strlen(ReportString));
-		
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
-
-		/* Wait until the endpoint is ready for another packet */
-		while (!(Endpoint_IsINReady()));
-		
-		/* Send an empty packet to ensure that the host does not buffer data sent to it */
-		Endpoint_ClearIN();
+		USB_CDC_SendString(&VirtualSerial1_CDC_Interface, ReportString, strlen(ReportString));		
 	}
-
-	/* Select the Serial Rx Endpoint */
-	Endpoint_SelectEndpoint(CDC1_RX_EPNUM);
-	
-	/* Throw away any received data from the host */
-	if (Endpoint_IsOUTReceived())
-	  Endpoint_ClearOUT();
 }
 
-/** Function to manage CDC data transmission and reception to and from the host for the second CDC interface, which echoes back
- *  all data sent to it from the host.
- */
-TASK(CDC2_Task)
+void EVENT_USB_Connect(void)
 {
-	/* Select the Serial Rx Endpoint */
-	Endpoint_SelectEndpoint(CDC2_RX_EPNUM);
-	
-	/* Check to see if any data has been received */
-	if (Endpoint_IsOUTReceived())
-	{
-		/* Create a temp buffer big enough to hold the incoming endpoint packet */
-		uint8_t  Buffer[Endpoint_BytesInEndpoint()];
-		
-		/* Remember how large the incoming packet is */
-		uint16_t DataLength = Endpoint_BytesInEndpoint();
-	
-		/* Read in the incoming packet into the buffer */
-		Endpoint_Read_Stream_LE(&Buffer, DataLength);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
+}
 
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearOUT();
+void EVENT_USB_Disconnect(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+}
 
-		/* Select the Serial Tx Endpoint */
-		Endpoint_SelectEndpoint(CDC2_TX_EPNUM);
-		
-		/* Write the received data to the endpoint */
-		Endpoint_Write_Stream_LE(&Buffer, DataLength);
+void EVENT_USB_ConfigurationChanged(void)
+{
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
+	if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial1_CDC_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 
-		/* Wait until the endpoint is ready for the next packet */
-		while (!(Endpoint_IsINReady()));
+	if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial2_CDC_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+}
 
-		/* Send an empty packet to prevent host buffering */
-		Endpoint_ClearIN();
-	}
+void EVENT_USB_UnhandledControlPacket(void)
+{
+	USB_CDC_ProcessControlPacket(&VirtualSerial1_CDC_Interface);
+	USB_CDC_ProcessControlPacket(&VirtualSerial2_CDC_Interface);
 }
diff --git a/Demos/Device/DualCDC/DualCDC.h b/Demos/Device/DualCDC/DualCDC.h
index 117af601e..3c1e29612 100644
--- a/Demos/Device/DualCDC/DualCDC.h
+++ b/Demos/Device/DualCDC/DualCDC.h
@@ -44,75 +44,26 @@
 
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                        // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>                // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>         // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>             // LEDs driver
-		#include <LUFA/Scheduler/Scheduler.h>            // Simple scheduler for task management
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
 
 	/* Macros: */
-		/** CDC Class specific request to get the current virtual serial port configuration settings. */
-		#define REQ_GetLineEncoding          0x21
-
-		/** CDC Class specific request to set the current virtual serial port configuration settings. */
-		#define REQ_SetLineEncoding          0x20
-
-		/** CDC Class specific request to set the current virtual serial port handshake line states. */
-		#define REQ_SetControlLineState      0x22
-
-	/* Type Defines: */
-		/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
-		 *  as set by the host via a class specific request.
-		 */
-		typedef struct
-		{
-			uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
-			uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the
-			                      *   CDCDevice_CDC_LineCodingFormats_t enum
-			                      */
-			uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the
-			                      *   CDCDevice_LineCodingParity_t enum
-			                      */
-			uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */
-		} CDC_Line_Coding_t;
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
-	/* Enums: */
-		/** Enum for the possible line encoding formats of a virtual serial port. */
-		enum CDCDevice_CDC_LineCodingFormats_t
-		{
-			OneStopBit          = 0, /**< Each frame contains one stop bit */
-			OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
-			TwoStopBits         = 2, /**< Each frame contains two stop bits */
-		};
-		
-		/** Enum for the possible line encoding parity settings of a virtual serial port. */
-		enum CDCDevice_LineCodingParity_t
-		{
-			Parity_None         = 0, /**< No parity bit mode on each frame */
-			Parity_Odd          = 1, /**< Odd parity bit mode on each frame */
-			Parity_Even         = 2, /**< Even parity bit mode on each frame */
-			Parity_Mark         = 3, /**< Mark parity bit mode on each frame */
-			Parity_Space        = 4, /**< Space parity bit mode on each frame */
-		};
-
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum DualCDC_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-
-	/* Tasks: */
-		TASK(CDC1_Task);
-		TASK(CDC2_Task);
-
 	/* Function Prototypes: */
+		void SetupHardware(void);
+		void CheckJoystickMovement(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-
-		void UpdateStatus(uint8_t CurrentStatus);
+		void EVENT_USB_StartOfFrame(void);
 		
 #endif
diff --git a/Demos/Device/DualCDC/makefile b/Demos/Device/DualCDC/makefile
index 06d0e184b..5fbda61dd 100644
--- a/Demos/Device/DualCDC/makefile
+++ b/Demos/Device/DualCDC/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/GenericHID/Descriptors.h b/Demos/Device/GenericHID/Descriptors.h
index 023687032..bc4c68ae6 100644
--- a/Demos/Device/GenericHID/Descriptors.h
+++ b/Demos/Device/GenericHID/Descriptors.h
@@ -37,30 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
-		 *  specification for details on the structure elements.
-		 */
-		typedef struct
-		{
-			USB_Descriptor_Header_t               Header;
-				
-			uint16_t                              HIDSpec;
-			uint8_t                               CountryCode;
-		
-			uint8_t                               TotalReportDescriptors;
-
-			uint8_t                               HIDReportType;
-			uint16_t                              HIDReportLength;
-		} USB_Descriptor_HID_t;
-
-		/** Type define for the data type used to store HID report descriptor elements. */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/** Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -73,7 +55,7 @@
 	        USB_Descriptor_Endpoint_t             GenericINEndpoint;
 	        USB_Descriptor_Endpoint_t             GenericOUTEndpoint;
 		} USB_Descriptor_Configuration_t;
-					
+
 	/* Macros: */
 		/** Endpoint number of the Generic HID reporting IN endpoint. */
 		#define GENERIC_IN_EPNUM          1
@@ -86,13 +68,7 @@
 		
 		/** Size in bytes of the Generic HID reports (including report ID byte). */
 		#define GENERIC_REPORT_SIZE       8
-
-		/** Descriptor header type value, to indicate a HID class HID descriptor. */
-		#define DTYPE_HID                 0x21
 		
-		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
-		#define DTYPE_Report              0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
 											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/GenericHID/GenericHID.c b/Demos/Device/GenericHID/GenericHID.c
index 058d269fe..4dfb8e455 100644
--- a/Demos/Device/GenericHID/GenericHID.c
+++ b/Demos/Device/GenericHID/GenericHID.c
@@ -28,29 +28,37 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the GenericHID demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
 #include "GenericHID.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_HID_Report       , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Generic_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
 
-/** Static buffer to hold the last received report from the host, so that it can be echoed back in the next sent report */
-static uint8_t LastReceived[GENERIC_REPORT_SIZE];
+		.ReportINEndpointNumber  = GENERIC_IN_EPNUM,
+		.ReportINEndpointSize    = GENERIC_EPSIZE,
+		
+		.ReportOUTEndpointNumber = GENERIC_OUT_EPNUM,
+		.ReportOUTEndpointSize   = GENERIC_EPSIZE,
+		
+		.ReportBufferSize        = GENERIC_REPORT_SIZE,
 
+		.UsingReportProtocol     = true,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the USB management task.
- */
 int main(void)
+{
+	SetupHardware();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+	
+	for (;;)
+	{
+		USB_HID_USBTask(&Generic_HID_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -61,220 +69,45 @@ int main(void)
 
 	/* Hardware Initialization */
 	LEDs_Init();
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-	
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management task.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running HID reporting and USB management tasks */
-	Scheduler_SetTaskMode(USB_HID_Report, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- *  of the USB device after enumeration, and configures the generic HID device endpoints.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Generic IN Report Endpoint */
-	Endpoint_ConfigureEndpoint(GENERIC_IN_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, GENERIC_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Setup Generic OUT Report Endpoint */
-	Endpoint_ConfigureEndpoint(GENERIC_OUT_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_OUT, GENERIC_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
+	if (!(USB_HID_ConfigureEndpoints(&Generic_HID_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the HID commands, which are
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				uint8_t GenericData[GENERIC_REPORT_SIZE];
-
-				Endpoint_ClearSETUP();
-	
-				CreateGenericHIDReport(GenericData);
-
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(&GenericData, sizeof(GenericData));
-
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-		case REQ_SetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				uint8_t GenericData[GENERIC_REPORT_SIZE];
-
-				Endpoint_ClearSETUP();
-				
-				/* Wait until the generic report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
-
-				Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));
-
-				ProcessGenericHIDReport(GenericData);
-			
-				/* Clear the endpoint data */
-				Endpoint_ClearOUT();
-
-				/* Wait until the host is ready to receive the request confirmation */
-				while (!(Endpoint_IsINReady()));
-				
-				/* Handshake the request by sending an empty IN packet */
-				Endpoint_ClearIN();
-			}
-			
-			break;
-	}
+	USB_HID_ProcessControlPacket(&Generic_HID_Interface);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the GenericHID_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void EVENT_USB_StartOfFrame(void)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
+	USB_HID_RegisterStartOfFrame(&Generic_HID_Interface);
 }
 
-/** Function to process the lest received report from the host.
- *
- *  \param DataArray  Pointer to a buffer where the last report data is stored
- */
-void ProcessGenericHIDReport(uint8_t* DataArray)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
 {
-	/*
-		This is where you need to process the reports being sent from the host to the device.
-		DataArray is an array holding the last report from the host. This function is called
-		each time the host has sent a report to the device.
-	*/
+	// Create generic HID report here
 	
-	for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)
-	  LastReceived[i] = DataArray[i];
+	return 0;
 }
 
-/** Function to create the next report to send back to the host at the next reporting interval.
- *
- *  \param DataArray  Pointer to a buffer where the next report data should be stored
- */
-void CreateGenericHIDReport(uint8_t* DataArray)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
 {
-	/*
-		This is where you need to create reports to be sent to the host from the device. This
-		function is called each time the host is ready to accept a new report. DataArray is 
-		an array to hold the report to the host.
-	*/
-
-	for (uint8_t i = 0; i < GENERIC_REPORT_SIZE; i++)
-	  DataArray[i] = LastReceived[i];
-}
-
-TASK(USB_HID_Report)
-{
-	/* Check if the USB system is connected to a host */
-	if (USB_IsConnected)
-	{
-		Endpoint_SelectEndpoint(GENERIC_OUT_EPNUM);
-		
-		/* Check to see if a packet has been sent from the host */
-		if (Endpoint_IsOUTReceived())
-		{
-			/* Check to see if the packet contains data */
-			if (Endpoint_IsReadWriteAllowed())
-			{
-				/* Create a temporary buffer to hold the read in report from the host */
-				uint8_t GenericData[GENERIC_REPORT_SIZE];
-				
-				/* Read Generic Report Data */
-				Endpoint_Read_Stream_LE(&GenericData, sizeof(GenericData));
-				
-				/* Process Generic Report Data */
-				ProcessGenericHIDReport(GenericData);
-			}
-
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearOUT();
-		}	
-
-		Endpoint_SelectEndpoint(GENERIC_IN_EPNUM);
-		
-		/* Check to see if the host is ready to accept another packet */
-		if (Endpoint_IsINReady())
-		{
-			/* Create a temporary buffer to hold the report to send to the host */
-			uint8_t GenericData[GENERIC_REPORT_SIZE];
-			
-			/* Create Generic Report Data */
-			CreateGenericHIDReport(GenericData);
-
-			/* Write Generic Report Data */
-			Endpoint_Write_Stream_LE(&GenericData, sizeof(GenericData));
-
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearIN();
-		}
-	}
+	// Process received generic HID report here
 }
diff --git a/Demos/Device/GenericHID/GenericHID.h b/Demos/Device/GenericHID/GenericHID.h
index 30354b756..27426431c 100644
--- a/Demos/Device/GenericHID/GenericHID.h
+++ b/Demos/Device/GenericHID/GenericHID.h
@@ -46,38 +46,28 @@
 		
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-			
-	/* Macros: */
-		/** HID Class specific request to get the next HID report from the device. */
-		#define REQ_GetReport      0x01
-
-		/** HID Class specific request to send the next HID report to the device. */
-		#define REQ_SetReport      0x09
-
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum GenericHID_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
-	/* Task Definitions: */
-		TASK(USB_HID_Report);
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
+		void EVENT_USB_StartOfFrame(void);
 
-		void UpdateStatus(uint8_t CurrentStatus);
-		void ProcessGenericHIDReport(uint8_t* DataArray);
-		void CreateGenericHIDReport(uint8_t* DataArray);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 		
 #endif
diff --git a/Demos/Device/GenericHID/makefile b/Demos/Device/GenericHID/makefile
index 9c6c891cd..5cc4b4a43 100644
--- a/Demos/Device/GenericHID/makefile
+++ b/Demos/Device/GenericHID/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/Joystick/Descriptors.h b/Demos/Device/Joystick/Descriptors.h
index 6121295fa..1241ad14e 100644
--- a/Demos/Device/Joystick/Descriptors.h
+++ b/Demos/Device/Joystick/Descriptors.h
@@ -37,30 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
-		 *  specification for details on the structure elements.
-		 */
-		typedef struct
-		{
-			USB_Descriptor_Header_t               Header;
-				
-			uint16_t                              HIDSpec;
-			uint8_t                               CountryCode;
-		
-			uint8_t                               TotalReportDescriptors;
-
-			uint8_t                               HIDReportType;
-			uint16_t                              HIDReportLength;
-		} USB_Descriptor_HID_t;
-
-		/** Type define for the data type used to store HID report descriptor elements. */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -80,12 +62,6 @@
 		/** Size in bytes of the Joystick HID reporting IN endpoint. */
 		#define JOYSTICK_EPSIZE              8
 
-		/** Descriptor header type value, to indicate a HID class HID descriptor. */
-		#define DTYPE_HID                 0x21
-		
-		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
-		#define DTYPE_Report              0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
 											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Joystick/Joystick.c b/Demos/Device/Joystick/Joystick.c
index 8c50a2c16..e073a87fd 100644
--- a/Demos/Device/Joystick/Joystick.c
+++ b/Demos/Device/Joystick/Joystick.c
@@ -28,25 +28,34 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the Joystick demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
 #include "Joystick.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Joystick_Report  , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Joystick_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
+
+		.ReportINEndpointNumber  = JOYSTICK_EPNUM,
+		.ReportINEndpointSize    = JOYSTICK_EPSIZE,
+		
+		.ReportBufferSize        = sizeof(USB_JoystickReport_Data_t),
+
+		.UsingReportProtocol     = true,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
 int main(void)
+{
+	SetupHardware();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+	
+	for (;;)
+	{
+		USB_HID_USBTask(&Joystick_HID_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -59,188 +68,64 @@ int main(void)
 	Joystick_Init();
 	LEDs_Init();
 	Buttons_Init();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management and joystick reporting tasks.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running joystick reporting and USB management tasks */
-	Scheduler_SetTaskMode(USB_Joystick_Report, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the joystick reporting task started.
- */ 
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Joystick Report Endpoint */
-	Endpoint_ConfigureEndpoint(JOYSTICK_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, JOYSTICK_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-
-	/* Start joystick reporting task */
-	Scheduler_SetTaskMode(USB_Joystick_Report, TASK_RUN);
+	if (!(USB_HID_ConfigureEndpoints(&Joystick_HID_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the HID commands, which are
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				USB_JoystickReport_Data_t JoystickReportData;
-				
-				Endpoint_ClearSETUP();
-
-				/* Create the next HID report to send to the host */				
-				GetNextReport(&JoystickReportData);
-					
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-	}
+	USB_HID_ProcessControlPacket(&Joystick_HID_Interface);
 }
 
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- *  \param ReportData  Pointer to a HID report data structure to be filled
- *
- *  \return Boolean true if the new report differs from the last report, false otherwise
- */
-bool GetNextReport(USB_JoystickReport_Data_t* ReportData)
+void EVENT_USB_StartOfFrame(void)
 {
-	static uint8_t PrevJoyStatus    = 0;
-	static uint8_t PrevButtonStatus = 0;
-	uint8_t        JoyStatus_LCL    = Joystick_GetStatus();
-	uint8_t        ButtonStatus_LCL = Buttons_GetStatus();
-	bool           InputChanged     = false;
+	USB_HID_RegisterStartOfFrame(&Joystick_HID_Interface);
+}
 
-	/* Clear the report contents */
-	memset(ReportData, 0, sizeof(USB_JoystickReport_Data_t));
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+{
+	USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
+	
+	uint8_t JoyStatus_LCL    = Joystick_GetStatus();
+	uint8_t ButtonStatus_LCL = Buttons_GetStatus();
 
 	if (JoyStatus_LCL & JOY_UP)
-	  ReportData->Y = -100;
+	  JoystickReport->Y = -100;
 	else if (JoyStatus_LCL & JOY_DOWN)
-	  ReportData->Y =  100;
+	  JoystickReport->Y =  100;
 
 	if (JoyStatus_LCL & JOY_RIGHT)
-	  ReportData->X =  100;
+	  JoystickReport->X =  100;
 	else if (JoyStatus_LCL & JOY_LEFT)
-	  ReportData->X = -100;
+	  JoystickReport->X = -100;
 
 	if (JoyStatus_LCL & JOY_PRESS)
-	  ReportData->Button  = (1 << 1);
+	  JoystickReport->Button  = (1 << 1);
 	  
 	if (ButtonStatus_LCL & BUTTONS_BUTTON1)
-	  ReportData->Button |= (1 << 0);
+	  JoystickReport->Button |= (1 << 0);
 	  
-	/* Check if the new report is different to the previous report */
-	InputChanged = (uint8_t)(PrevJoyStatus ^ JoyStatus_LCL) | (uint8_t)(PrevButtonStatus ^ ButtonStatus_LCL);
-
-	/* Save the current joystick status for later comparison */
-	PrevJoyStatus    = JoyStatus_LCL;
-	PrevButtonStatus = ButtonStatus_LCL;
-
-	/* Return whether the new report is different to the previous report or not */
-	return InputChanged;
+	return sizeof(USB_JoystickReport_Data_t);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the Joystick_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Function to manage HID report generation and transmission to the host. */
-TASK(USB_Joystick_Report)
-{
-	/* Check if the USB System is connected to a Host */
-	if (USB_IsConnected)
-	{
-		/* Select the Joystick Report Endpoint */
-		Endpoint_SelectEndpoint(JOYSTICK_EPNUM);
-
-		/* Check to see if the host is ready for another packet */
-		if (Endpoint_IsINReady())
-		{
-			USB_JoystickReport_Data_t JoystickReportData;
-			
-			/* Create the next HID report to send to the host */
-			GetNextReport(&JoystickReportData);
-		
-			/* Write Joystick Report Data */
-			Endpoint_Write_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
-
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearIN();
-			
-			/* Clear the report data afterwards */
-			memset(&JoystickReportData, 0, sizeof(JoystickReportData));
-		}
-	}
+	// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
 }
diff --git a/Demos/Device/Joystick/Joystick.h b/Demos/Device/Joystick/Joystick.h
index 9763cada3..461d0d0cc 100644
--- a/Demos/Device/Joystick/Joystick.h
+++ b/Demos/Device/Joystick/Joystick.h
@@ -44,19 +44,12 @@
 
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-		#include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-		
-	/* Task Definitions: */
-		TASK(USB_Joystick_Report);
-
-	/* Macros: */
-		/** HID Class specific request to get the next HID report from the device. */
-		#define REQ_GetReport   0x01
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Buttons.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
 	/* Type Defines: */
 		/** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC.
@@ -69,22 +62,23 @@
 			uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
 		} USB_JoystickReport_Data_t;
 			
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum Joystick_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
+		void EVENT_USB_StartOfFrame(void);
 
-		bool GetNextReport(USB_JoystickReport_Data_t* ReportData);
-		void UpdateStatus(uint8_t CurrentStatus);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/Demos/Device/Joystick/makefile b/Demos/Device/Joystick/makefile
index aaf69e80b..826766c30 100644
--- a/Demos/Device/Joystick/makefile
+++ b/Demos/Device/Joystick/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/Keyboard/Descriptors.h b/Demos/Device/Keyboard/Descriptors.h
index 92eb7b884..0a95ca06e 100644
--- a/Demos/Device/Keyboard/Descriptors.h
+++ b/Demos/Device/Keyboard/Descriptors.h
@@ -38,30 +38,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
-		 *  specification for details on the structure elements.
-		 */	
-		typedef struct
-		{
-			USB_Descriptor_Header_t Header;
-				
-			uint16_t                HIDSpec;
-			uint8_t                 CountryCode;
-		
-			uint8_t                 TotalReportDescriptors;
-
-			uint8_t                 HIDReportType;
-			uint16_t                HIDReportLength;
-		} USB_Descriptor_HID_t;
-		
-		/** Type define for the data type used to store HID report descriptor elements. */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -85,12 +67,6 @@
 		/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */		
 		#define KEYBOARD_EPSIZE              8
 
-		/** Descriptor header type value, to indicate a HID class HID descriptor. */
-		#define DTYPE_HID                 0x21
-		
-		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
-		#define DTYPE_Report              0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
 											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Keyboard/Keyboard.c b/Demos/Device/Keyboard/Keyboard.c
index 6abd193f4..d8893bfaa 100644
--- a/Demos/Device/Keyboard/Keyboard.c
+++ b/Demos/Device/Keyboard/Keyboard.c
@@ -28,397 +28,120 @@
   arising out of or in connection with the use or performance of
   this software.
 */
-
-/** \file
- *
- *  Main source file for the Keyboard demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
  
 #include "Keyboard.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },	
-	{ .Task = USB_Keyboard_Report  , .TaskStatus = TASK_STOP },
-};
-
-/* Global Variables */
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot
- *  protocol reporting mode.
- */
-bool UsingReportProtocol = true;
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+    {
+        .InterfaceNumber         = 0,
 
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports
- *  for either the entire idle duration, or until the report status changes (e.g. the user presses a key).
- */
-uint16_t IdleCount = 500;
+        .ReportINEndpointNumber  = KEYBOARD_EPNUM,
+        .ReportINEndpointSize    = KEYBOARD_EPSIZE,
 
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle
- *  milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request 
- *  the current idle period via a Get Idle HID class request, thus its value must be preserved.
- */
-uint16_t IdleMSRemaining = 0;
+        .ReportOUTEndpointNumber = KEYBOARD_LEDS_EPNUM,
+        .ReportOUTEndpointSize   = KEYBOARD_EPSIZE,
+        
+		.ReportBufferSize        = sizeof(USB_KeyboardReport_Data_t),
 
+        .IdleCount               = 500,
+    };
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the USB management task.
- */
 int main(void)
 {
-	/* Disable watchdog if enabled by bootloader/fuses */
-	MCUSR &= ~(1 << WDRF);
-	wdt_disable();
-
-	/* Disable clock division */
-	clock_prescale_set(clock_div_1);
-
-	/* Hardware Initialization */
-	Joystick_Init();
-	LEDs_Init();
-	
-	/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
-	OCR0A  = 0x7D;
-	TCCR0A = (1 << WGM01);
-	TCCR0B = ((1 << CS01) | (1 << CS00));
-	TIMSK0 = (1 << OCIE0A);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
+    SetupHardware();
+
+    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+    
+    for (;;)
+    {
+        USB_HID_USBTask(&Keyboard_HID_Interface);
+        USB_USBTask();
+    }
+}
 
-	/* Initialize USB Subsystem */
-	USB_Init();
-	
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
+void SetupHardware()
+{
+    /* Disable watchdog if enabled by bootloader/fuses */
+    MCUSR &= ~(1 << WDRF);
+    wdt_disable();
+
+    /* Disable clock division */
+    clock_prescale_set(clock_div_1);
+
+    /* Hardware Initialization */
+    Joystick_Init();
+    LEDs_Init();
+    Buttons_Init();
+    USB_Init();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-
-	/* Default to report protocol on connect */
-	UsingReportProtocol = true;
+    LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running keyboard reporting and USB management tasks */
-	Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- *  of the USB device after enumeration, and configures the keyboard device endpoints.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Keyboard Keycode Report Endpoint */
-	Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Setup Keyboard LED Report Endpoint */
-	Endpoint_ConfigureEndpoint(KEYBOARD_LEDS_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_OUT, KEYBOARD_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+    LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-
-	/* Start running keyboard reporting task */
-	Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);
+    if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))
+      LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the HID commands, which are
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				USB_KeyboardReport_Data_t KeyboardReportData;
-
-				Endpoint_ClearSETUP();
-	
-				/* Create the next keyboard report for transmission to the host */
-				CreateKeyboardReport(&KeyboardReportData);
-
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-		case REQ_SetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Wait until the LED report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
-
-				/* Read in the LED report from the host */
-				uint8_t LEDStatus = Endpoint_Read_Byte();
-
-				/* Process the incoming LED report */
-				ProcessLEDReport(LEDStatus);
-			
-				/* Clear the endpoint data */
-				Endpoint_ClearOUT();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_GetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Write the current protocol flag to the host */
-				Endpoint_Write_Byte(UsingReportProtocol);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-
-				/* Set or clear the flag depending on what the host indicates that the current Protocol should be */
-				UsingReportProtocol = (USB_ControlRequest.wValue != 0);
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_SetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Get idle period in MSB */
-				IdleCount = (USB_ControlRequest.wValue >> 8);
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_GetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{		
-				Endpoint_ClearSETUP();
-				
-				/* Write the current idle duration to the host */
-				Endpoint_Write_Byte(IdleCount);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-
-			break;
-	}
+    USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
 }
 
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the
- *  scheduler elapsed idle period counter when the host has set an idle period.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
 {
-	/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
-	if (IdleMSRemaining)
-	  IdleMSRemaining--;
-}
-
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- *  \param ReportData  Pointer to a HID report data structure to be filled
- */
-void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData)
-{
-	uint8_t JoyStatus_LCL = Joystick_GetStatus();
-
-	/* Clear the report contents */
-	memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
-
-	if (JoyStatus_LCL & JOY_UP)
-	  ReportData->KeyCode[0] = 0x04; // A
-	else if (JoyStatus_LCL & JOY_DOWN)
-	  ReportData->KeyCode[0] = 0x05; // B
-
-	if (JoyStatus_LCL & JOY_LEFT)
-	  ReportData->KeyCode[0] = 0x06; // C
-	else if (JoyStatus_LCL & JOY_RIGHT)
-	  ReportData->KeyCode[0] = 0x07; // D
-
-	if (JoyStatus_LCL & JOY_PRESS)
-	  ReportData->KeyCode[0] = 0x08; // E
-}
-
-/** Processes a received LED report, and updates the board LEDs states to match.
- *
- *  \param LEDReport  LED status report from the host
- */
-void ProcessLEDReport(uint8_t LEDReport)
-{
-	uint8_t LEDMask = LEDS_LED2;
-	
-	if (LEDReport & 0x01) // NUM Lock
-	  LEDMask |= LEDS_LED1;
-	
-	if (LEDReport & 0x02) // CAPS Lock
-	  LEDMask |= LEDS_LED3;
-
-	if (LEDReport & 0x04) // SCROLL Lock
-	  LEDMask |= LEDS_LED4;
-
-	/* Set the status LEDs to the current Keyboard LED status */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Sends the next HID report to the host, via the keyboard data endpoint. */
-void SendNextReport(void)
-{
-	static USB_KeyboardReport_Data_t PrevKeyboardReportData;
-	USB_KeyboardReport_Data_t        KeyboardReportData;
-	bool                             SendReport = true;
-	
-	/* Create the next keyboard report for transmission to the host */
-	CreateKeyboardReport(&KeyboardReportData);
-	
-	/* Check to see if the report data has changed - if so a report MUST be sent */
-	SendReport = (memcmp(&PrevKeyboardReportData, &KeyboardReportData, sizeof(USB_KeyboardReport_Data_t)) != 0);
-	
-	/* Save the current report data for later comparison to check for changes */
-	PrevKeyboardReportData = KeyboardReportData;
-	
-	/* Check if the idle period is set and has elapsed */
-	if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))
-	{
-		/* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
-		IdleMSRemaining = (IdleCount << 2);
-		
-		/* Idle period is set and has elapsed, must send a report to the host */
-		SendReport = true;
-	}
-	
-	/* Select the Keyboard Report Endpoint */
-	Endpoint_SelectEndpoint(KEYBOARD_EPNUM);
-
-	/* Check if Keyboard Endpoint Ready for Read/Write and if we should send a new report */
-	if (Endpoint_IsReadWriteAllowed() && SendReport)
-	{
-		/* Write Keyboard Report Data */
-		Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-		
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
-	}
-}
-
-/** Reads the next LED status report from the host from the LED data endpoint, if one has been sent. */
-void ReceiveNextReport(void)
-{
-	/* Select the Keyboard LED Report Endpoint */
-	Endpoint_SelectEndpoint(KEYBOARD_LEDS_EPNUM);
-
-	/* Check if Keyboard LED Endpoint contains a packet */
-	if (Endpoint_IsOUTReceived())
-	{
-		/* Check to see if the packet contains data */
-		if (Endpoint_IsReadWriteAllowed())
-		{
-			/* Read in the LED report from the host */
-			uint8_t LEDReport = Endpoint_Read_Byte();
-
-			/* Process the read LED report from the host */
-			ProcessLEDReport(LEDReport);
-		}
-
-		/* Handshake the OUT Endpoint - clear endpoint and ready for next report */
-		Endpoint_ClearOUT();
-	}
+    USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the Keyboard_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
+    USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+    
+    uint8_t JoyStatus_LCL    = Joystick_GetStatus();
+    uint8_t ButtonStatus_LCL = Buttons_GetStatus();
+
+    if (JoyStatus_LCL & JOY_UP)
+      KeyboardReport->KeyCode[0] = 0x04; // A
+    else if (JoyStatus_LCL & JOY_DOWN)
+      KeyboardReport->KeyCode[0] = 0x05; // B
+
+    if (JoyStatus_LCL & JOY_LEFT)
+      KeyboardReport->KeyCode[0] = 0x06; // C
+    else if (JoyStatus_LCL & JOY_RIGHT)
+      KeyboardReport->KeyCode[0] = 0x07; // D
+
+    if (JoyStatus_LCL & JOY_PRESS)
+      KeyboardReport->KeyCode[0] = 0x08; // E
+      
+    if (ButtonStatus_LCL & BUTTONS_BUTTON1)
+      KeyboardReport->KeyCode[0] = 0x09; // F
+      
+    return sizeof(USB_KeyboardReport_Data_t);
 }
 
-/** Function to manage HID report generation and transmission to the host, when in report mode. */
-TASK(USB_Keyboard_Report)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
 {
-	/* Check if the USB system is connected to a host */
-	if (USB_IsConnected)
-	{
-		/* Send the next keypress report to the host */
-		SendNextReport();
-		
-		/* Process the LED report sent from the host */
-		ReceiveNextReport();
-	}
+    uint8_t  LEDMask   = LEDS_NO_LEDS;
+    uint8_t* LEDReport = (uint8_t*)ReportData;
+
+    if (*LEDReport & 0x01) // NUM Lock
+      LEDMask |= LEDS_LED1;
+    
+    if (*LEDReport & 0x02) // CAPS Lock
+      LEDMask |= LEDS_LED3;
+
+    if (*LEDReport & 0x04) // SCROLL Lock
+      LEDMask |= LEDS_LED4;
+      
+    LEDs_SetAllLEDs(LEDMask);
 }
diff --git a/Demos/Device/Keyboard/Keyboard.h b/Demos/Device/Keyboard/Keyboard.h
index c4ed6e07c..eeb7be9b7 100644
--- a/Demos/Device/Keyboard/Keyboard.h
+++ b/Demos/Device/Keyboard/Keyboard.h
@@ -47,36 +47,12 @@
 
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-
-	/* Macros: */
-		/** Idle period indicating that reports should be sent only when the inputs have changed */
-		#define HID_IDLE_CHANGESONLY   0
-
-		/** HID Class specific request to get the next HID report from the device. */
-		#define REQ_GetReport          0x01
-
-		/** HID Class specific request to get the idle timeout period of the device. */
-		#define REQ_GetIdle            0x02
-
-		/** HID Class specific request to send the next HID report to the device. */
-		#define REQ_SetReport          0x09
-
-		/** HID Class specific request to set the idle timeout period of the device. */
-		#define REQ_SetIdle            0x0A
-
-		/** HID Class specific request to get the current HID protocol in use, either report or boot. */
-		#define REQ_GetProtocol        0x03
-
-		/** HID Class specific request to set the current HID protocol in use, either report or boot. */
-		#define REQ_SetProtocol        0x0B
-		
-	/* Task Definitions: */
-		TASK(USB_Keyboard_Report);
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Buttons.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
 	/* Type Defines: */
 		/** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.
@@ -89,25 +65,23 @@
 			uint8_t KeyCode[6]; /**< Array of up to six simultaneous key codes of pressed keys */
 		} USB_KeyboardReport_Data_t;
 			
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum Keyboard_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
+		void EVENT_USB_StartOfFrame(void);
 
-		void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData);
-		void ProcessLEDReport(uint8_t LEDReport);
-		void SendNextReport(void);
-		void ReceiveNextReport(void);
-		void UpdateStatus(uint8_t CurrentStatus);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/Demos/Device/Keyboard/makefile b/Demos/Device/Keyboard/makefile
index 88e4de0e6..98cda2f89 100644
--- a/Demos/Device/Keyboard/makefile
+++ b/Demos/Device/Keyboard/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/KeyboardMouse/Descriptors.h b/Demos/Device/KeyboardMouse/Descriptors.h
index 43c345a21..152e5111a 100644
--- a/Demos/Device/KeyboardMouse/Descriptors.h
+++ b/Demos/Device/KeyboardMouse/Descriptors.h
@@ -38,30 +38,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
-		 *  specification for details on the structure elements.
-		 */
-		typedef struct
-		{
-			USB_Descriptor_Header_t               Header;
-				
-			uint16_t                              HIDSpec;
-			uint8_t                               CountryCode;
-		
-			uint8_t                               TotalReportDescriptors;
-
-			uint8_t                               HIDReportType;
-			uint16_t                              HIDReportLength;
-		} USB_Descriptor_HID_t;
-
-		/** Type define for the data type used to store HID report descriptor elements. */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -91,12 +73,6 @@
 		/** Size in bytes of each of the HID reporting IN and OUT endpoints. */
 		#define HID_EPSIZE                8
 
-		/** Descriptor header type value, to indicate a HID class HID descriptor. */
-		#define DTYPE_HID                 0x21
-		
-		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
-		#define DTYPE_Report              0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
 											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.c b/Demos/Device/KeyboardMouse/KeyboardMouse.c
index 25d633e43..8f6a573a6 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.c
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.c
@@ -28,34 +28,52 @@
   arising out of or in connection with the use or performance of
   this software.
 */
-
-/** \file
- *
- *  Main source file for the KeyboardMouse demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
  
 #include "KeyboardMouse.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask               , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Mouse                 , .TaskStatus = TASK_RUN  },
-	{ .Task = USB_Keyboard              , .TaskStatus = TASK_RUN  },
-};
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
+
+		.ReportINEndpointNumber  = KEYBOARD_IN_EPNUM,
+		.ReportINEndpointSize    = HID_EPSIZE,
+
+		.ReportOUTEndpointNumber = KEYBOARD_OUT_EPNUM,
+		.ReportOUTEndpointSize   = HID_EPSIZE,
+		
+		.ReportBufferSize        = sizeof(USB_KeyboardReport_Data_t),
+
+		.IdleCount               = 500,
+	};
+	
+USB_ClassInfo_HID_t Mouse_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
 
-/* Global Variables */
-/** Global structure to hold the current keyboard interface HID report, for transmission to the host */
-USB_KeyboardReport_Data_t KeyboardReportData;
+		.ReportINEndpointNumber  = MOUSE_IN_EPNUM,
+		.ReportINEndpointSize    = HID_EPSIZE,
 
-/** Global structure to hold the current mouse interface HID report, for transmission to the host */
-USB_MouseReport_Data_t    MouseReportData;
+		.ReportBufferSize        = sizeof(USB_MouseReport_Data_t),
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the USB management task.
- */
+		.ReportOUTEndpointNumber = 0,
+		.ReportOUTEndpointSize   = 0,
+	};
+	
 int main(void)
+{
+	SetupHardware();
+
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+	for (;;)
+	{
+		USB_HID_USBTask(&Keyboard_HID_Interface);
+		USB_HID_USBTask(&Mouse_HID_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware()
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -67,284 +85,111 @@ int main(void)
 	/* Hardware Initialization */
 	Joystick_Init();
 	LEDs_Init();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
-	USB_Init();
-	
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
+	USB_Init();	
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management task.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running HID reporting and USB management tasks */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- *  of the USB device after enumeration, and configures the keyboard and mouse device endpoints.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Keyboard Report Endpoint */
-	Endpoint_ConfigureEndpoint(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, HID_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Setup Keyboard LED Report Endpoint */
-	Endpoint_ConfigureEndpoint(KEYBOARD_OUT_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_OUT, HID_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Setup Mouse Report Endpoint */
-	Endpoint_ConfigureEndpoint(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, HID_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
+	if (!(USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+	
+	if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the HID commands, which are
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	uint8_t* ReportData;
-	uint8_t  ReportSize;
-
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-	
-				/* Determine if it is the mouse or the keyboard data that is being requested */
-				if (!(USB_ControlRequest.wIndex))
-				{
-					ReportData = (uint8_t*)&KeyboardReportData;
-					ReportSize = sizeof(KeyboardReportData);
-				}
-				else
-				{
-					ReportData = (uint8_t*)&MouseReportData;
-					ReportSize = sizeof(MouseReportData);
-				}
-
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
-
-				/* Clear the report data afterwards */
-				memset(ReportData, 0, ReportSize);
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-		case REQ_SetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Wait until the LED report has been sent by the host */
-				while (!(Endpoint_IsOUTReceived()));
-
-				/* Read in the LED report from the host */
-				uint8_t LEDStatus = Endpoint_Read_Byte();
-				uint8_t LEDMask   = LEDS_LED2;
-				
-				if (LEDStatus & 0x01) // NUM Lock
-				  LEDMask |= LEDS_LED1;
-				
-				if (LEDStatus & 0x02) // CAPS Lock
-				  LEDMask |= LEDS_LED3;
-
-				if (LEDStatus & 0x04) // SCROLL Lock
-				  LEDMask |= LEDS_LED4;
-
-				/* Set the status LEDs to the current HID LED status */
-				LEDs_SetAllLEDs(LEDMask);
-
-				/* Clear the endpoint data */
-				Endpoint_ClearOUT();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-	}
+	USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
+	USB_HID_ProcessControlPacket(&Mouse_HID_Interface);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the KeyboardMouse_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void EVENT_USB_StartOfFrame(void)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
+	USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
+	USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);
 }
 
-/** Keyboard task. This generates the next keyboard HID report for the host, and transmits it via the
- *  keyboard IN endpoint when the host is ready for more data. Additionally, it processes host LED status
- *  reports sent to the device via the keyboard OUT reporting endpoint.
- */
-TASK(USB_Keyboard)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
 {
-	uint8_t JoyStatus_LCL = Joystick_GetStatus();
+	uint8_t JoyStatus_LCL    = Joystick_GetStatus();
+	uint8_t ButtonStatus_LCL = Buttons_GetStatus();
 
-	/* Check if board button is not pressed, if so mouse mode enabled */
-	if (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
+	if (HIDInterfaceInfo == &Keyboard_HID_Interface)
 	{
+		USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+		
+		/* If first board button not being held down, no keyboard report */
+		if (!(ButtonStatus_LCL & BUTTONS_BUTTON1))
+		  return 0;
+		
 		if (JoyStatus_LCL & JOY_UP)
-		  KeyboardReportData.KeyCode[0] = 0x04; // A
+		  KeyboardReport->KeyCode[0] = 0x04; // A
 		else if (JoyStatus_LCL & JOY_DOWN)
-		  KeyboardReportData.KeyCode[0] = 0x05; // B
+		  KeyboardReport->KeyCode[0] = 0x05; // B
 
 		if (JoyStatus_LCL & JOY_LEFT)
-		  KeyboardReportData.KeyCode[0] = 0x06; // C
+		  KeyboardReport->KeyCode[0] = 0x06; // C
 		else if (JoyStatus_LCL & JOY_RIGHT)
-		  KeyboardReportData.KeyCode[0] = 0x07; // D
+		  KeyboardReport->KeyCode[0] = 0x07; // D
 
 		if (JoyStatus_LCL & JOY_PRESS)
-		  KeyboardReportData.KeyCode[0] = 0x08; // E
+		  KeyboardReport->KeyCode[0] = 0x08; // E
+		  
+		return sizeof(USB_KeyboardReport_Data_t);
 	}
-	
-	/* Check if the USB system is connected to a host and report protocol mode is enabled */
-	if (USB_IsConnected)
+	else
 	{
-		/* Select the Keyboard Report Endpoint */
-		Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
-
-		/* Check if Keyboard Endpoint Ready for Read/Write */
-		if (Endpoint_IsReadWriteAllowed())
-		{
-			/* Write Keyboard Report Data */
-			Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearIN();
-
-			/* Clear the report data afterwards */
-			memset(&KeyboardReportData, 0, sizeof(KeyboardReportData));
-		}
+		USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
 
-		/* Select the Keyboard LED Report Endpoint */
-		Endpoint_SelectEndpoint(KEYBOARD_OUT_EPNUM);
-
-		/* Check if Keyboard LED Endpoint Ready for Read/Write */
-		if (Endpoint_IsReadWriteAllowed())
-		{		
-			/* Read in the LED report from the host */
-			uint8_t LEDStatus = Endpoint_Read_Byte();
-			uint8_t LEDMask   = LEDS_LED2;
-			
-			if (LEDStatus & 0x01) // NUM Lock
-			  LEDMask |= LEDS_LED1;
-			
-			if (LEDStatus & 0x02) // CAPS Lock
-			  LEDMask |= LEDS_LED3;
-
-			if (LEDStatus & 0x04) // SCROLL Lock
-			  LEDMask |= LEDS_LED4;
-
-			/* Set the status LEDs to the current Keyboard LED status */
-			LEDs_SetAllLEDs(LEDMask);
-
-			/* Handshake the OUT Endpoint - clear endpoint and ready for next report */
-			Endpoint_ClearOUT();
-		}
-	}
-}
-
-/** Mouse task. This generates the next mouse HID report for the host, and transmits it via the
- *  mouse IN endpoint when the host is ready for more data.
- */
-TASK(USB_Mouse)
-{
-	uint8_t JoyStatus_LCL = Joystick_GetStatus();
-
-	/* Check if board button is pressed, if so mouse mode enabled */
-	if (Buttons_GetStatus() & BUTTONS_BUTTON1)
-	{
+		/* If first board button being held down, no mouse report */
+		if (ButtonStatus_LCL & BUTTONS_BUTTON1)
+		  return 0;
+		  
 		if (JoyStatus_LCL & JOY_UP)
-		  MouseReportData.Y =  1;
+		  MouseReport->Y = -1;
 		else if (JoyStatus_LCL & JOY_DOWN)
-		  MouseReportData.Y = -1;
+		  MouseReport->Y =  1;
 
 		if (JoyStatus_LCL & JOY_RIGHT)
-		  MouseReportData.X =  1;
+		  MouseReport->X =  1;
 		else if (JoyStatus_LCL & JOY_LEFT)
-		  MouseReportData.X = -1;
+		  MouseReport->X = -1;
 
 		if (JoyStatus_LCL & JOY_PRESS)
-		  MouseReportData.Button  = (1 << 0);
+		  MouseReport->Button  = (1 << 0);
+		
+		return sizeof(USB_MouseReport_Data_t);		
 	}
+}
 
-	/* Check if the USB system is connected to a host and report protocol mode is enabled */
-	if (USB_IsConnected)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+{
+	if (HIDInterfaceInfo == &Keyboard_HID_Interface)
 	{
-		/* Select the Mouse Report Endpoint */
-		Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
-
-		/* Check if Mouse Endpoint Ready for Read/Write */
-		if (Endpoint_IsReadWriteAllowed())
-		{
-			/* Write Mouse Report Data */
-			Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));
+		uint8_t  LEDMask   = LEDS_NO_LEDS;
+		uint8_t* LEDReport = (uint8_t*)ReportData;
 
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearIN();
+		if (*LEDReport & 0x01) // NUM Lock
+		  LEDMask |= LEDS_LED1;
+		
+		if (*LEDReport & 0x02) // CAPS Lock
+		  LEDMask |= LEDS_LED3;
 
-			/* Clear the report data afterwards */
-			memset(&MouseReportData, 0, sizeof(MouseReportData));
-		}
+		if (*LEDReport & 0x04) // SCROLL Lock
+		  LEDMask |= LEDS_LED4;
+		  
+		LEDs_SetAllLEDs(LEDMask);
 	}
-}
+}
\ No newline at end of file
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.h b/Demos/Device/KeyboardMouse/KeyboardMouse.h
index e3f943402..a5c3c5db2 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.h
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.h
@@ -41,38 +41,18 @@
 
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-		#include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-		
-	/* Task Definitions: */
-		TASK(USB_Keyboard);
-		TASK(USB_Mouse);
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Buttons.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum KeyboardMouse_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-		
 	/* Macros: */
-		/** HID Class specific request to get the next HID report from the device. */
-		#define REQ_GetReport      0x01
-
-		/** HID Class specific request to send the next HID report to the device. */
-		#define REQ_SetReport      0x09
-
-		/** HID Class specific request to get the current HID protocol in use, either report or boot. */
-		#define REQ_GetProtocol    0x03
-
-		/** HID Class specific request to set the current HID protocol in use, either report or boot. */
-		#define REQ_SetProtocol    0x0B
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
 	/* Type Defines: */
 		/** Type define for the keyboard HID report structure, for creating and sending HID reports to the host PC.
@@ -96,11 +76,16 @@
 		} USB_MouseReport_Data_t;
 			
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
+		void EVENT_USB_StartOfFrame(void);
 
-		void UpdateStatus(uint8_t CurrentStatus);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 		
 #endif
diff --git a/Demos/Device/KeyboardMouse/makefile b/Demos/Device/KeyboardMouse/makefile
index c6b34d96e..ddad7d24b 100644
--- a/Demos/Device/KeyboardMouse/makefile
+++ b/Demos/Device/KeyboardMouse/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -183,7 +182,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/MIDI/makefile b/Demos/Device/MIDI/makefile
index 18fc3b154..485cdc710 100644
--- a/Demos/Device/MIDI/makefile
+++ b/Demos/Device/MIDI/makefile
@@ -183,7 +183,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.c b/Demos/Device/MassStorage/Lib/DataflashManager.c
index 4b624190f..87edef12b 100644
--- a/Demos/Device/MassStorage/Lib/DataflashManager.c
+++ b/Demos/Device/MassStorage/Lib/DataflashManager.c
@@ -46,7 +46,7 @@
  *  \param BlockAddress  Data block starting address for the write sequence
  *  \param TotalBlocks   Number of blocks of data to write
  */
-void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)
+void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
 {
 	uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
 	uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
@@ -142,7 +142,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
 			BytesInBlockDiv16++;
 
 			/* Check if the current command is being aborted by the host */
-			if (IsMassStoreReset)
+			if (MSInterfaceInfo->IsMassStoreReset)
 			  return;			
 		}
 			
@@ -171,7 +171,7 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
  *  \param BlockAddress  Data block starting address for the read sequence
  *  \param TotalBlocks   Number of blocks of data to read
  */
-void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)
+void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks)
 {
 	uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
 	uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
@@ -250,7 +250,7 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
 			BytesInBlockDiv16++;
 
 			/* Check if the current command is being aborted by the host */
-			if (IsMassStoreReset)
+			if (MSInterfaceInfo->IsMassStoreReset)
 			  return;
 		}
 		
@@ -341,11 +341,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
 			CurrDFPageByteDiv16++;
 
 			/* Increment the block 16 byte block counter */
-			BytesInBlockDiv16++;
-
-			/* Check if the current command is being aborted by the host */
-			if (IsMassStoreReset)
-			  return;			
+			BytesInBlockDiv16++;		
 		}
 			
 		/* Decrement the blocks remaining counter and reset the sub block counter */
@@ -421,10 +417,6 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total
 			
 			/* Increment the block 16 byte block counter */
 			BytesInBlockDiv16++;
-
-			/* Check if the current command is being aborted by the host */
-			if (IsMassStoreReset)
-			  return;
 		}
 		
 		/* Decrement the blocks remaining counter */
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.h b/Demos/Device/MassStorage/Lib/DataflashManager.h
index 1332fd3a3..b828051aa 100644
--- a/Demos/Device/MassStorage/Lib/DataflashManager.h
+++ b/Demos/Device/MassStorage/Lib/DataflashManager.h
@@ -64,8 +64,8 @@
 		#define VIRTUAL_MEMORY_BLOCKS               (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
 		
 	/* Function Prototypes: */
-		void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);
-		void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);
+		void DataflashManager_WriteBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);
+		void DataflashManager_ReadBlocks(USB_ClassInfo_MS_t* MSInterfaceInfo, const uint32_t BlockAddress, uint16_t TotalBlocks);
 		void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
 		                                      uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);
 		void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,
diff --git a/Demos/Device/MassStorage/Lib/SCSI.c b/Demos/Device/MassStorage/Lib/SCSI.c
index 5993a546d..8f3167a47 100644
--- a/Demos/Device/MassStorage/Lib/SCSI.c
+++ b/Demos/Device/MassStorage/Lib/SCSI.c
@@ -84,37 +84,37 @@ SCSI_Request_Sense_Response_t SenseData =
  *  to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
  *  a command failure due to a ILLEGAL REQUEST.
  */
-void SCSI_DecodeSCSICommand(void)
+bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
 	bool CommandSuccess = false;
 
 	/* Run the appropriate SCSI command hander function based on the passed command */
-	switch (CommandBlock.SCSICommandData[0])
+	switch (MSInterfaceInfo->CommandBlock.SCSICommandData[0])
 	{
 		case SCSI_CMD_INQUIRY:
-			CommandSuccess = SCSI_Command_Inquiry();			
+			CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);			
 			break;
 		case SCSI_CMD_REQUEST_SENSE:
-			CommandSuccess = SCSI_Command_Request_Sense();
+			CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
 			break;
 		case SCSI_CMD_READ_CAPACITY_10:
-			CommandSuccess = SCSI_Command_Read_Capacity_10();			
+			CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);			
 			break;
 		case SCSI_CMD_SEND_DIAGNOSTIC:
-			CommandSuccess = SCSI_Command_Send_Diagnostic();
+			CommandSuccess = SCSI_Command_Send_Diagnostic(MSInterfaceInfo);
 			break;
 		case SCSI_CMD_WRITE_10:
-			CommandSuccess = SCSI_Command_ReadWrite_10(DATA_WRITE);
+			CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
 			break;
 		case SCSI_CMD_READ_10:
-			CommandSuccess = SCSI_Command_ReadWrite_10(DATA_READ);
+			CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
 			break;
 		case SCSI_CMD_TEST_UNIT_READY:
 		case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
 		case SCSI_CMD_VERIFY_10:
 			/* These commands should just succeed, no handling required */
 			CommandSuccess = true;
-			CommandBlock.DataTransferLength = 0;
+			MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
 			break;
 		default:
 			/* Update the SENSE key to reflect the invalid command */
@@ -123,22 +123,18 @@ void SCSI_DecodeSCSICommand(void)
 		                   SCSI_ASENSEQ_NO_QUALIFIER);
 			break;
 	}
-	
+
 	/* Check if command was successfully processed */
 	if (CommandSuccess)
 	{
-		/* Command succeeded - set the CSW status and update the SENSE key */
-		CommandStatus.Status = Command_Pass;
-		
 		SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
 		               SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
-		               SCSI_ASENSEQ_NO_QUALIFIER);					   
-	}
-	else
-	{
-		/* Command failed - set the CSW status - failed command function updates the SENSE key */
-		CommandStatus.Status = Command_Fail;
+		               SCSI_ASENSEQ_NO_QUALIFIER);
+		
+		return true;
 	}
+
+	return false;
 }
 
 /** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
@@ -146,16 +142,16 @@ void SCSI_DecodeSCSICommand(void)
  *
  *  \return Boolean true if the command completed successfully, false otherwise.
  */
-static bool SCSI_Command_Inquiry(void)
+static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
-	uint16_t AllocationLength  = (((uint16_t)CommandBlock.SCSICommandData[3] << 8) |
-	                                         CommandBlock.SCSICommandData[4]);
+	uint16_t AllocationLength  = (((uint16_t)MSInterfaceInfo->CommandBlock.SCSICommandData[3] << 8) |
+	                                         MSInterfaceInfo->CommandBlock.SCSICommandData[4]);
 	uint16_t BytesTransferred  = (AllocationLength < sizeof(InquiryData))? AllocationLength :
 	                                                                       sizeof(InquiryData);
 
 	/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
-	if ((CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
-	     CommandBlock.SCSICommandData[2])
+	if ((MSInterfaceInfo->CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
+	     MSInterfaceInfo->CommandBlock.SCSICommandData[2])
 	{
 		/* Optional but unsupported bits set - update the SENSE key and fail the request */
 		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
@@ -164,20 +160,19 @@ static bool SCSI_Command_Inquiry(void)
 
 		return false;
 	}
-
-	/* Write the INQUIRY data to the endpoint */
-	Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);
+	
+	Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NO_STREAM_CALLBACK);
 
 	uint8_t PadBytes[AllocationLength - BytesTransferred];
 	
 	/* Pad out remaining bytes with 0x00 */
-	Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);
+	Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
 
 	/* Finalize the stream transfer to send the last packet */
 	Endpoint_ClearIN();
 
 	/* Succeed the command and update the bytes transferred counter */
-	CommandBlock.DataTransferLength -= BytesTransferred;
+	MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
 	
 	return true;
 }
@@ -187,24 +182,19 @@ static bool SCSI_Command_Inquiry(void)
  *
  *  \return Boolean true if the command completed successfully, false otherwise.
  */
-static bool SCSI_Command_Request_Sense(void)
+static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
-	uint8_t  AllocationLength = CommandBlock.SCSICommandData[4];
+	uint8_t  AllocationLength = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
 	uint8_t  BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);
 	
-	/* Send the SENSE data - this indicates to the host the status of the last command */
-	Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);
-	
 	uint8_t PadBytes[AllocationLength - BytesTransferred];
-	
-	/* Pad out remaining bytes with 0x00 */
-	Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);
 
-	/* Finalize the stream transfer to send the last packet */
+	Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NO_STREAM_CALLBACK);
+	Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), NO_STREAM_CALLBACK);
 	Endpoint_ClearIN();
 
 	/* Succeed the command and update the bytes transferred counter */
-	CommandBlock.DataTransferLength -= BytesTransferred;
+	MSInterfaceInfo->CommandBlock.DataTransferLength -= BytesTransferred;
 
 	return true;
 }
@@ -214,23 +204,17 @@ static bool SCSI_Command_Request_Sense(void)
  *
  *  \return Boolean true if the command completed successfully, false otherwise.
  */
-static bool SCSI_Command_Read_Capacity_10(void)
+static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
-	/* Send the total number of logical blocks in the current LUN */
-	Endpoint_Write_DWord_BE(LUN_MEDIA_BLOCKS - 1);
+	uint32_t TotalLUNs      = (LUN_MEDIA_BLOCKS - 1);
+	uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE;
 
-	/* Send the logical block size of the device (must be 512 bytes) */
-	Endpoint_Write_DWord_BE(VIRTUAL_MEMORY_BLOCK_SIZE);
-
-	/* Check if the current command is being aborted by the host */
-	if (IsMassStoreReset)
-	  return false;
-
-	/* Send the endpoint data packet to the host */
+	Endpoint_Write_Stream_BE(&TotalLUNs, sizeof(TotalLUNs), NO_STREAM_CALLBACK);
+	Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK);
 	Endpoint_ClearIN();
-
+	
 	/* Succeed the command and update the bytes transferred counter */
-	CommandBlock.DataTransferLength -= 8;
+	MSInterfaceInfo->CommandBlock.DataTransferLength -= 8;
 	
 	return true;
 }
@@ -241,12 +225,12 @@ static bool SCSI_Command_Read_Capacity_10(void)
  *
  *  \return Boolean true if the command completed successfully, false otherwise.
  */
-static bool SCSI_Command_Send_Diagnostic(void)
+static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
 	uint8_t ReturnByte;
 
 	/* Check to see if the SELF TEST bit is not set */
-	if (!(CommandBlock.SCSICommandData[1] & (1 << 2)))
+	if (!(MSInterfaceInfo->CommandBlock.SCSICommandData[1] & (1 << 2)))
 	{
 		/* Only self-test supported - update SENSE key and fail the command */
 		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
@@ -293,7 +277,7 @@ static bool SCSI_Command_Send_Diagnostic(void)
 	#endif
 	
 	/* Succeed the command and update the bytes transferred counter */
-	CommandBlock.DataTransferLength = 0;
+	MSInterfaceInfo->CommandBlock.DataTransferLength = 0;
 	
 	return true;
 }
@@ -306,20 +290,20 @@ static bool SCSI_Command_Send_Diagnostic(void)
  *
  *  \return Boolean true if the command completed successfully, false otherwise.
  */
-static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
+static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead)
 {
 	uint32_t BlockAddress;
 	uint16_t TotalBlocks;
 	
 	/* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */
-	((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2];
-	((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];
-	((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];
-	((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];
+	((uint8_t*)&BlockAddress)[3] = MSInterfaceInfo->CommandBlock.SCSICommandData[2];
+	((uint8_t*)&BlockAddress)[2] = MSInterfaceInfo->CommandBlock.SCSICommandData[3];
+	((uint8_t*)&BlockAddress)[1] = MSInterfaceInfo->CommandBlock.SCSICommandData[4];
+	((uint8_t*)&BlockAddress)[0] = MSInterfaceInfo->CommandBlock.SCSICommandData[5];
 
 	/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */
-	((uint8_t*)&TotalBlocks)[1]  = CommandBlock.SCSICommandData[7];
-	((uint8_t*)&TotalBlocks)[0]  = CommandBlock.SCSICommandData[8];
+	((uint8_t*)&TotalBlocks)[1]  = MSInterfaceInfo->CommandBlock.SCSICommandData[7];
+	((uint8_t*)&TotalBlocks)[0]  = MSInterfaceInfo->CommandBlock.SCSICommandData[8];
 	
 	/* Check if the block address is outside the maximum allowable value for the LUN */
 	if (BlockAddress >= LUN_MEDIA_BLOCKS)
@@ -334,17 +318,17 @@ static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
 
 	#if (TOTAL_LUNS > 1)
 	/* Adjust the given block address to the real media address based on the selected LUN */
-	BlockAddress += ((uint32_t)CommandBlock.LUN * LUN_MEDIA_BLOCKS);
+	BlockAddress += ((uint32_t)MSInterfaceInfo->CommandBlock.LUN * LUN_MEDIA_BLOCKS);
 	#endif
 	
 	/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
 	if (IsDataRead == DATA_READ)
-	  DataflashManager_ReadBlocks(BlockAddress, TotalBlocks);
+	  DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
 	else
-	  DataflashManager_WriteBlocks(BlockAddress, TotalBlocks);
+	  DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks);
 
 	/* Update the bytes transferred counter and succeed the command */
-	CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
+	MSInterfaceInfo->CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);
 	
 	return true;
 }
diff --git a/Demos/Device/MassStorage/Lib/SCSI.h b/Demos/Device/MassStorage/Lib/SCSI.h
index d7693cafb..3fd751dee 100644
--- a/Demos/Device/MassStorage/Lib/SCSI.h
+++ b/Demos/Device/MassStorage/Lib/SCSI.h
@@ -40,9 +40,8 @@
 		#include <avr/io.h>
 		#include <avr/pgmspace.h>
 
-		#include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/MassStorage.h>
 
 		#include "MassStorage.h"
 		#include "Descriptors.h"
@@ -63,16 +62,16 @@
 		                                                   SenseData.AdditionalSenseQualifier = aqual; }MACROE
 
 		/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
-		#define DATA_READ      true
+		#define DATA_READ           true
 
 		/** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
-		#define DATA_WRITE     false
+		#define DATA_WRITE          false
 
 		/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
-		#define DEVICE_TYPE_BLOCK 0x00
+		#define DEVICE_TYPE_BLOCK   0x00
 		
 		/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */
-		#define DEVICE_TYPE_CDROM 0x05
+		#define DEVICE_TYPE_CDROM   0x05
 
 	/* Type Defines: */
 		/** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the
@@ -136,14 +135,14 @@
 		} SCSI_Request_Sense_Response_t;
 		
 	/* Function Prototypes: */
-		void SCSI_DecodeSCSICommand(void);
+		bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_t* MSInterfaceInfo);
 		
 		#if defined(INCLUDE_FROM_SCSI_C)
-			static bool SCSI_Command_Inquiry(void);
-			static bool SCSI_Command_Request_Sense(void);
-			static bool SCSI_Command_Read_Capacity_10(void);
-			static bool SCSI_Command_Send_Diagnostic(void);
-			static bool SCSI_Command_ReadWrite_10(const bool IsDataRead);
+			static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static bool SCSI_Command_Send_Diagnostic(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_t* MSInterfaceInfo, const bool IsDataRead);
 		#endif
 		
 #endif
diff --git a/Demos/Device/MassStorage/MassStorage.c b/Demos/Device/MassStorage/MassStorage.c
index 72a230219..8e2b9f450 100644
--- a/Demos/Device/MassStorage/MassStorage.c
+++ b/Demos/Device/MassStorage/MassStorage.c
@@ -28,35 +28,35 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the Mass Storage demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
-#define  INCLUDE_FROM_MASSSTORAGE_C
 #include "MassStorage.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_MassStorage      , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_MS_t Disk_MS_Interface =
+	{
+		.InterfaceNumber        = 0,
 
-/* Global Variables */
-/** Structure to hold the latest Command Block Wrapper issued by the host, containing a SCSI command to execute. */
-CommandBlockWrapper_t  CommandBlock;
+		.DataINEndpointNumber   = MASS_STORAGE_IN_EPNUM,
+		.DataINEndpointSize     = MASS_STORAGE_IO_EPSIZE,
 
-/** Structure to hold the latest Command Status Wrapper to return to the host, containing the status of the last issued command. */
-CommandStatusWrapper_t CommandStatus = { .Signature = CSW_SIGNATURE };
+		.DataOUTEndpointNumber  = MASS_STORAGE_OUT_EPNUM,
+		.DataOUTEndpointSize    = MASS_STORAGE_IO_EPSIZE,
 
-/** Flag to asynchronously abort any in-progress data transfers upon the reception of a mass storage reset command. */
-volatile bool          IsMassStoreReset = false;
+		.TotalLUNs              = TOTAL_LUNS,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
 int main(void)
+{
+	SetupHardware();
+
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+	for (;;)
+	{
+		USB_MS_USBTask(&Disk_MS_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -68,303 +68,42 @@ int main(void)
 	/* Hardware Initialization */
 	LEDs_Init();
 	Dataflash_Init(SPI_SPEED_FCPU_DIV_2);
+	USB_Init();
 
 	/* Clear Dataflash sector protections, if enabled */
 	DataflashManager_ResetDataflashProtections();
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
-	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
 void EVENT_USB_Connect(void)
 {
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-	
-	/* Reset the MSReset flag upon connection */
-	IsMassStoreReset = false;
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the Mass Storage management task.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running mass storage task */
-	Scheduler_SetTaskMode(USB_MassStorage, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the Mass Storage management task started.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Mass Storage In and Out Endpoints */
-	Endpoint_ConfigureEndpoint(MASS_STORAGE_IN_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, MASS_STORAGE_IO_EPSIZE,
-	                           ENDPOINT_BANK_DOUBLE);
-
-	Endpoint_ConfigureEndpoint(MASS_STORAGE_OUT_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, MASS_STORAGE_IO_EPSIZE,
-	                           ENDPOINT_BANK_DOUBLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-	
-	/* Start mass storage task */
-	Scheduler_SetTaskMode(USB_MassStorage, TASK_RUN);
+	if (!(USB_MS_ConfigureEndpoints(&Disk_MS_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the Mass Storage class-specific
- *  requests) so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Process UFI specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_MassStorageReset:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-
-				/* Indicate that the current transfer should be aborted */
-				IsMassStoreReset = true;			
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-
-			break;
-		case REQ_GetMaxLUN:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-
-				/* Indicate to the host the number of supported LUNs (virtual disks) on the device */
-				Endpoint_Write_Byte(TOTAL_LUNS - 1);
-				
-				Endpoint_ClearIN();
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-	}
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the MassStorage_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-		case Status_CommandBlockError:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_ProcessingCommandBlock:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the Mass Storage interface, reading in Command Block Wrappers from the host, processing the SCSI commands they
- *  contain, and returning Command Status Wrappers back to the host to indicate the success or failure of the last issued command.
- */
-TASK(USB_MassStorage)
-{
-	/* Check if the USB System is connected to a Host */
-	if (USB_IsConnected)
-	{
-		/* Select the Data Out Endpoint */
-		Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-		
-		/* Check to see if a command from the host has been issued */
-		if (Endpoint_IsReadWriteAllowed())
-		{	
-			/* Indicate busy */
-			UpdateStatus(Status_ProcessingCommandBlock);
-
-			/* Process sent command block from the host */
-			if (ReadInCommandBlock())
-			{
-				/* Check direction of command, select Data IN endpoint if data is from the device */
-				if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
-				  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-
-				/* Decode the received SCSI command */
-				SCSI_DecodeSCSICommand();
-
-				/* Load in the CBW tag into the CSW to link them together */
-				CommandStatus.Tag = CommandBlock.Tag;
-
-				/* Load in the data residue counter into the CSW */
-				CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
-
-				/* Stall the selected data pipe if command failed (if data is still to be transferred) */
-				if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
-				  Endpoint_StallTransaction();
-
-				/* Return command status block to the host */
-				ReturnCommandStatus();
-				
-				/* Check if a Mass Storage Reset occurred */
-				if (IsMassStoreReset)
-				{
-					/* Reset the data endpoint banks */
-					Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
-					Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
-					
-					Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-					Endpoint_ClearStall();
-					Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-					Endpoint_ClearStall();
-
-					/* Clear the abort transfer flag */
-					IsMassStoreReset = false;
-				}
-
-				/* Indicate ready */
-				UpdateStatus(Status_USBReady);
-			}
-			else
-			{
-				/* Indicate error reading in the command block from the host */
-				UpdateStatus(Status_CommandBlockError);
-			}
-		}
-	}
-}
-
-/** Function to read in a command block from the host, via the bulk data OUT endpoint. This function reads in the next command block
- *  if one has been issued, and performs validation to ensure that the block command is valid.
- *
- *  \return Boolean true if a valid command block has been read in from the endpoint, false otherwise
- */
-static bool ReadInCommandBlock(void)
-{
-	/* Select the Data Out endpoint */
-	Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-
-	/* Read in command block header */
-	Endpoint_Read_Stream_LE(&CommandBlock, (sizeof(CommandBlock) - sizeof(CommandBlock.SCSICommandData)),
-	                        StreamCallback_AbortOnMassStoreReset);
-
-	/* Check if the current command is being aborted by the host */
-	if (IsMassStoreReset)
-	  return false;
-
-	/* Verify the command block - abort if invalid */
-	if ((CommandBlock.Signature != CBW_SIGNATURE) ||
-	    (CommandBlock.LUN >= TOTAL_LUNS) ||
-		(CommandBlock.SCSICommandLength > MAX_SCSI_COMMAND_LENGTH))
-	{
-		/* Stall both data pipes until reset by host */
-		Endpoint_StallTransaction();
-		Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-		Endpoint_StallTransaction();
-		
-		return false;
-	}
-
-	/* Read in command block command data */
-	Endpoint_Read_Stream_LE(&CommandBlock.SCSICommandData,
-	                        CommandBlock.SCSICommandLength,
-	                        StreamCallback_AbortOnMassStoreReset);
-	  
-	/* Check if the current command is being aborted by the host */
-	if (IsMassStoreReset)
-	  return false;
-
-	/* Finalize the stream transfer to send the last packet */
-	Endpoint_ClearOUT();
-	
-	return true;
+	USB_MS_ProcessControlPacket(&Disk_MS_Interface);
 }
 
-/** Returns the filled Command Status Wrapper back to the host via the bulk data IN endpoint, waiting for the host to clear any
- *  stalled data endpoints as needed.
- */
-static void ReturnCommandStatus(void)
+bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo)
 {
-	/* Select the Data Out endpoint */
-	Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
-
-	/* While data pipe is stalled, wait until the host issues a control request to clear the stall */
-	while (Endpoint_IsStalled())
-	{
-		/* Check if the current command is being aborted by the host */
-		if (IsMassStoreReset)
-		  return;
-	}
-
-	/* Select the Data In endpoint */
-	Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
-
-	/* While data pipe is stalled, wait until the host issues a control request to clear the stall */
-	while (Endpoint_IsStalled())
-	{
-		/* Check if the current command is being aborted by the host */
-		if (IsMassStoreReset)
-		  return;
-	}
+	bool CommandSuccess;
 	
-	/* Write the CSW to the endpoint */
-	Endpoint_Write_Stream_LE(&CommandStatus, sizeof(CommandStatus),
-	                          StreamCallback_AbortOnMassStoreReset);
-	
-	/* Check if the current command is being aborted by the host */
-	if (IsMassStoreReset)
-	  return;
-
-	/* Finalize the stream transfer to send the last packet */
-	Endpoint_ClearIN();
-}
-
-/** Stream callback function for the Endpoint stream read and write functions. This callback will abort the current stream transfer
- *  if a Mass Storage Reset request has been issued to the control endpoint.
- */
-uint8_t StreamCallback_AbortOnMassStoreReset(void)
-{	
-	/* Abort if a Mass Storage reset command was received */
-	if (IsMassStoreReset)
-	  return STREAMCALLBACK_Abort;
+	LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+	CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 	
-	/* Continue with the current stream operation */
-	return STREAMCALLBACK_Continue;
+	return CommandSuccess;
 }
diff --git a/Demos/Device/MassStorage/MassStorage.h b/Demos/Device/MassStorage/MassStorage.h
index cbd3cd931..a50edac99 100644
--- a/Demos/Device/MassStorage/MassStorage.h
+++ b/Demos/Device/MassStorage/MassStorage.h
@@ -46,104 +46,33 @@
 		#include "Lib/SCSI.h"
 		#include "Lib/DataflashManager.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-		#include <LUFA/Drivers/Board/Dataflash.h>    // Dataflash chip driver
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Buttons.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/MassStorage.h>
 
 	/* Macros: */
-		/** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
-		#define REQ_MassStorageReset       0xFF
-
-		/** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
-		#define REQ_GetMaxLUN              0xFE
-
-		/** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */
-		#define MAX_SCSI_COMMAND_LENGTH    16
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
+		#define LEDMASK_USB_BUSY          LEDS_LED2
 		
-		/** Total number of Logical Units (drives) in the device. The total device capacity is shared equally between
-		 *  each drive - this can be set to any positive non-zero amount.
-		 */
-		#define TOTAL_LUNS                 2
+		#define TOTAL_LUNS                2
 		
 		/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
-		#define LUN_MEDIA_BLOCKS           (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)    
-		
-		/** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
-		#define CBW_SIGNATURE              0x43425355UL
-
-		/** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
-		#define CSW_SIGNATURE              0x53425355UL
-		
-		/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
-		#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
-
-		/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
-		#define COMMAND_DIRECTION_DATA_IN  (1 << 7)
-
-	/* Type defines: */
-		/** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
-		typedef struct
-		{
-			uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
-			uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
-			uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
-			uint8_t  Flags; /**< Command block flags, indicating command data direction */
-			uint8_t  LUN; /**< Logical Unit number this command is issued to */
-			uint8_t  SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
-			uint8_t  SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */
-		} CommandBlockWrapper_t;
-		
-		/** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
-		typedef struct
-		{
-			uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
-			uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
-			uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
-			uint8_t  Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
-		} CommandStatusWrapper_t;
-		
-	/* Enums: */
-		/** Enum for the possible command status wrapper return status codes. */
-		enum MassStorage_CommandStatusCodes_t
-		{
-			Command_Pass = 0, /**< Command completed with no error */
-			Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
-			Phase_Error  = 2  /**< Command failed due to being invalid in the current phase */
-		};
-
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum MassStorage_StatusCodes_t
-		{
-			Status_USBNotReady            = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating         = 1, /**< USB interface is enumerating */
-			Status_USBReady               = 2, /**< USB interface is connected and ready */
-			Status_CommandBlockError      = 3, /**< Processing a SCSI command block from the host */
-			Status_ProcessingCommandBlock = 4, /**< Error during the processing of a SCSI command block from the host */
-		};
-		
-	/* Global Variables: */
-		extern CommandBlockWrapper_t  CommandBlock;
-		extern CommandStatusWrapper_t CommandStatus;
-		extern volatile bool          IsMassStoreReset;
-
-	/* Task Definitions: */
-		TASK(USB_MassStorage);
+		#define LUN_MEDIA_BLOCKS         (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
 		
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		void UpdateStatus(uint8_t CurrentStatus);
-
-		#if defined(INCLUDE_FROM_MASSSTORAGE_C)
-			static bool ReadInCommandBlock(void);
-			static void ReturnCommandStatus(void);
-		#endif
-
-		uint8_t StreamCallback_AbortOnMassStoreReset(void);
+		bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
 
 #endif
diff --git a/Demos/Device/MassStorage/makefile b/Demos/Device/MassStorage/makefile
index 93f895727..c4adfc9be 100644
--- a/Demos/Device/MassStorage/makefile
+++ b/Demos/Device/MassStorage/makefile
@@ -127,7 +127,6 @@ SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
 	  Lib/SCSI.c                                                  \
 	  Lib/DataflashManager.c                                      \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -138,7 +137,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/MassStorage.c    \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -188,7 +187,6 @@ CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
-CDEFS += -DINTERRUPT_CONTROL_ENDPOINT
 
 
 # Place -D or -U options here for ASM sources
diff --git a/Demos/Device/Mouse/Descriptors.h b/Demos/Device/Mouse/Descriptors.h
index 883ef31e8..ef3215ca6 100644
--- a/Demos/Device/Mouse/Descriptors.h
+++ b/Demos/Device/Mouse/Descriptors.h
@@ -37,30 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
-		 *  specification for details on the structure elements.
-		 */
-		typedef struct
-		{
-			USB_Descriptor_Header_t Header;
-				
-			uint16_t                HIDSpec;
-			uint8_t                 CountryCode;
-		
-			uint8_t                 TotalReportDescriptors;
-
-			uint8_t                 HIDReportType;
-			uint16_t                HIDReportLength;
-		} USB_Descriptor_HID_t;
-
-		/** Type define for the data type used to store HID report descriptor elements. */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -80,12 +62,6 @@
 		/** Size in bytes of the Mouse HID reporting IN endpoint. */
 		#define MOUSE_EPSIZE              8
 
-		/** Descriptor header type value, to indicate a HID class HID descriptor. */
-		#define DTYPE_HID                 0x21
-		
-		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
-		#define DTYPE_Report              0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
 											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
diff --git a/Demos/Device/Mouse/Mouse.c b/Demos/Device/Mouse/Mouse.c
index 32b12fc61..57c1aa114 100644
--- a/Demos/Device/Mouse/Mouse.c
+++ b/Demos/Device/Mouse/Mouse.c
@@ -27,44 +27,33 @@
   arising out of or in connection with the use or performance of
   this software.
 */
-
-/** \file
- *
- *  Main source file for the Mouse demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
  
 #include "Mouse.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Mouse_Report     , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_HID_t Mouse_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
 
-/* Global Variables */
-/** Indicates what report mode the host has requested, true for normal HID reporting mode, false for special boot
- *  protocol reporting mode.
- */
-bool UsingReportProtocol = true;
+		.ReportINEndpointNumber  = MOUSE_EPNUM,
+		.ReportINEndpointSize    = MOUSE_EPSIZE,
 
-/** Current Idle period. This is set by the host via a Set Idle HID class request to silence the device's reports
- *  for either the entire idle duration, or until the report status changes (e.g. the user moves the mouse).
- */
-uint16_t IdleCount = HID_IDLE_CHANGESONLY;
+		.ReportBufferSize        = sizeof(USB_MouseReport_Data_t),
+	};
 
-/** Current Idle period remaining. When the IdleCount value is set, this tracks the remaining number of idle
- *  milliseconds. This is separate to the IdleCount timer and is incremented and compared as the host may request 
- *  the current idle period via a Get Idle HID class request, thus its value must be preserved.
- */
-uint16_t IdleMSRemaining = 0;
+int main(void)
+{	
+	SetupHardware();
+	
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 
+	for (;;)
+	{
+		USB_HID_USBTask(&Mouse_HID_Interface);
+		USB_USBTask();
+	}
+}
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -77,284 +66,64 @@ int main(void)
 	Joystick_Init();
 	LEDs_Init();
 	Buttons_Init();
-	
-	/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
-	OCR0A  = 0x7D;
-	TCCR0A = (1 << WGM01);
-	TCCR0B = ((1 << CS01) | (1 << CS00));
-	TIMSK0 = (1 << OCIE0A);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-	
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
-
-	/* Default to report protocol on connect */
-	UsingReportProtocol = true;
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management and Mouse reporting tasks.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running mouse reporting and USB management tasks */
-	Scheduler_SetTaskMode(USB_Mouse_Report, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the mouse reporting task started.
- */ 
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Mouse Report Endpoint */
-	Endpoint_ConfigureEndpoint(MOUSE_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, MOUSE_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	/* Start running mouse reporting task */
-	Scheduler_SetTaskMode(USB_Mouse_Report, TASK_RUN);
+	if (!(USB_HID_ConfigureEndpoints(&Mouse_HID_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the HID commands, which are
- *  all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				USB_MouseReport_Data_t MouseReportData;
-
-				Endpoint_ClearSETUP();
-
-				/* Create the next mouse report for transmission to the host */
-				CreateMouseReport(&MouseReportData);
-	
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData));
-				
-				/* Clear the report data afterwards */
-				memset(&MouseReportData, 0, sizeof(MouseReportData));
-
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-		case REQ_GetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Write the current protocol flag to the host */
-				Endpoint_Write_Byte(UsingReportProtocol);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Set or clear the flag depending on what the host indicates that the current Protocol should be */
-				UsingReportProtocol = (USB_ControlRequest.wValue != 0);
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_SetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Get idle period in MSB */
-				IdleCount = (USB_ControlRequest.wValue >> 8);
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_GetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{		
-				Endpoint_ClearSETUP();
-				
-				/* Write the current idle duration to the host */
-				Endpoint_Write_Byte(IdleCount);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-
-			break;
-	}
+	USB_HID_ProcessControlPacket(&Mouse_HID_Interface);
 }
 
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and increments the
- *  scheduler elapsed idle period counter when the host has set an idle period.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
 {
-	/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
-	if (IdleMSRemaining)
-	  IdleMSRemaining--;
+	USB_HID_RegisterStartOfFrame(&Mouse_HID_Interface);
 }
 
-/** Fills the given HID report data structure with the next HID report to send to the host.
- *
- *  \param ReportData  Pointer to a HID report data structure to be filled
- */
-void CreateMouseReport(USB_MouseReport_Data_t* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
 {
+	USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
+		
 	uint8_t JoyStatus_LCL    = Joystick_GetStatus();
 	uint8_t ButtonStatus_LCL = Buttons_GetStatus();
-	
-	/* Clear the report contents */
-	memset(ReportData, 0, sizeof(USB_MouseReport_Data_t));
 
 	if (JoyStatus_LCL & JOY_UP)
-	  ReportData->Y = -1;
+	  MouseReport->Y = -1;
 	else if (JoyStatus_LCL & JOY_DOWN)
-	  ReportData->Y =  1;
+	  MouseReport->Y =  1;
 
 	if (JoyStatus_LCL & JOY_RIGHT)
-	  ReportData->X =  1;
+	  MouseReport->X =  1;
 	else if (JoyStatus_LCL & JOY_LEFT)
-	  ReportData->X = -1;
+	  MouseReport->X = -1;
 
 	if (JoyStatus_LCL & JOY_PRESS)
-	  ReportData->Button  = (1 << 0);
+	  MouseReport->Button  = (1 << 0);
 	  
 	if (ButtonStatus_LCL & BUTTONS_BUTTON1)
-	  ReportData->Button |= (1 << 1);
-}
-
-/** Sends the next HID report to the host, via the keyboard data endpoint. */
-void SendNextReport(void)
-{
-	static USB_MouseReport_Data_t PrevMouseReportData;
-	USB_MouseReport_Data_t        MouseReportData;
-	bool                          SendReport;
-	
-	/* Create the next mouse report for transmission to the host */
-	CreateMouseReport(&MouseReportData);
-	
-	/* Check to see if the report data has changed - if so a report MUST be sent */
-	SendReport = (memcmp(&PrevMouseReportData, &MouseReportData, sizeof(USB_MouseReport_Data_t)) != 0);
-	
-	/* Override the check if the Y or X values are non-zero - we want continuous movement while the joystick
-	 * is being held down (via continuous reports), otherwise the cursor will only move once per joystick toggle */
-	if ((MouseReportData.Y != 0) || (MouseReportData.X != 0))
-	  SendReport = true;
-	
-	/* Save the current report data for later comparison to check for changes */
-	PrevMouseReportData = MouseReportData;
-	
-	/* Check if the idle period is set and has elapsed */
-	if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining)))
-	{
-		/* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
-		IdleMSRemaining = (IdleCount << 2);
-		
-		/* Idle period is set and has elapsed, must send a report to the host */
-		SendReport = true;
-	}
+	  MouseReport->Button |= (1 << 1);
 	
-	/* Select the Mouse Report Endpoint */
-	Endpoint_SelectEndpoint(MOUSE_EPNUM);
-
-	/* Check if Mouse Endpoint Ready for Read/Write and if we should send a new report */
-	if (Endpoint_IsReadWriteAllowed() && SendReport)
-	{
-		/* Write Mouse Report Data */
-		Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));
-		
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
-	}
+	return sizeof(USB_MouseReport_Data_t);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the Mouse_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
 {
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage HID report generation and transmission to the host, when in report mode. */
-TASK(USB_Mouse_Report)
-{
-	/* Check if the USB system is connected to a host */
-	if (USB_IsConnected)
-	{
-		/* Send the next mouse report to the host */
-		SendNextReport();
-	}
+	// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
 }
diff --git a/Demos/Device/Mouse/Mouse.h b/Demos/Device/Mouse/Mouse.h
index 65879da8e..5c8049590 100644
--- a/Demos/Device/Mouse/Mouse.h
+++ b/Demos/Device/Mouse/Mouse.h
@@ -46,37 +46,12 @@
 		
 		#include "Descriptors.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Drivers/Board/Joystick.h>     // Joystick driver
-		#include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver
-		#include <LUFA/Drivers/Board/Buttons.h>      // Board Buttons driver
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-		
-	/* Task Definitions: */
-		TASK(USB_Mouse_Report);
-
-	/* Macros: */
-		/** Idle period indicating that reports should be sent only when the inputs have changed */
-		#define HID_IDLE_CHANGESONLY 0
-	
-		/** HID Class specific request to get the next HID report from the device. */
-		#define REQ_GetReport        0x01
-
-		/** HID Class specific request to get the idle timeout period of the device. */
-		#define REQ_GetIdle          0x02
-
-		/** HID Class specific request to send the next HID report to the device. */
-		#define REQ_SetReport        0x09
-
-		/** HID Class specific request to set the idle timeout period of the device. */
-		#define REQ_SetIdle          0x0A
-
-		/** HID Class specific request to get the current HID protocol in use, either report or boot. */
-		#define REQ_GetProtocol      0x03
-
-		/** HID Class specific request to set the current HID protocol in use, either report or boot. */
-		#define REQ_SetProtocol      0x0B
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Buttons.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
 	/* Type Defines: */
 		/** Type define for the mouse HID report structure, for creating and sending HID reports to the host PC.
@@ -89,22 +64,23 @@
 			int8_t  Y; /**< Current mouse delta Y movement, as a signed 8-bit integer */
 		} USB_MouseReport_Data_t;
 		
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum Mouse_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 			
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
+		void EVENT_USB_StartOfFrame(void);
 
-		void CreateMouseReport(USB_MouseReport_Data_t* ReportData);
-		void UpdateStatus(uint8_t CurrentStatus);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/Demos/Device/Mouse/makefile b/Demos/Device/Mouse/makefile
index 632bf91ae..4c18f9d4a 100644
--- a/Demos/Device/Mouse/makefile
+++ b/Demos/Device/Mouse/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -136,7 +135,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
  
 # List C++ source files here. (C dependencies are automatically generated.)
 CPPSRC = 
@@ -182,7 +181,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Device/RNDISEthernet/Lib/ARP.h b/Demos/Device/RNDISEthernet/Lib/ARP.h
index 8551df85b..f05d8f093 100644
--- a/Demos/Device/RNDISEthernet/Lib/ARP.h
+++ b/Demos/Device/RNDISEthernet/Lib/ARP.h
@@ -38,9 +38,7 @@
 
 	/* Includes: */
 		#include <avr/io.h>
-		#include <string.h>
-		
-		#include <LUFA/Scheduler/Scheduler.h>
+		#include <string.h>
 		
 		#include "EthernetProtocols.h"
 		#include "Ethernet.h"
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/RNDISEthernet/Lib/Ethernet.c
index 3d34f716a..57380a082 100644
--- a/Demos/Device/RNDISEthernet/Lib/Ethernet.c
+++ b/Demos/Device/RNDISEthernet/Lib/Ethernet.c
@@ -38,12 +38,6 @@
 #include "Ethernet.h"
 
 /* Global Variables: */
-/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */
-Ethernet_Frame_Info_t FrameIN;
-
-/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */
-Ethernet_Frame_Info_t FrameOUT;
-
 /** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */
 const MAC_Address_t ServerMACAddress    = {SERVER_MAC_ADDRESS};
 
@@ -63,31 +57,31 @@ const IP_Address_t  ClientIPAddress     = {CLIENT_IP_ADDRESS};
 /** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet
  *  frame buffer if the sub protocol handlers create a valid response.
  */
-void Ethernet_ProcessPacket(void)
+void Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT)
 {
-	DecodeEthernetFrameHeader(FrameIN.FrameData);
+	DecodeEthernetFrameHeader(FrameIN->FrameData);
 
 	/* Cast the incoming Ethernet frame to the Ethernet header type */
-	Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;
-	Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
+	Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN->FrameData;
+	Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT->FrameData;
 	
 	int16_t                  RetSize        = NO_RESPONSE;
 	
 	/* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */
 	if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||
-	     MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&
-		(SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))
+	     MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)))
 	{
 		/* Process the packet depending on its protocol */
 		switch (SwapEndian_16(FrameINHeader->EtherType))
 		{
 			case ETHERTYPE_ARP:
-				RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
-				                               &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
+				RetSize = ARP_ProcessARPPacket(&FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+				                               &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
 				break;		
 			case ETHERTYPE_IPV4:
-				RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],
-				                             &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);
+				RetSize = IP_ProcessIPPacket(FrameIN,
+				                             &FrameIN->FrameData[sizeof(Ethernet_Frame_Header_t)],
+				                             &FrameOUT->FrameData[sizeof(Ethernet_Frame_Header_t)]);
 				break;
 		}
 		
@@ -100,8 +94,8 @@ void Ethernet_ProcessPacket(void)
 			FrameOUTHeader->EtherType       = FrameINHeader->EtherType;
 			
 			/* Set the response length in the buffer and indicate that a response is ready to be sent */
-			FrameOUT.FrameLength            = (sizeof(Ethernet_Frame_Header_t) + RetSize);
-			FrameOUT.FrameInBuffer          = true;
+			FrameOUT->FrameLength           = (sizeof(Ethernet_Frame_Header_t) + RetSize);
+			FrameOUT->FrameInBuffer         = true;
 		}
 	}
 
@@ -109,7 +103,7 @@ void Ethernet_ProcessPacket(void)
 	if (RetSize != NO_PROCESS)
 	{
 		/* Clear the frame buffer */
-		FrameIN.FrameInBuffer = false;
+		FrameIN->FrameInBuffer = false;
 	}
 }
 
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.h b/Demos/Device/RNDISEthernet/Lib/Ethernet.h
index b360f07ae..b3002523a 100644
--- a/Demos/Device/RNDISEthernet/Lib/Ethernet.h
+++ b/Demos/Device/RNDISEthernet/Lib/Ethernet.h
@@ -39,6 +39,8 @@
 	/* Includes: */
 		#include <avr/io.h>
 		#include <string.h>
+		
+		#include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
 
 		#include "EthernetProtocols.h"
 		#include "ProtocolDecoders.h"
@@ -50,6 +52,9 @@
 		#include "IP.h"
 		
 	/* Macros: */
+		/** Physical MAC address of the USB RNDIS network adapter */
+		#define ADAPTER_MAC_ADDRESS              {0x00, 0x02, 0x00, 0x02, 0x00, 0x02}		
+
 		/** Physical MAC address of the virtual server on the network */
 		#define SERVER_MAC_ADDRESS               {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}		
 
@@ -64,12 +69,6 @@
 		 *  \return True if the addresses match, false otherwise
 		 */
 		#define MAC_COMPARE(MAC1, MAC2)          (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)
-
-		/** Maximum size of an incoming or outgoing Ethernet frame in bytes */
-		#define ETHERNET_FRAME_SIZE_MAX          1500
-		
-		/** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */
-		#define ETHERNET_VER2_MINSIZE            0x0600
 		
 		/** Return value for all sub protocol handling routines, indicating that no response packet has been generated */
 		#define NO_RESPONSE                      0		
@@ -78,14 +77,6 @@
 		#define NO_PROCESS                       -1
 
 	/* Type Defines: */
-		/** Type define for an Ethernet frame buffer. */
-		typedef struct
-		{
-			uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
-			uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
-			bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
-		} Ethernet_Frame_Info_t;
-
 		/** Type define for an Ethernet frame header */
 		typedef struct
 		{
@@ -100,9 +91,6 @@
 		} Ethernet_Frame_Header_t;
 		
 	/* External Variables: */
-		extern Ethernet_Frame_Info_t FrameIN;
-		extern Ethernet_Frame_Info_t FrameOUT;
-
 		extern const MAC_Address_t ServerMACAddress;
 		extern const IP_Address_t  ServerIPAddress;
 		extern const MAC_Address_t BroadcastMACAddress;
@@ -110,7 +98,7 @@
 		extern const IP_Address_t  ClientIPAddress;
 		
 	/* Function Prototypes: */
-		void     Ethernet_ProcessPacket(void);
+		void     Ethernet_ProcessPacket(Ethernet_Frame_Info_t* FrameIN, Ethernet_Frame_Info_t* FrameOUT);
 		uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);
 		
 #endif
diff --git a/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h b/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
index 3ff3433ae..1ec5961e1 100644
--- a/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
+++ b/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
@@ -71,13 +71,7 @@
 		#define PROTOCOL_OSPF                    89
 		#define PROTOCOL_SCTP                    132
 
-	/* Type Defines: */
-		/** Type define for a physical MAC address of a device on a network */
-		typedef struct
-		{
-			uint8_t       Octets[6]; /**< Individual bytes of a MAC address */
-		} MAC_Address_t;
-		
+	/* Type Defines: */		
 		/** Type define for a protocol IP address of a device on a network */
 		typedef struct
 		{
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.c b/Demos/Device/RNDISEthernet/Lib/ICMP.c
index da4ffcfa1..ba6e1db68 100644
--- a/Demos/Device/RNDISEthernet/Lib/ICMP.c
+++ b/Demos/Device/RNDISEthernet/Lib/ICMP.c
@@ -45,7 +45,7 @@
  *
  *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise
  */
-int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
+int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
 {
 	ICMP_Header_t* ICMPHeaderIN  = (ICMP_Header_t*)InDataStart;
 	ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;
@@ -62,7 +62,7 @@ int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)
 		ICMPHeaderOUT->Id       = ICMPHeaderIN->Id;
 		ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;
 		
-		uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));
+		uint16_t DataSize = FrameIN->FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN->FrameData));
 		
 		/* Copy the remaining payload to the response - echo requests should echo back any sent data */
 		memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.h b/Demos/Device/RNDISEthernet/Lib/ICMP.h
index b20a557e9..56749c09c 100644
--- a/Demos/Device/RNDISEthernet/Lib/ICMP.h
+++ b/Demos/Device/RNDISEthernet/Lib/ICMP.h
@@ -75,6 +75,6 @@
 		} ICMP_Header_t;
 		
 	/* Function Prototypes: */
-		int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);
+		int16_t ICMP_ProcessICMPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
 
 #endif
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.c b/Demos/Device/RNDISEthernet/Lib/IP.c
index 8fb0b446d..08500450c 100644
--- a/Demos/Device/RNDISEthernet/Lib/IP.c
+++ b/Demos/Device/RNDISEthernet/Lib/IP.c
@@ -46,7 +46,7 @@
  *           response was generated, NO_PROCESS if the packet processing was deferred until the
  *           next Ethernet packet handler iteration
  */
-int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
+int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart)
 {
 	DecodeIPHeader(InDataStart);
 
@@ -69,7 +69,8 @@ int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)
 	switch (IPHeaderIN->Protocol)
 	{
 		case PROTOCOL_ICMP:
-			RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],
+			RetSize = ICMP_ProcessICMPPacket(FrameIN,
+			                                 &((uint8_t*)InDataStart)[HeaderLengthBytes],
 			                                 &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);
 			break;
 		case PROTOCOL_TCP:
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.h b/Demos/Device/RNDISEthernet/Lib/IP.h
index fc1a46aef..f77c772d8 100644
--- a/Demos/Device/RNDISEthernet/Lib/IP.h
+++ b/Demos/Device/RNDISEthernet/Lib/IP.h
@@ -88,6 +88,6 @@
 		} IP_Header_t;
 		
 	/* Function Prototypes: */
-		int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);
+		int16_t IP_ProcessIPPacket(Ethernet_Frame_Info_t* FrameIN, void* InDataStart, void* OutDataStart);
 
 #endif
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.c b/Demos/Device/RNDISEthernet/Lib/RNDIS.c
deleted file mode 100644
index c5202bcd1..000000000
--- a/Demos/Device/RNDISEthernet/Lib/RNDIS.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2009.
-              
-  dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
-*/
-
-/*
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, provided that the above copyright notice appear in all
-  copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/** \file
- *
- *  RNDIS command handler functions. This handles RNDIS commands according to
- *  the Microsoft RNDIS specification, creating a USB Ethernet network adapter.
- */
- 
-#define  INCLUDE_FROM_RNDIS_C
-#include "RNDIS.h"
-
-/* Global Variables: */
-/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */
-static MAC_Address_t  PROGMEM AdapterMACAddress          = {ADAPTER_MAC_ADDRESS};
-
-/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for
- *  the device, but may still be used by the OS in some circumstances.
- */
-static char           PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";
-
-/** List of RNDIS OID commands supported by this adapter. */
-static const uint32_t PROGMEM AdapterSupportedOIDList[]  =
-							{
-								OID_GEN_SUPPORTED_LIST,
-								OID_GEN_PHYSICAL_MEDIUM,
-								OID_GEN_HARDWARE_STATUS,
-								OID_GEN_MEDIA_SUPPORTED,
-								OID_GEN_MEDIA_IN_USE,
-								OID_GEN_MAXIMUM_FRAME_SIZE,
-								OID_GEN_MAXIMUM_TOTAL_SIZE,
-								OID_GEN_LINK_SPEED,
-								OID_GEN_TRANSMIT_BLOCK_SIZE,
-								OID_GEN_RECEIVE_BLOCK_SIZE,
-								OID_GEN_VENDOR_ID,
-								OID_GEN_VENDOR_DESCRIPTION,
-								OID_GEN_CURRENT_PACKET_FILTER,
-								OID_GEN_MAXIMUM_TOTAL_SIZE,
-								OID_GEN_MEDIA_CONNECT_STATUS,
-								OID_GEN_XMIT_OK,
-								OID_GEN_RCV_OK,
-								OID_GEN_XMIT_ERROR,
-								OID_GEN_RCV_ERROR,
-								OID_GEN_RCV_NO_BUFFER,
-								OID_802_3_PERMANENT_ADDRESS,
-								OID_802_3_CURRENT_ADDRESS,
-								OID_802_3_MULTICAST_LIST,
-								OID_802_3_MAXIMUM_LIST_SIZE,
-								OID_802_3_RCV_ERROR_ALIGNMENT,
-								OID_802_3_XMIT_ONE_COLLISION,
-								OID_802_3_XMIT_MORE_COLLISIONS,
-							};
-
-/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire
- *  Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this
- *  reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.
- */
-uint8_t                 RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];
-
-/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */
-RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;
-
-/** Indicates if a RNDIS message response is ready to be sent back to the host. */
-bool                    ResponseReady               = false;
-
-/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */
-uint8_t                 CurrRNDISState              = RNDIS_Uninitialized;
-
-/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */
-uint32_t                CurrPacketFilter            = 0;							
-
-
-/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is
- *  created, the ResponseReady global is updated so that the response is written back to the host upon request.
- */
-void ProcessRNDISControlMessage(void)
-{
-	/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
-	         this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
-
-	switch (MessageHeader->MessageType)
-	{
-		case REMOTE_NDIS_INITIALIZE_MSG:
-			/* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */
-
-			ResponseReady = true;
-			
-			RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;
-			RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;
-			
-			INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;
-			INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);
-			INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;
-			INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;
-			
-			INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;
-			INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;			
-			INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;
-			INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;
-			INITIALIZE_Response->MaxPacketsPerTransfer = 1;
-			INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
-			INITIALIZE_Response->PacketAlignmentFactor = 0;
-			INITIALIZE_Response->AFListOffset          = 0;
-			INITIALIZE_Response->AFListSize            = 0;
-			
-			CurrRNDISState = RNDIS_Initialized;
-		
-			break;
-		case REMOTE_NDIS_HALT_MSG:
-			/* Halt the adapter, reset the adapter state - note that no response should be returned when completed */
-
-			ResponseReady = false;
-			MessageHeader->MessageLength = 0;
-
-			CurrRNDISState = RNDIS_Uninitialized;
-
-			break;
-		case REMOTE_NDIS_QUERY_MSG:
-			/* Request for information about a parameter about the adapter, specified as an OID token */
-
-			ResponseReady = true;
-						
-			RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;
-			RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;
-			uint32_t             Query_Oid      = QUERY_Message->Oid;
-						
-			void*     QueryData                 = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
-			                                                          QUERY_Message->InformationBufferOffset];
-			void*     ResponseData              = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];		
-			uint16_t  ResponseSize;
-
-			QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;
-			QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);
-						
-			if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
-			                     ResponseData, &ResponseSize))
-			{
-				QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;
-				QUERY_Response->MessageLength          += ResponseSize;
-							
-				QUERY_Response->InformationBufferLength = ResponseSize;
-				QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));
-			}
-			else
-			{				
-				QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
-
-				QUERY_Response->InformationBufferLength = 0;
-				QUERY_Response->InformationBufferOffset = 0;
-			}
-			
-			break;
-		case REMOTE_NDIS_SET_MSG:
-			/* Request to set a parameter of the adapter, specified as an OID token */
-		
-			ResponseReady = true;
-			
-			RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;
-			RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;
-			uint32_t           SET_Oid      = SET_Message->Oid;
-
-			SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;
-			SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);
-			SET_Response->RequestId         = SET_Message->RequestId;
-
-			void* SetData                   = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
-			                                                      SET_Message->InformationBufferOffset];
-						
-			if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
-			  SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;
-			else
-			  SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
-
-			break;
-		case REMOTE_NDIS_RESET_MSG:
-			/* Soft reset the adapter */
-		
-			ResponseReady = true;
-			
-			RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;
-
-			RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;
-			RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);
-			RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;
-			RESET_Response->AddressingReset     = 0;
-
-			break;
-		case REMOTE_NDIS_KEEPALIVE_MSG:
-			/* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
-		
-			ResponseReady = true;
-			
-			RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;
-			RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;
-
-			KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;
-			KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
-			KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;
-			KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;
-			
-			break;
-	}
-}
-
-/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
- *  parameter is given as an OID value.
- *
- *  \param OId           OId value of the parameter being queried
- *  \param QueryData     Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
- *  \param QuerySize     Size in bytes of the extra query data being sent by the host
- *  \param ResponseData  Pointer to the start of the query response inside the RNDIS message buffer
- *  \param ResponseSize  Pointer to the size in bytes of the response data being sent to the host
- *
- *  \return Boolean true if the query was handled, false otherwise
- */
-static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
-                             void* ResponseData, uint16_t* ResponseSize)
-{
-	/* Handler for REMOTE_NDIS_QUERY_MSG messages */
-
-	switch (OId)
-	{
-		case OID_GEN_SUPPORTED_LIST:
-			*ResponseSize = sizeof(AdapterSupportedOIDList);
-			
-			/* Copy the list of supported NDIS OID tokens to the response buffer */
-			memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
-			
-			return true;
-		case OID_GEN_PHYSICAL_MEDIUM:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate that the device is a true ethernet link */
-			*((uint32_t*)ResponseData) = 0;
-			
-			return true;
-		case OID_GEN_HARDWARE_STATUS:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Always indicate hardware ready */
-			*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
-			
-			return true;
-		case OID_GEN_MEDIA_SUPPORTED:
-		case OID_GEN_MEDIA_IN_USE:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate 802.3 (Ethernet) supported by the adapter */
-			*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
-			
-			return true;
-		case OID_GEN_VENDOR_ID:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
-			*((uint32_t*)ResponseData) = 0x00FFFFFF;
-			
-			return true;
-		case OID_GEN_MAXIMUM_FRAME_SIZE:
-		case OID_GEN_TRANSMIT_BLOCK_SIZE:
-		case OID_GEN_RECEIVE_BLOCK_SIZE:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate that the maximum frame size is the size of the ethernet frame buffer */
-			*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
-			
-			return true;
-		case OID_GEN_VENDOR_DESCRIPTION:
-			*ResponseSize = sizeof(AdapterVendorDescription);
-			
-			/* Copy vendor description string to the response buffer */
-			memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
-			
-			return true;
-		case OID_GEN_MEDIA_CONNECT_STATUS:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Always indicate that the adapter is connected to a network */
-			*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
-			
-			return true;
-		case OID_GEN_LINK_SPEED:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate 10Mb/s link speed */
-			*((uint32_t*)ResponseData) = 100000;
-
-			return true;
-		case OID_802_3_PERMANENT_ADDRESS:
-		case OID_802_3_CURRENT_ADDRESS:
-			*ResponseSize = sizeof(MAC_Address_t);
-			
-			/* Copy over the fixed adapter MAC to the response buffer */
-			memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
-
-			return true;
-		case OID_802_3_MAXIMUM_LIST_SIZE:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate only one multicast address supported */
-			*((uint32_t*)ResponseData) = 1;
-		
-			return true;
-		case OID_GEN_CURRENT_PACKET_FILTER:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate the current packet filter mask */
-			*((uint32_t*)ResponseData) = CurrPacketFilter;
-		
-			return true;			
-		case OID_GEN_XMIT_OK:
-		case OID_GEN_RCV_OK:
-		case OID_GEN_XMIT_ERROR:
-		case OID_GEN_RCV_ERROR:
-		case OID_GEN_RCV_NO_BUFFER:
-		case OID_802_3_RCV_ERROR_ALIGNMENT:
-		case OID_802_3_XMIT_ONE_COLLISION:
-		case OID_802_3_XMIT_MORE_COLLISIONS:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Unused statistic OIDs - always return 0 for each */
-			*((uint32_t*)ResponseData) = 0;
-		
-			return true;
-		case OID_GEN_MAXIMUM_TOTAL_SIZE:
-			*ResponseSize = sizeof(uint32_t);
-			
-			/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
-			*((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
-		
-			return true;
-		default:
-			return false;
-	}
-}
-
-/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given 
- *  as an OID value.
- *
- *  \param OId      OId value of the parameter being set
- *  \param SetData  Pointer to the parameter value in the RNDIS message buffer
- *  \param SetSize  Size in bytes of the parameter value being sent by the host
- *
- *  \return Boolean true if the set was handled, false otherwise
- */
-static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
-{
-	/* Handler for REMOTE_NDIS_SET_MSG messages */
-
-	switch (OId)
-	{
-		case OID_GEN_CURRENT_PACKET_FILTER:
-			/* Save the packet filter mask in case the host queries it again later */
-			CurrPacketFilter = *((uint32_t*)SetData);
-		
-			/* Set the RNDIS state to initialized if the packet filter is non-zero */
-			CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
-			
-			return true;
-		case OID_802_3_MULTICAST_LIST:
-			/* Do nothing - throw away the value from the host as it is unused */
-		
-			return true;
-		default:
-			return false;
-	}
-}
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.c b/Demos/Device/RNDISEthernet/Lib/TCP.c
index f259aad02..1ebd15435 100644
--- a/Demos/Device/RNDISEthernet/Lib/TCP.c
+++ b/Demos/Device/RNDISEthernet/Lib/TCP.c
@@ -56,7 +56,7 @@ TCP_ConnectionState_t  ConnectionStateTable[MAX_TCP_CONNECTIONS];
  *  level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT
  *  buffer for later transmission.
  */
-TASK(TCP_Task)
+void TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
 {
 	/* Task to hand off TCP packets to and from the listening applications. */
 
@@ -76,7 +76,7 @@ TASK(TCP_Task)
 	}
 	
 	/* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */
-	if (FrameOUT.FrameInBuffer)
+	if (RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
 	  return;
 	
 	/* Send response packets from each application as the TCP packet buffers are filled by the applications */
@@ -86,13 +86,13 @@ TASK(TCP_Task)
 		if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&
 		    (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))
 		{
-			Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;
-			IP_Header_t*             IPHeaderOUT    = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
-			TCP_Header_t*            TCPHeaderOUT   = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
-			                                                                             sizeof(IP_Header_t)];						
-			void*                    TCPDataOUT     = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
-			                                                              sizeof(IP_Header_t) +
-			                                                              sizeof(TCP_Header_t)];
+			Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData;
+			IP_Header_t*    IPHeaderOUT  = (IP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];
+			TCP_Header_t*   TCPHeaderOUT = (TCP_Header_t*)&RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
+			                                                                                      sizeof(IP_Header_t)];						
+			void*           TCPDataOUT     = &RNDISInterfaceInfo->FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +
+			                                                                         sizeof(IP_Header_t) +
+			                                                                         sizeof(TCP_Header_t)];
 
 			uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;
 
@@ -145,8 +145,8 @@ TASK(TCP_Task)
 			PacketSize += sizeof(Ethernet_Frame_Header_t);
 
 			/* Set the response length in the buffer and indicate that a response is ready to be sent */
-			FrameOUT.FrameLength            = PacketSize;
-			FrameOUT.FrameInBuffer          = true;
+			RNDISInterfaceInfo->FrameOUT.FrameLength   = PacketSize;
+			RNDISInterfaceInfo->FrameOUT.FrameInBuffer = true;
 			
 			ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;
 			
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.h b/Demos/Device/RNDISEthernet/Lib/TCP.h
index d4b72a519..3448245ed 100644
--- a/Demos/Device/RNDISEthernet/Lib/TCP.h
+++ b/Demos/Device/RNDISEthernet/Lib/TCP.h
@@ -38,9 +38,7 @@
 
 	/* Includes: */
 		#include <avr/io.h>
-		#include <stdbool.h>
-		
-		#include <LUFA/Scheduler/Scheduler.h>
+		#include <stdbool.h>
 		
 		#include "EthernetProtocols.h"
 		#include "Ethernet.h"
@@ -229,14 +227,12 @@
 			uint16_t               Checksum; /**< TCP checksum */
 			uint16_t               UrgentPointer; /**< Urgent data pointer */
 		} TCP_Header_t;
-
-	/* Tasks: */
-		TASK(TCP_Task);
 		
 	/* External Variables: */
 		TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];
 
 	/* Function Prototypes: */
+		void                  TCP_TCPTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
 		void                  TCP_Init(void);
 		bool                  TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));
 		uint8_t               TCP_GetPortState(uint16_t Port);
diff --git a/Demos/Device/RNDISEthernet/RNDISEthernet.c b/Demos/Device/RNDISEthernet/RNDISEthernet.c
index b046f7870..3246cd8bc 100644
--- a/Demos/Device/RNDISEthernet/RNDISEthernet.c
+++ b/Demos/Device/RNDISEthernet/RNDISEthernet.c
@@ -28,27 +28,50 @@
   this software.
 */
 
-/** \file
- *
- *  Main source file for the RNDISEthernet demo. This file contains the main tasks of the demo and
- *  is responsible for the initial application hardware configuration.
- */
-
 #include "RNDISEthernet.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = Ethernet_Task        , .TaskStatus = TASK_STOP },
-	{ .Task = TCP_Task             , .TaskStatus = TASK_STOP },
-	{ .Task = RNDIS_Task           , .TaskStatus = TASK_STOP },
-};
+USB_ClassInfo_RNDIS_t Ethernet_RNDIS_Interface =
+	{
+		.ControlInterfaceNumber     = 0,
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the USB management task.
- */
+		.DataINEndpointNumber       = CDC_TX_EPNUM,
+		.DataINEndpointSize         = CDC_TXRX_EPSIZE,
+
+		.DataOUTEndpointNumber      = CDC_RX_EPNUM,
+		.DataOUTEndpointSize        = CDC_TXRX_EPSIZE,
+
+		.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+		.NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,
+		
+		.AdapterVendorDescription   = "LUFA RNDIS Demo Adapter",
+		.AdapterMACAddress          = {ADAPTER_MAC_ADDRESS},
+	};
+	
 int main(void)
+{
+	SetupHardware();
+
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+	
+	printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
+
+	for (;;)
+	{
+		if (Ethernet_RNDIS_Interface.FrameIN.FrameInBuffer)
+		{
+			LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
+			Ethernet_ProcessPacket(&Ethernet_RNDIS_Interface.FrameIN, &Ethernet_RNDIS_Interface.FrameOUT);
+			LEDs_SetAllLEDs(LEDMASK_USB_READY);
+		}
+
+		TCP_TCPTask(&Ethernet_RNDIS_Interface);
+
+		USB_RNDIS_USBTask(&Ethernet_RNDIS_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -60,279 +83,32 @@ int main(void)
 	/* Hardware Initialization */
 	LEDs_Init();
 	SerialStream_Init(9600, false);
-	
-	/* Webserver Initialization */
-	TCP_Init();
-	Webserver_Init();
-
-	printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
 
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
+	/* Initialize TCP and Webserver modules */
+	TCP_Init();
+	Webserver_Init();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops all the relevant tasks.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running TCP/IP and USB management tasks */
-	Scheduler_SetTaskMode(RNDIS_Task, TASK_STOP);
-	Scheduler_SetTaskMode(Ethernet_Task, TASK_STOP);
-	Scheduler_SetTaskMode(TCP_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host sets the current configuration
- *  of the USB device after enumeration, and configures the RNDIS device endpoints and starts the relevant tasks.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup CDC Notification, Rx and Tx Endpoints */
-	Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-
-	/* Start TCP/IP tasks */
-	Scheduler_SetTaskMode(RNDIS_Task, TASK_RUN);
-	Scheduler_SetTaskMode(Ethernet_Task, TASK_RUN);
-	Scheduler_SetTaskMode(TCP_Task, TASK_RUN);
+	if (!(USB_RNDIS_ConfigureEndpoints(&Ethernet_RNDIS_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the RNDIS control commands,
- *  which set up the USB RNDIS network adapter), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Process RNDIS class commands */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_SendEncapsulatedCommand:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Clear the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-				
-				/* Read in the RNDIS message into the message buffer */
-				Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength);
-
-				/* Finalize the stream transfer to clear the last packet from the host */
-				Endpoint_ClearIN();
-
-				/* Process the RNDIS message */
-				ProcessRNDISControlMessage();
-			}
-			
-			break;
-		case REQ_GetEncapsulatedResponse:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Clear the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-				
-				/* Check if a response to the last message is ready */
-				if (!(MessageHeader->MessageLength))
-				{
-					/* Set the response to a single 0x00 byte to indicate that no response is ready */
-					RNDISMessageBuffer[0] = 0;
-					MessageHeader->MessageLength = 1;
-				}
-
-				/* Write the message response data to the endpoint */
-				Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-
-				/* Reset the message header once again after transmission */
-				MessageHeader->MessageLength = 0;
-			}
-	
-			break;
-	}
-}
-
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the RNDISEthernet_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-		case Status_ProcessingEthernetFrame:
-			LEDMask = (LEDS_LED2 | LEDS_LED3);
-			break;		
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Task to manage the sending and receiving of encapsulated RNDIS data and notifications. This removes the RNDIS
- *  wrapper from received Ethernet frames and places them in the FrameIN global buffer, or adds the RNDIS wrapper
- *  to a frame in the FrameOUT global before sending the buffer contents to the host.
- */
-TASK(RNDIS_Task)
-{
-	/* Select the notification endpoint */
-	Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
-
-	/* Check if a message response is ready for the host */
-	if (Endpoint_IsINReady() && ResponseReady)
-	{
-		USB_Notification_t Notification = (USB_Notification_t)
-			{
-				.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
-				.bNotification = NOTIF_RESPONSE_AVAILABLE,
-				.wValue        = 0,
-				.wIndex        = 0,
-				.wLength       = 0,
-			};
-		
-		/* Indicate that a message response is ready for the host */
-		Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
-
-		/* Finalize the stream transfer to send the last packet */
-		Endpoint_ClearIN();
-
-		/* Indicate a response is no longer ready */
-		ResponseReady = false;
-	}
-	
-	/* Don't process the data endpoints until the system is in the data initialized state, and the buffer is free */
-	if ((CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
-	{
-		/* Create a new packet header for reading/writing */
-		RNDIS_PACKET_MSG_t RNDISPacketHeader;
-
-		/* Select the data OUT endpoint */
-		Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-		
-		/* Check if the data OUT endpoint contains data, and that the IN buffer is empty */
-		if (Endpoint_IsOUTReceived() && !(FrameIN.FrameInBuffer))
-		{
-			/* Read in the packet message header */
-			Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
-
-			/* Stall the request if the data is too large */
-			if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
-			{
-				Endpoint_StallTransaction();
-				return;
-			}
-			
-			/* Read in the Ethernet frame into the buffer */
-			Endpoint_Read_Stream_LE(FrameIN.FrameData, RNDISPacketHeader.DataLength);
-
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearOUT();
-			
-			/* Store the size of the Ethernet frame */
-			FrameIN.FrameLength = RNDISPacketHeader.DataLength;
-
-			/* Indicate Ethernet IN buffer full */
-			FrameIN.FrameInBuffer = true;
-		}
-		
-		/* Select the data IN endpoint */
-		Endpoint_SelectEndpoint(CDC_TX_EPNUM);
-		
-		/* Check if the data IN endpoint is ready for more data, and that the IN buffer is full */
-		if (Endpoint_IsINReady() && FrameOUT.FrameInBuffer)
-		{
-			/* Clear the packet header with all 0s so that the relevant fields can be filled */
-			memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
-
-			/* Construct the required packet header fields in the buffer */
-			RNDISPacketHeader.MessageType   = REMOTE_NDIS_PACKET_MSG;
-			RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + FrameOUT.FrameLength);
-			RNDISPacketHeader.DataOffset    = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
-			RNDISPacketHeader.DataLength    = FrameOUT.FrameLength;
-
-			/* Send the packet header to the host */
-			Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t));
-
-			/* Send the Ethernet frame data to the host */
-			Endpoint_Write_Stream_LE(FrameOUT.FrameData, RNDISPacketHeader.DataLength);
-			
-			/* Finalize the stream transfer to send the last packet */
-			Endpoint_ClearIN();
-			
-			/* Indicate Ethernet OUT buffer no longer full */
-			FrameOUT.FrameInBuffer = false;
-		}
-	}
-}
-
-/** Ethernet frame processing task. This task checks to see if a frame has been received, and if so hands off the processing
- *  of the frame to the Ethernet processing routines.
- */
-TASK(Ethernet_Task)
-{
-	/* Task for Ethernet processing. Incoming ethernet frames are loaded into the FrameIN structure, and
-	   outgoing frames should be loaded into the FrameOUT structure. Both structures can only hold a single
-	   Ethernet frame at a time, so the FrameInBuffer bool is used to indicate when the buffers contain data. */
-
-	/* Check if a frame has been written to the IN frame buffer */
-	if (FrameIN.FrameInBuffer)
-	{
-		/* Indicate packet processing started */
-		UpdateStatus(Status_ProcessingEthernetFrame);
-
-		/* Process the ethernet frame - replace this with your own Ethernet handler code as desired */
-		Ethernet_ProcessPacket();
-
-		/* Indicate packet processing complete */
-		UpdateStatus(Status_USBReady);
-	}
+	USB_RNDIS_ProcessControlPacket(&Ethernet_RNDIS_Interface);
 }
diff --git a/Demos/Device/RNDISEthernet/RNDISEthernet.h b/Demos/Device/RNDISEthernet/RNDISEthernet.h
index 703af4003..bc5004205 100644
--- a/Demos/Device/RNDISEthernet/RNDISEthernet.h
+++ b/Demos/Device/RNDISEthernet/RNDISEthernet.h
@@ -45,56 +45,34 @@
 		#include <stdio.h>
 
 		#include "Descriptors.h"
-
-		#include "Lib/RNDIS.h"
+
 		#include "Lib/Ethernet.h"
 		#include "Lib/TCP.h"
 		#include "Lib/ARP.h"
 		#include "Lib/Webserver.h"
 
-		#include <LUFA/Version.h>                         // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>                 // USB Functionality
-		#include <LUFA/Drivers/Board/LEDs.h>              // LEDs driver
-		#include <LUFA/Scheduler/Scheduler.h>             // Simple scheduler for task management
-		#include <LUFA/Drivers/Peripheral/SerialStream.h> // Serial stream driver
-	
-	/* Macros: */
-		/** Notification value to indicate that a frame is ready to be read by the host. */
-		#define NOTIF_RESPONSE_AVAILABLE                 0x01
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/RNDIS.h>
 
-	/* Type Defines: */
-		/** Type define for a RNDIS notification message, for transmission to the RNDIS host via the notification
-		 *  Endpoint.
-		 */
-		typedef struct
-		{
-			uint8_t  bmRequestType; /**< Notification type, a mask of values from SrdRequestType.h */
-			uint8_t  bNotification; /**< Notification index, indicating what the RNDIS notification relates to */
-			uint16_t wValue; /**< Two byte notification value parameter */
-			uint16_t wIndex; /**< Two byte notification index parameter */
-			uint16_t wLength; /**< Size of data payload following the notification header */
-		} USB_Notification_t;
-
-	/* Enums: */
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum RNDISEthernet_StatusCodes_t
-		{
-			Status_USBNotReady             = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating          = 1, /**< USB interface is enumerating */
-			Status_USBReady                = 2, /**< USB interface is connected and ready */
-			Status_ProcessingEthernetFrame = 3, /**< Currently processing an ethernet frame from the host */
-		};
+	/* Macros: */
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
+		#define LEDMASK_USB_BUSY          LEDS_LED2
 		
-	/* Tasks: */
-		TASK(RNDIS_Task);
-		TASK(Ethernet_Task);
-
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-
-		void UpdateStatus(uint8_t CurrentStatus);
+		void EVENT_USB_StartOfFrame(void);
+		
+		void CALLBACK_USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
 	
 #endif
diff --git a/Demos/Device/RNDISEthernet/makefile b/Demos/Device/RNDISEthernet/makefile
index f40c37b05..3bcc37c8e 100644
--- a/Demos/Device/RNDISEthernet/makefile
+++ b/Demos/Device/RNDISEthernet/makefile
@@ -125,7 +125,6 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
       Descriptors.c                                               \
-      Lib/RNDIS.c                                                 \
 	  Lib/Ethernet.c                                              \
 	  Lib/ProtocolDecoders.c                                      \
 	  Lib/ICMP.c                                                  \
@@ -135,7 +134,6 @@ SRC = $(TARGET).c                                                 \
 	  Lib/ARP.c                                                   \
 	  Lib/IP.c                                                    \
 	  Lib/Webserver.c                                             \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \
 	  $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
@@ -148,7 +146,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/RNDIS.c          \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -195,7 +193,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 CDEFS += -DNO_DECODE_ETHERNET -DNO_DECODE_ARP -DNO_DECODE_ICMP -DNO_DECODE_IP -DNO_DECODE_TCP -DNO_DECODE_UDP -DNO_DECODE_DHCP
diff --git a/Demos/Device/USBtoSerial/Descriptors.h b/Demos/Device/USBtoSerial/Descriptors.h
index 41b44300a..9e372e35b 100644
--- a/Demos/Device/USBtoSerial/Descriptors.h
+++ b/Demos/Device/USBtoSerial/Descriptors.h
@@ -37,26 +37,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
+
 	/* Macros: */
-		/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
-		 *  uniform structure but variable sized data payloads, thus cannot be represented accurately by
-		 *  a single typedef struct. A macro is used instead so that functional descriptors can be created
-		 *  easily by specifying the size of the payload. This allows sizeof() to work correctly.
-		 *
-		 *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload
-		 */
-		#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \
-		     struct                                        \
-		     {                                             \
-		          USB_Descriptor_Header_t Header;          \
-			      uint8_t                 SubType;         \
-		          uint8_t                 Data[DataSize];  \
-		     }
-			 
 		/** Endpoint number of the CDC device-to-host notification IN endpoint. */
 		#define CDC_NOTIFICATION_EPNUM         2
 
diff --git a/Demos/Device/USBtoSerial/USBtoSerial.c b/Demos/Device/USBtoSerial/USBtoSerial.c
index 7cef56560..7c89278ef 100644
--- a/Demos/Device/USBtoSerial/USBtoSerial.c
+++ b/Demos/Device/USBtoSerial/USBtoSerial.c
@@ -30,37 +30,54 @@
 
 #include "USBtoSerial.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = CDC_Task             , .TaskStatus = TASK_STOP },
-};
+RingBuff_t Rx_Buffer;
+RingBuff_t Tx_Buffer;
 
-/* Globals: */
-/** Contains the current baud rate and other settings of the virtual serial port.
- *
- *  These values are set by the host via a class-specific request, and the physical USART should be reconfigured to match the
- *  new settings each time they are changed by the host.
- */
-CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
-                                 .CharFormat  = OneStopBit,
-                                 .ParityType  = Parity_None,
-                                 .DataBits    = 8            };
+USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
+	{
+		.ControlInterfaceNumber     = 0,
 
-/** Ring (circular) buffer to hold the RX data - data from the host to the attached device on the serial port. */
-RingBuff_t Rx_Buffer;
+		.DataINEndpointNumber       = CDC_TX_EPNUM,
+		.DataINEndpointSize         = CDC_TXRX_EPSIZE,
 
-/** Ring (circular) buffer to hold the TX data - data from the attached device on the serial port to the host. */
-RingBuff_t Tx_Buffer;
+		.DataOUTEndpointNumber      = CDC_RX_EPNUM,
+		.DataOUTEndpointSize        = CDC_TXRX_EPSIZE,
 
-/** Flag to indicate if the USART is currently transmitting data from the Rx_Buffer circular buffer. */
-volatile bool Transmitting = false;
+		.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+		.NotificationEndpointSize   = CDC_NOTIFICATION_EPSIZE,
+	};
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
 int main(void)
+{
+	SetupHardware();
+	
+	Buffer_Initialize(&Rx_Buffer);
+	Buffer_Initialize(&Tx_Buffer);
+
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+
+	for (;;)
+	{
+		for (uint8_t DataBytesRem = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)
+		{
+			if (!(BUFF_STATICSIZE - Rx_Buffer.Elements))
+			  break;
+			  
+			Buffer_StoreElement(&Rx_Buffer, USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface));
+		}
+		
+		if (Tx_Buffer.Elements)
+		  USB_CDC_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&Rx_Buffer));
+		  
+		if (Rx_Buffer.Elements)
+		  Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
+		
+		USB_CDC_USBTask(&VirtualSerial_CDC_Interface);
+		USB_USBTask();
+	}
+}
+
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -70,304 +87,61 @@ int main(void)
 	clock_prescale_set(clock_div_1);
 
 	/* Hardware Initialization */
+	Joystick_Init();
 	LEDs_Init();
-	ReconfigureUSART();
-	
-	/* Ring buffer Initialization */
-	Buffer_Initialize(&Rx_Buffer);
-	Buffer_Initialize(&Tx_Buffer);
-	
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
- *  starts the library USB task to begin the enumeration and USB management process.
- */
 void EVENT_USB_Connect(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-
-	/* Indicate USB enumerating */
-	UpdateStatus(Status_USBEnumerating);
+	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
-/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- *  the status LEDs and stops the USB management and CDC management tasks.
- */
 void EVENT_USB_Disconnect(void)
 {
-	/* Stop running CDC and USB management tasks */
-	Scheduler_SetTaskMode(CDC_Task, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-	
-	/* Reset Tx and Rx buffers, device disconnected */
-	Buffer_Initialize(&Rx_Buffer);
-	Buffer_Initialize(&Tx_Buffer);
-
-	/* Indicate USB not ready */
-	UpdateStatus(Status_USBNotReady);
+	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
- *  of the USB device after enumeration - the device endpoints are configured and the CDC management task started.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup CDC Notification, Rx and Tx Endpoints */
-	Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
+	LEDs_SetAllLEDs(LEDMASK_USB_READY);
 
-	Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
-		                       ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-
-	/* Indicate USB connected and ready */
-	UpdateStatus(Status_USBReady);
-
-	/* Start CDC task */
-	Scheduler_SetTaskMode(CDC_Task, TASK_RUN);
+	if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
+	  LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the CDC control commands,
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	uint8_t* LineCodingData = (uint8_t*)&LineCoding;
-
-	/* Process CDC specific control requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{	
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Write the line coding data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetLineEncoding:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-
-				/* Read the line coding data in from the host into the global struct */
-				Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
-
-				/* Finalize the stream transfer to clear the last packet from the host */
-				Endpoint_ClearIN();
-				
-				/* Reconfigure the USART with the new settings */
-				ReconfigureUSART();
-			}
-	
-			break;
-		case REQ_SetControlLineState:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{				
-				/* Acknowledge the SETUP packet, ready for data transfer */
-				Endpoint_ClearSETUP();
-				
-				/* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
-				         lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
-						 CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
-				*/
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-	
-			break;
-	}
-}
-
-/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */
-TASK(CDC_Task)
-{
-	if (USB_IsConnected)
-	{
-#if 0
-		/* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232
-				 handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:
-		*/
-
-		USB_Notification_Header_t Notification = (USB_Notification_Header_t)
-			{
-				.NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
-				.Notification     = NOTIF_SerialState,
-				.wValue           = 0,
-				.wIndex           = 0,
-				.wLength          = sizeof(uint16_t),
-			};
-			
-		uint16_t LineStateMask;
-		
-		// Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host
-		
-		Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
-		Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
-		Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
-		Endpoint_ClearIN();
-#endif
-
-		/* Select the Serial Rx Endpoint */
-		Endpoint_SelectEndpoint(CDC_RX_EPNUM);
-		
-		/* Check to see if a packet has been received from the host */
-		if (Endpoint_IsOUTReceived())
-		{
-			/* Read the bytes in from the endpoint into the buffer while space is available */
-			while (Endpoint_BytesInEndpoint() && (BUFF_STATICSIZE - Rx_Buffer.Elements))
-			{
-				/* Store each character from the endpoint */
-				Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte());
-			}
-			
-			/* Check to see if all bytes in the current packet have been read */
-			if (!(Endpoint_BytesInEndpoint()))
-			{
-				/* Clear the endpoint buffer */
-				Endpoint_ClearOUT();
-			}
-		}
-		
-		/* Check if Rx buffer contains data - if so, send it */
-		if (Rx_Buffer.Elements)
-		  Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
-
-		/* Select the Serial Tx Endpoint */
-		Endpoint_SelectEndpoint(CDC_TX_EPNUM);
-
-		/* Check if the Tx buffer contains anything to be sent to the host */
-		if (Tx_Buffer.Elements)
-		{
-			/* Wait until Serial Tx Endpoint Ready for Read/Write */
-			while (!(Endpoint_IsReadWriteAllowed()));
-			
-			/* Write the bytes from the buffer to the endpoint while space is available */
-			while (Tx_Buffer.Elements && (Endpoint_BytesInEndpoint() < CDC_TXRX_EPSIZE))
-			{
-				/* Write each byte retreived from the buffer to the endpoint */
-				Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer));
-			}
-			
-			/* Remember if the packet to send completely fills the endpoint */
-			bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);
-			
-			/* Send the data */
-			Endpoint_ClearIN();
-
-			/* If no more data to send and the last packet filled the endpoint, send an empty packet to release
-			 * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */
-			if (IsFull && !(Tx_Buffer.Elements))
-			{
-				/* Wait until Serial Tx Endpoint Ready for Read/Write */
-				while (!(Endpoint_IsReadWriteAllowed()));
-
-				/* Send an empty packet to terminate the transfer */
-				Endpoint_ClearIN();
-			}
-		}
-	}
+	USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);
 }
 
-/** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received
- *  character into the Tx_Buffer circular buffer for later transmission to the host.
- */
 ISR(USART1_RX_vect, ISR_BLOCK)
 {
-	/* Only store received characters if the USB interface is connected */
 	if (USB_IsConnected)
-	{
-		/* Character received, store it into the buffer */
-		Buffer_StoreElement(&Tx_Buffer, UDR1);
-	}
+	  Buffer_StoreElement(&Tx_Buffer, UDR1);
 }
 
-/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
- *  log to a serial port, or anything else that is suitable for status updates.
- *
- *  \param CurrentStatus  Current status of the system, from the USBtoSerial_StatusCodes_t enum
- */
-void UpdateStatus(uint8_t CurrentStatus)
-{
-	uint8_t LEDMask = LEDS_NO_LEDS;
-	
-	/* Set the LED mask to the appropriate LED mask based on the given status code */
-	switch (CurrentStatus)
-	{
-		case Status_USBNotReady:
-			LEDMask = (LEDS_LED1);
-			break;
-		case Status_USBEnumerating:
-			LEDMask = (LEDS_LED1 | LEDS_LED2);
-			break;
-		case Status_USBReady:
-			LEDMask = (LEDS_LED2 | LEDS_LED4);
-			break;
-	}
-	
-	/* Set the board LEDs to the new LED mask */
-	LEDs_SetAllLEDs(LEDMask);
-}
-
-/** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */
-void ReconfigureUSART(void)
+void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
 {
 	uint8_t ConfigMask = 0;
 
-	/* Determine parity - non odd/even parity mode defaults to no parity */
-	if (LineCoding.ParityType == Parity_Odd)
+	if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Odd)
 	  ConfigMask = ((1 << UPM11) | (1 << UPM10));
-	else if (LineCoding.ParityType == Parity_Even)
+	else if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Even)
 	  ConfigMask = (1 << UPM11);
 
-	/* Determine stop bits - 1.5 stop bits is set as 1 stop bit due to hardware limitations */
-	if (LineCoding.CharFormat == TwoStopBits)
+	if (CDCInterfaceInfo->LineEncoding.CharFormat == TwoStopBits)
 	  ConfigMask |= (1 << USBS1);
 
-	/* Determine data size - 5, 6, 7, or 8 bits are supported */
-	if (LineCoding.DataBits == 6)
+	if (CDCInterfaceInfo->LineEncoding.DataBits == 6)
 	  ConfigMask |= (1 << UCSZ10);
-	else if (LineCoding.DataBits == 7)
+	else if (CDCInterfaceInfo->LineEncoding.DataBits == 7)
 	  ConfigMask |= (1 << UCSZ11);
-	else if (LineCoding.DataBits == 8)
+	else if (CDCInterfaceInfo->LineEncoding.DataBits == 8)
 	  ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
 	
-	/* Enable double speed, gives better error percentages at 8MHz */
-	UCSR1A = (1 << U2X1);
-	
-	/* Enable transmit and receive modules and interrupts */
+	UCSR1A = (1 << U2X1);	
 	UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
-
-	/* Set the USART mode to the mask generated by the Line Coding options */
-	UCSR1C = ConfigMask;
-	
-	/* Set the USART baud rate register to the desired baud rate value */
-	UBRR1  = SERIAL_2X_UBBRVAL((uint16_t)LineCoding.BaudRateBPS);
+	UCSR1C = ConfigMask;	
+	UBRR1  = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->LineEncoding.BaudRateBPS);
 }
diff --git a/Demos/Device/USBtoSerial/USBtoSerial.h b/Demos/Device/USBtoSerial/USBtoSerial.h
index 8e7e8aed8..7ff796e70 100644
--- a/Demos/Device/USBtoSerial/USBtoSerial.h
+++ b/Demos/Device/USBtoSerial/USBtoSerial.h
@@ -46,140 +46,28 @@
 
 		#include "Lib/RingBuff.h"
 
-		#include <LUFA/Version.h>                         // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>                 // USB Functionality
-		#include <LUFA/Drivers/Peripheral/Serial.h>       // USART driver
-		#include <LUFA/Drivers/Board/LEDs.h>              // LEDs driver
-		#include <LUFA/Scheduler/Scheduler.h>             // Simple scheduler for task management
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/Board/LEDs.h>
+		#include <LUFA/Drivers/Board/Joystick.h>
+		#include <LUFA/Drivers/Peripheral/Serial.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/CDC.h>
 
 	/* Macros: */
-		/** CDC Class specific request to get the current virtual serial port configuration settings. */
-		#define REQ_GetLineEncoding          0x21
-
-		/** CDC Class specific request to set the current virtual serial port configuration settings. */
-		#define REQ_SetLineEncoding          0x20
-
-		/** CDC Class specific request to set the current virtual serial port handshake line states. */
-		#define REQ_SetControlLineState      0x22
-		
-		/** Notification type constant for a change in the virtual serial port handshake line states, for
-		 *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC 
-		 *  notification endpoint.
-		 */
-		#define NOTIF_SerialState            0x20
-
-		/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
-		 *  from the host, to indicate that the DTR line state should be high.
-		 */
-		#define CONTROL_LINE_OUT_DTR         (1 << 0)
-
-		/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
-		 *  from the host, to indicate that theRTS line state should be high.
-		 */
-		#define CONTROL_LINE_OUT_RTS         (1 << 1)
+		#define LEDMASK_USB_NOTREADY      LEDS_LED1
+		#define LEDMASK_USB_ENUMERATING  (LEDS_LED2 | LEDS_LED3)
+		#define LEDMASK_USB_READY        (LEDS_LED2 | LEDS_LED4)
+		#define LEDMASK_USB_ERROR        (LEDS_LED1 | LEDS_LED3)
 		
-		/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the DCD line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_DCD          (1 << 0)
-
-		/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the DSR line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_DSR          (1 << 1)
-
-		/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the BREAK line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_BREAK        (1 << 2)
-
-		/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
-		 *  from the device to the host, to indicate that the RING line state is currently high.
-		 */
-		#define CONTROL_LINE_IN_RING         (1 << 3)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a framing error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a parity error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_PARITYERROR  (1 << 5)
-
-		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
-		 *  to indicate that a data overrun error has occurred on the virtual serial port.
-		 */
-		#define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
-		
-	/* Type Defines: */
-		/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
-		 *  as set by the host via a class specific request.
-		 */
-		typedef struct
-		{
-			uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
-			uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the
-			                      *   CDCDevice_CDC_LineCodingFormats_t enum
-			                      */
-			uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the
-			                      *   CDCDevice_LineCodingParity_t enum
-			                      */
-			uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */
-		} CDC_Line_Coding_t;
-		
-		/** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
-		 *  change in the device state asynchronously.
-		 */
-		typedef struct
-		{
-			uint8_t  NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
-			                            *   from the library StdRequestType.h header
-			                            */
-			uint8_t  Notification; /**< Notification value, a NOTIF_* constant */
-			uint16_t wValue; /**< Notification wValue, notification-specific */
-			uint16_t wIndex; /**< Notification wIndex, notification-specific */
-			uint16_t wLength; /**< Notification wLength, notification-specific */
-		} USB_Notification_Header_t;
-		
-	/* Enums: */
-		/** Enum for the possible line encoding formats of a virtual serial port. */
-		enum CDCDevice_CDC_LineCodingFormats_t
-		{
-			OneStopBit          = 0, /**< Each frame contains one stop bit */
-			OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
-			TwoStopBits         = 2, /**< Each frame contains two stop bits */
-		};
-		
-		/** Enum for the possible line encoding parity settings of a virtual serial port. */
-		enum CDCDevice_LineCodingParity_t
-		{
-			Parity_None         = 0, /**< No parity bit mode on each frame */
-			Parity_Odd          = 1, /**< Odd parity bit mode on each frame */
-			Parity_Even         = 2, /**< Even parity bit mode on each frame */
-			Parity_Mark         = 3, /**< Mark parity bit mode on each frame */
-			Parity_Space        = 4, /**< Space parity bit mode on each frame */
-		};
-
-		/** Enum for the possible status codes for passing to the UpdateStatus() function. */
-		enum USBtoSerial_StatusCodes_t
-		{
-			Status_USBNotReady    = 0, /**< USB is not ready (disconnected from a USB host) */
-			Status_USBEnumerating = 1, /**< USB interface is enumerating */
-			Status_USBReady       = 2, /**< USB interface is connected and ready */
-		};
-		
-	/* Tasks: */
-		TASK(CDC_Task);
-
 	/* Function Prototypes: */
+		void SetupHardware(void);
+
 		void EVENT_USB_Connect(void);
 		void EVENT_USB_Disconnect(void);
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-
-		void ReconfigureUSART(void);
-		void UpdateStatus(uint8_t CurrentStatus);
+		void EVENT_USB_StartOfFrame(void);
+		
+		void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
 
 #endif
diff --git a/Demos/Device/USBtoSerial/makefile b/Demos/Device/USBtoSerial/makefile
index 708e87246..5cf9c617e 100644
--- a/Demos/Device/USBtoSerial/makefile
+++ b/Demos/Device/USBtoSerial/makefile
@@ -126,7 +126,6 @@ LUFA_PATH = ../../..
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
 	  Lib/RingBuff.c                                              \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -137,7 +136,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -184,7 +183,7 @@ CSTANDARD = -std=gnu99
 
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
-CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
+CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
 CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
 CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 
diff --git a/Demos/Host/GenericHIDHost/makefile b/Demos/Host/GenericHIDHost/makefile
index b17ae1641..b912b2ff8 100644
--- a/Demos/Host/GenericHIDHost/makefile
+++ b/Demos/Host/GenericHIDHost/makefile
@@ -138,7 +138,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Host/HIDParser.c        \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
diff --git a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
index 95aafca8c..f47e9f5ed 100644
--- a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
+++ b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
@@ -119,10 +119,10 @@ static uint8_t MassStore_WaitForDataReceived(void)
 	while (!(Pipe_IsINReceived()))
 	{
 		/* Check to see if a new frame has been issued (1ms elapsed) */
-		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		if (FrameElapsed)
 		{
 			/* Clear the flag and decrement the timeout period counter */
-			USB_INT_Clear(USB_INT_HSOFI);
+			FrameElapsed = false;
 			TimeoutMSRem--;
 
 			/* Check to see if the timeout period for the command has elapsed */
diff --git a/Demos/Host/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/StillImageHost/Lib/StillImageCommands.c
index 8f05e48f4..f2f666bd1 100644
--- a/Demos/Host/StillImageHost/Lib/StillImageCommands.c
+++ b/Demos/Host/StillImageHost/Lib/StillImageCommands.c
@@ -109,10 +109,10 @@ uint8_t SImage_RecieveBlockHeader(void)
 	while (!(Pipe_IsReadWriteAllowed()))
 	{
 		/* Check to see if a new frame has been issued (1ms elapsed) */
-		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		if (FrameElapsed)
 		{
 			/* Clear the flag and decrement the timeout period counter */
-			USB_INT_Clear(USB_INT_HSOFI);
+			FrameElapsed = false;
 			TimeoutMSRem--;
 
 			/* Check to see if the timeout period for the command has elapsed */
diff --git a/Demos/OTG/TestApp/TestApp.h b/Demos/OTG/TestApp/TestApp.h
index de4d52612..7ae5663d9 100644
--- a/Demos/OTG/TestApp/TestApp.h
+++ b/Demos/OTG/TestApp/TestApp.h
@@ -45,7 +45,6 @@
 		#include <LUFA/Version.h>                               // Library Version Information
 		#include <LUFA/Drivers/USB/USB.h>                       // USB Functionality
 		#include <LUFA/Scheduler/Scheduler.h>                   // Simple scheduler for task management
-		#include <LUFA/MemoryAllocator/DynAlloc.h>              // Auto-defragmenting Dynamic Memory allocation
 		#include <LUFA/Drivers/Misc/TerminalCodes.h>            // ANSI Terminal Escape Codes
 		#include <LUFA/Drivers/Peripheral/ADC.h>                // ADC driver
 		#include <LUFA/Drivers/Peripheral/SerialStream.h>       // USART Stream driver
diff --git a/Demos/OTG/TestApp/makefile b/Demos/OTG/TestApp/makefile
index dd6d8f43f..a8bf4ac42 100644
--- a/Demos/OTG/TestApp/makefile
+++ b/Demos/OTG/TestApp/makefile
@@ -127,7 +127,6 @@ SRC = $(TARGET).c                                                 \
 	  TestEvents.c                                                \
 	  Descriptors.c                                               \
 	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
-	  $(LUFA_PATH)/LUFA/MemoryAllocator/DynAlloc.c                \
 	  $(LUFA_PATH)/LUFA/Drivers/Board/Temperature.c               \
 	  $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \
 	  $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \
@@ -141,7 +140,6 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
@@ -189,7 +187,6 @@ CSTANDARD = -std=gnu99
 # Place -D or -U options here for C sources
 CDEFS  = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
 CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES
-CDEFS += -DNUM_BLOCKS=100 -DBLOCK_SIZE=8 -DNUM_HANDLES=20
 
 
 # Place -D or -U options here for ASM sources
diff --git a/LUFA.pnproj b/LUFA.pnproj
index 235ccfa3b..ae38c0bb9 100644
--- a/LUFA.pnproj
+++ b/LUFA.pnproj
@@ -1 +1 @@
-<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><Folder name="Lib"><File path="Demos\Device\MassStorage\Lib\DataflashManager.c"></File><File path="Demos\Device\MassStorage\Lib\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI.c"></File><File path="Demos\Device\MassStorage\Lib\SCSI.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><Folder name="Lib"><File path="Demos\Device\RNDISEthernet\Lib\Webserver.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\Lib\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.c"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDISConstants.h"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Webserver.c"></File></Folder><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File></Folder><Folder name="USBtoSerial"><Folder name="Lib"><File path="Demos\Device\USBtoSerial\Lib\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\Lib\RingBuff.h"></File></Folder><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><Folder name="Lib"><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><Folder name="Lib"><File path="Demos\Host\StillImageHost\Lib\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.h"></File></Folder><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><File path="LUFA\Drivers\USB\Class\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\HIDReportData.h"></File></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="Scheduler"><File path="LUFA\Scheduler\Scheduler.h"></File><File path="LUFA\Scheduler\Scheduler.c"></File></Folder><Folder name="MemoryAllocator"><File path="LUFA\MemoryAllocator\DynAlloc.h"></File><File path="LUFA\MemoryAllocator\DynAlloc.c"></File></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\Groups.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\SchedulerOverview.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\WritingBoardDrivers.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><Folder name="Lib"><File path="Projects\Magstripe\Lib\CircularBitBuffer.c"></File><File path="Projects\Magstripe\Lib\CircularBitBuffer.h"></File><File path="Projects\Magstripe\Lib\MagstripeHW.h"></File></Folder><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
+<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><Folder name="Lib"><File path="Demos\Device\MassStorage\Lib\DataflashManager.c"></File><File path="Demos\Device\MassStorage\Lib\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI.c"></File><File path="Demos\Device\MassStorage\Lib\SCSI.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><Folder name="Lib"><File path="Demos\Device\RNDISEthernet\Lib\Webserver.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\Lib\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Webserver.c"></File></Folder><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File></Folder><Folder name="USBtoSerial"><Folder name="Lib"><File path="Demos\Device\USBtoSerial\Lib\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\Lib\RingBuff.h"></File></Folder><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><Folder name="Lib"><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><Folder name="Lib"><File path="Demos\Host\StillImageHost\Lib\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.h"></File></Folder><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><Folder name="Device"><File path="LUFA\Drivers\USB\Class\Device\HID.c"></File><File path="LUFA\Drivers\USB\Class\Device\HID.h"></File><File path="LUFA\Drivers\USB\Class\Device\CDC.c"></File><File path="LUFA\Drivers\USB\Class\Device\CDC.h"></File><File path="LUFA\Drivers\USB\Class\Device\RNDIS.c"></File><File path="LUFA\Drivers\USB\Class\Device\RNDIS.h"></File><File path="LUFA\Drivers\USB\Class\Device\RNDISConstants.h"></File><File path="LUFA\Drivers\USB\Class\Device\MassStorage.c"></File><File path="LUFA\Drivers\USB\Class\Device\MassStorage.h"></File><File path="LUFA\Drivers\USB\Class\Device\Audio.c"></File><File path="LUFA\Drivers\USB\Class\Device\Audio.h"></File></Folder><Folder name="Host"><File path="LUFA\Drivers\USB\Class\Host\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\Host\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\Host\HIDReportData.h"></File></Folder></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\Groups.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\WritingBoardDrivers.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><Folder name="Lib"><File path="Projects\Magstripe\Lib\CircularBitBuffer.c"></File><File path="Projects\Magstripe\Lib\CircularBitBuffer.h"></File><File path="Projects\Magstripe\Lib\MagstripeHW.h"></File></Folder><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
diff --git a/LUFA/ChangeLog.txt b/LUFA/ChangeLog.txt
index ac675348b..fe3b63360 100644
--- a/LUFA/ChangeLog.txt
+++ b/LUFA/ChangeLog.txt
@@ -4,6 +4,14 @@
  *  documentation pages. It is not a project source file.
  */
    
+========== TODO: ===========
+	- Document new class drivers
+	- Re-document all demos now that they have changed
+	- Add standardized descriptor names to class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES
+	- Add C++ compatibility to class drivers
+	- Disable JTAG in demos
+============================
+
  /** \page Page_ChangeLog Project Changelog
   *
   *  \section Sec_ChangeLogXXXXXX Version XXXXXX
@@ -30,6 +38,8 @@
   *    LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs
   *  - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure
   *  - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt
+  *  - Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated)
+  *  - Removed psuedo-scheduler, dynamic memory block allocator from the library (no longer needed and not used respectively)
   *
   *
   *  \section Sec_ChangeLog090510 Version 090510
diff --git a/LUFA/DirectorySummaries.txt b/LUFA/DirectorySummaries.txt
index f43984760..3fae9c18e 100644
--- a/LUFA/DirectorySummaries.txt
+++ b/LUFA/DirectorySummaries.txt
@@ -10,19 +10,6 @@
  *  This folder contains header files which are common to all parts of the LUFA library. They may be used freely in
  *  user applications.
  *
- *  \dir MemoryAllocator
- *  \brief Auto-defragmenting dynamic memory allocation library.
- *  
- *  This folder contains a simple handle-based dynamic memory allocation library, capable of handing out memory in
- *  block chunks. As new memory is allocated, the library will defragment the already allocated memory to ensure
- *  optimal memory usage. It is not used within the LUFA library, and is provided as a convenience for user applications.
- *
- *  \dir Scheduler
- *  \brief Simple round-robbin scheduler.
- *  
- *  This folder contains the simple LUFA round-robbin scheduler, provided as a convenience for user applications. It
- *  is very simple in design, and is intended to make code easier to read, rather than providing a complete RTOS kernel.
- *
  *  \dir Drivers
  *  \brief Library hardware and software drivers.
  *  
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
new file mode 100644
index 000000000..b0800ba0f
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -0,0 +1,154 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#include "Audio.h"
+
+void USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+	if (!(Endpoint_IsSETUPReceived()))
+	  return;
+	  
+//	if (USB_ControlRequest.wIndex != AudioInterfaceInfo->InterfaceNumber)
+//	  return;
+
+	switch (USB_ControlRequest.bRequest)
+	{
+		case REQ_SetInterface:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+				
+				AudioInterfaceInfo->InterfaceEnabled = (USB_ControlRequest.wValue != 0);
+				  
+				while (!(Endpoint_IsINReady()));
+				Endpoint_ClearIN();
+			}
+
+			break;
+	}
+}
+
+bool USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+	if (AudioInterfaceInfo->DataINEndpointNumber)
+	{
+		if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataINEndpointNumber, EP_TYPE_ISOCHRONOUS,
+										 ENDPOINT_DIR_IN, AudioInterfaceInfo->DataINEndpointSize,
+										 ENDPOINT_BANK_DOUBLE)))
+		{
+			return false;
+		}
+	}
+
+	if (AudioInterfaceInfo->DataOUTEndpointNumber)
+	{
+		if (!(Endpoint_ConfigureEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_ISOCHRONOUS,
+										 ENDPOINT_DIR_OUT, AudioInterfaceInfo->DataOUTEndpointSize,
+										 ENDPOINT_BANK_DOUBLE)))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+int8_t USB_Audio_ReadSample8(void)
+{
+	int8_t Sample;
+
+	Sample = Endpoint_Read_Byte();
+
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearOUT();
+	
+	return Sample;
+}
+
+int16_t USB_Audio_ReadSample16(void)
+{
+	int16_t Sample;
+
+	Sample = (int16_t)Endpoint_Read_Word_LE();
+		  
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearOUT();
+
+	return Sample;
+}
+
+int32_t USB_Audio_ReadSample24(void)
+{
+	int32_t Sample;
+
+	Sample = (((uint32_t)Endpoint_Read_Byte() << 16) | Endpoint_Read_Word_LE());
+		  
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearOUT();
+
+	return Sample;
+}
+
+void USB_Audio_WriteSample8(int8_t Sample)
+{
+	Endpoint_Write_Byte(Sample);
+
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample16(int16_t Sample)
+{
+	Endpoint_Write_Word_LE(Sample);
+
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearIN();
+}
+
+void USB_Audio_WriteSample24(int32_t Sample)
+{
+	Endpoint_Write_Byte(Sample >> 16);
+	Endpoint_Write_Word_LE(Sample);
+
+	if (!(Endpoint_IsReadWriteAllowed()))
+	  Endpoint_ClearIN();
+}
+
+bool USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(AudioInterfaceInfo->DataOUTEndpointNumber);
+	return Endpoint_IsOUTReceived();
+}
+
+bool USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(AudioInterfaceInfo->DataINEndpointNumber);
+	return Endpoint_IsINReady();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
new file mode 100644
index 000000000..aa7b4069c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -0,0 +1,70 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#ifndef _AUDIO_CLASS_H_
+#define _AUDIO_CLASS_H_
+
+	/* Includes: */
+		#include "../../USB.h"
+
+		#include <string.h>
+
+	/* Macros: */
+
+	/* Enums: */
+
+	/* Type Defines: */
+		typedef struct
+		{
+			uint8_t  InterfaceNumber;
+
+			uint8_t  DataINEndpointNumber;
+			uint16_t DataINEndpointSize;
+
+			uint8_t  DataOUTEndpointNumber;
+			uint16_t DataOUTEndpointSize;
+
+			bool     InterfaceEnabled;
+		} USB_ClassInfo_Audio_t;
+		
+	/* Function Prototypes: */
+		bool     USB_Audio_ConfigureEndpoints(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+		void     USB_Audio_ProcessControlPacket(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+		void     USB_Audio_USBTask(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+		
+		int8_t   USB_Audio_ReadSample8(void);
+		int16_t  USB_Audio_ReadSample16(void);
+		int32_t  USB_Audio_ReadSample24(void);
+		void     USB_Audio_WriteSample8(int8_t Sample);
+		void     USB_Audio_WriteSample16(int16_t Sample);
+		void     USB_Audio_WriteSample24(int32_t Sample);
+		bool     USB_Audio_IsSampleReceived(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+		bool     USB_Audio_IsReadyForNextSample(USB_ClassInfo_Audio_t* AudioInterfaceInfo);
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
new file mode 100644
index 000000000..8acaac7a1
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -0,0 +1,185 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#define  INCLUDE_FROM_CDC_CLASS_C
+#include "CDC.h"
+
+void USB_CDC_Event_Stub(void)
+{
+
+}
+
+void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+	if (!(Endpoint_IsSETUPReceived()))
+	  return;
+	  
+	if (USB_ControlRequest.wIndex != CDCInterfaceInfo->ControlInterfaceNumber)
+	  return;
+
+	switch (USB_ControlRequest.bRequest)
+	{
+		case REQ_GetLineEncoding:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+				Endpoint_Write_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+				Endpoint_ClearOUT();
+			}
+			
+			break;
+		case REQ_SetLineEncoding:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+				Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->LineEncoding, sizeof(CDCInterfaceInfo->LineEncoding));
+				Endpoint_ClearIN();
+
+				EVENT_USB_CDC_LineEncodingChanged(CDCInterfaceInfo);
+			}
+	
+			break;
+		case REQ_SetControlLineState:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{				
+				Endpoint_ClearSETUP();
+				
+				CDCInterfaceInfo->ControlLineState = USB_ControlRequest.wValue;
+				
+				EVENT_USB_CDC_ControLineStateChanged();
+
+				while (!(Endpoint_IsINReady()));
+				Endpoint_ClearIN();
+			}
+	
+			break;
+	}
+}
+
+bool USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+	if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+							         ENDPOINT_DIR_IN, CDCInterfaceInfo->DataINEndpointSize,
+							         ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+	                                 ENDPOINT_DIR_OUT, CDCInterfaceInfo->DataOUTEndpointSize,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	if (!(Endpoint_ConfigureEndpoint(CDCInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+	                                 ENDPOINT_DIR_IN, CDCInterfaceInfo->NotificationEndpointSize,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	return true;
+}
+
+void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+	if (!(USB_IsConnected))
+	  return;
+
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+	if (!(Endpoint_BytesInEndpoint()))
+	  return;
+	  
+	if (!(Endpoint_IsReadWriteAllowed()))
+	{
+		Endpoint_ClearIN();
+		while (!(Endpoint_IsReadWriteAllowed()));
+	}	
+	
+	Endpoint_ClearIN();
+}
+
+void USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length)
+{
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+	Endpoint_Write_Stream_LE(Data, Length, NO_STREAM_CALLBACK);
+}
+
+void USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data)
+{
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->DataINEndpointNumber);
+
+	if (!(Endpoint_IsReadWriteAllowed()))
+	{
+		Endpoint_ClearIN();
+		while (!(Endpoint_IsReadWriteAllowed()));
+	}
+
+	Endpoint_Write_Byte(Data);	
+}
+
+uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+
+	return Endpoint_BytesInEndpoint();
+}
+
+uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->DataOUTEndpointNumber);
+	
+	uint8_t DataByte = Endpoint_Read_Byte();
+	
+	if (!(Endpoint_BytesInEndpoint()))
+	  Endpoint_ClearOUT();
+	  
+	return DataByte;
+}
+
+void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
+{
+	Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);
+	
+	USB_Request_Header_t Notification = (USB_Request_Header_t)
+		{
+			.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+			.bRequest      = NOTIF_SerialState,
+			.wValue        = 0,
+			.wIndex        = 0,
+			.wLength       = sizeof(uint16_t),
+		};
+
+	Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+	Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask), NO_STREAM_CALLBACK);
+	Endpoint_ClearIN();
+}
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
new file mode 100644
index 000000000..bbe1c9838
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -0,0 +1,188 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#ifndef _CDC_CLASS_H_
+#define _CDC_CLASS_H_
+
+	/* Includes: */
+		#include "../../USB.h"
+
+		#include <string.h>
+
+	/* Macros: */
+		/** CDC Class specific request to get the current virtual serial port configuration settings. */
+		#define REQ_GetLineEncoding          0x21
+
+		/** CDC Class specific request to set the current virtual serial port configuration settings. */
+		#define REQ_SetLineEncoding          0x20
+
+		/** CDC Class specific request to set the current virtual serial port handshake line states. */
+		#define REQ_SetControlLineState      0x22
+		
+		/** Notification type constant for a change in the virtual serial port handshake line states, for
+		 *  use with a USB_Notification_Header_t notification structure when sent to the host via the CDC 
+		 *  notification endpoint.
+		 */
+		#define NOTIF_SerialState            0x20
+
+		/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
+		 *  from the host, to indicate that the DTR line state should be high.
+		 */
+		#define CONTROL_LINE_OUT_DTR         (1 << 0)
+
+		/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
+		 *  from the host, to indicate that theRTS line state should be high.
+		 */
+		#define CONTROL_LINE_OUT_RTS         (1 << 1)
+		
+		/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
+		 *  from the device to the host, to indicate that the DCD line state is currently high.
+		 */
+		#define CONTROL_LINE_IN_DCD          (1 << 0)
+
+		/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
+		 *  from the device to the host, to indicate that the DSR line state is currently high.
+		 */
+		#define CONTROL_LINE_IN_DSR          (1 << 1)
+
+		/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
+		 *  from the device to the host, to indicate that the BREAK line state is currently high.
+		 */
+		#define CONTROL_LINE_IN_BREAK        (1 << 2)
+
+		/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
+		 *  from the device to the host, to indicate that the RING line state is currently high.
+		 */
+		#define CONTROL_LINE_IN_RING         (1 << 3)
+
+		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+		 *  to indicate that a framing error has occurred on the virtual serial port.
+		 */
+		#define CONTROL_LINE_IN_FRAMEERROR   (1 << 4)
+
+		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+		 *  to indicate that a parity error has occurred on the virtual serial port.
+		 */
+		#define CONTROL_LINE_IN_PARITYERROR  (1 << 5)
+
+		/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
+		 *  to indicate that a data overrun error has occurred on the virtual serial port.
+		 */
+		#define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
+		
+		/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
+		 *  uniform structure but variable sized data payloads, thus cannot be represented accurately by
+		 *  a single typedef struct. A macro is used instead so that functional descriptors can be created
+		 *  easily by specifying the size of the payload. This allows sizeof() to work correctly.
+		 *
+		 *  \param DataSize  Size in bytes of the CDC functional descriptor's data payload
+		 */
+		#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize)        \
+		     struct                                        \
+		     {                                             \
+		          USB_Descriptor_Header_t Header;          \
+			      uint8_t                 SubType;         \
+		          uint8_t                 Data[DataSize];  \
+		     }
+
+	/* Enums: */
+		/** Enum for the possible line encoding formats of a virtual serial port. */
+		enum CDCDevice_CDC_LineCodingFormats_t
+		{
+			OneStopBit          = 0, /**< Each frame contains one stop bit */
+			OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
+			TwoStopBits         = 2, /**< Each frame contains two stop bits */
+		};
+		
+		/** Enum for the possible line encoding parity settings of a virtual serial port. */
+		enum CDCDevice_LineCodingParity_t
+		{
+			Parity_None         = 0, /**< No parity bit mode on each frame */
+			Parity_Odd          = 1, /**< Odd parity bit mode on each frame */
+			Parity_Even         = 2, /**< Even parity bit mode on each frame */
+			Parity_Mark         = 3, /**< Mark parity bit mode on each frame */
+			Parity_Space        = 4, /**< Space parity bit mode on each frame */
+		};
+
+	/* Type Defines: */
+		/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+		 *  as set by the host via a class specific request.
+		 */
+		typedef struct
+		{
+			uint8_t  ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
+
+			uint8_t  DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
+			uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
+
+			uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
+			uint16_t DataOUTEndpointSize;  /**< Size in bytes of the CDC interface's OUT data endpoint */
+
+			uint8_t  NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
+			uint16_t NotificationEndpointSize;  /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
+
+			uint8_t  ControlLineState;
+
+			struct
+			{
+				uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
+				uint8_t  CharFormat; /**< Character format of the virtual serial port, a value from the
+									  *   CDCDevice_CDC_LineCodingFormats_t enum
+									  */
+				uint8_t  ParityType; /**< Parity setting of the virtual serial port, a value from the
+									  *   CDCDevice_LineCodingParity_t enum
+									  */
+				uint8_t  DataBits; /**< Bits of data per character of the virtual serial port */
+			} LineEncoding;
+		} USB_ClassInfo_CDC_t;
+		
+	/* Function Prototypes: */
+		#if defined(INCLUDE_FROM_CDC_CLASS_C)
+			void USB_CDC_Event_Stub(void);
+			void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
+												   ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);
+			void EVENT_USB_CDC_ControLineStateChanged(void) ATTR_WEAK ATTR_ALIAS(USB_CDC_Event_Stub);; 
+		#endif
+	
+		void     USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		bool     USB_CDC_ConfigureEndpoints(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		void     USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		void     USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+
+		void     EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		void     EVENT_USB_CDC_ControLineStateChanged(void);
+
+		void     USB_CDC_SendString(USB_ClassInfo_CDC_t* CDCInterfaceInfo, char* Data, uint16_t Length);
+		void     USB_CDC_SendByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint8_t Data);
+		uint16_t USB_CDC_BytesReceived(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		uint8_t  USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);
+		
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
new file mode 100644
index 000000000..fbc5e3a5c
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -0,0 +1,211 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#include "HID.h"
+
+void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+	if (!(Endpoint_IsSETUPReceived()))
+	  return;
+	  
+	if (USB_ControlRequest.wIndex != HIDInterfaceInfo->InterfaceNumber)
+	  return;
+
+	switch (USB_ControlRequest.bRequest)
+	{
+		case REQ_GetReport:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();	
+
+				uint8_t  ReportINData[HIDInterfaceInfo->ReportBufferSize];
+				uint16_t ReportINSize;
+
+				memset(ReportINData, 0, sizeof(ReportINData));
+
+				ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+				Endpoint_Write_Control_Stream_LE(ReportINData, ReportINSize);
+				Endpoint_ClearOUT();
+			}
+		
+			break;
+		case REQ_SetReport:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+				
+				uint16_t ReportOUTSize = USB_ControlRequest.wLength;
+				uint8_t  ReportOUTData[ReportOUTSize];
+
+				Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
+				Endpoint_ClearIN();
+				
+				CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+			}
+			
+			break;
+		case REQ_GetProtocol:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				Endpoint_Write_Byte(HIDInterfaceInfo->UsingReportProtocol);
+				Endpoint_ClearIN();
+
+				while (!(Endpoint_IsOUTReceived()));
+				Endpoint_ClearOUT();
+			}
+			
+			break;
+		case REQ_SetProtocol:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				HIDInterfaceInfo->UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
+				
+				while (!(Endpoint_IsINReady()));
+				Endpoint_ClearIN();
+			}
+			
+			break;
+		case REQ_SetIdle:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+				
+				HIDInterfaceInfo->IdleCount = ((USB_ControlRequest.wValue >> 8) << 2);
+				
+				while (!(Endpoint_IsINReady()));
+				Endpoint_ClearIN();
+			}
+			
+			break;
+		case REQ_GetIdle:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{		
+				Endpoint_ClearSETUP();
+				
+				Endpoint_Write_Byte(HIDInterfaceInfo->IdleCount >> 2);
+				Endpoint_ClearIN();
+
+				while (!(Endpoint_IsOUTReceived()));
+				Endpoint_ClearOUT();
+			}
+
+			break;
+	}
+}
+
+bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+	HIDInterfaceInfo->UsingReportProtocol = true;
+
+	if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportINEndpointNumber, EP_TYPE_INTERRUPT,
+									 ENDPOINT_DIR_IN, HIDInterfaceInfo->ReportINEndpointSize, ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+	
+	if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+	{
+		if (!(Endpoint_ConfigureEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber, EP_TYPE_INTERRUPT,
+										 ENDPOINT_DIR_OUT, HIDInterfaceInfo->ReportOUTEndpointSize, ENDPOINT_BANK_SINGLE)))
+		{
+			return false;
+		}
+	}
+	
+	return true;
+}
+
+void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+	if (HIDInterfaceInfo->IdleMSRemaining)
+	  HIDInterfaceInfo->IdleMSRemaining--;
+}
+		
+void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)
+{
+	if (!(USB_IsConnected))
+	  return;
+
+	Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportINEndpointNumber);
+	
+	if (Endpoint_IsReadWriteAllowed() &&
+	    !(HIDInterfaceInfo->IdleCount && HIDInterfaceInfo->IdleMSRemaining))
+	{
+		if (HIDInterfaceInfo->IdleCount && !(HIDInterfaceInfo->IdleMSRemaining))
+		  HIDInterfaceInfo->IdleMSRemaining = HIDInterfaceInfo->IdleCount;
+
+		uint8_t  ReportINData[HIDInterfaceInfo->ReportBufferSize];
+		uint16_t ReportINSize;
+
+		memset(ReportINData, 0, sizeof(ReportINData));
+
+		ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+
+		if (ReportINSize)
+		{
+			Endpoint_Write_Stream_LE(ReportINData, ReportINSize
+			#if !defined(NO_STREAM_CALLBACKS)
+			                         , NO_STREAM_CALLBACK
+			#endif
+			                         );
+		}
+		
+		Endpoint_ClearIN();
+	}
+	
+	if (HIDInterfaceInfo->ReportOUTEndpointNumber)
+	{
+		Endpoint_SelectEndpoint(HIDInterfaceInfo->ReportOUTEndpointNumber);
+		
+		if (Endpoint_IsOUTReceived())
+		{
+			uint16_t ReportOUTSize = Endpoint_BytesInEndpoint();
+			uint8_t  ReportOUTData[ReportOUTSize];
+			
+			if (ReportOUTSize)
+			{
+				Endpoint_Read_Stream_LE(ReportOUTData, ReportOUTSize
+				#if !defined(NO_STREAM_CALLBACKS)
+			                            , NO_STREAM_CALLBACK
+				#endif
+			                            );
+			}
+			  
+			CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+			
+			Endpoint_ClearOUT();
+		}
+	}
+}
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
new file mode 100644
index 000000000..8fdeb064a
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/HID.h
@@ -0,0 +1,115 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#ifndef _HID_CLASS_H_
+#define _HID_CLASS_H_
+
+	/* Includes: */
+		#include "../../USB.h"
+
+		#include <string.h>
+
+	/* Macros: */
+		/** HID Class Specific Request to get the current HID report from the device. */
+		#define REQ_GetReport      0x01
+
+		/** HID Class Specific Request to get the current device idle count. */
+		#define REQ_GetIdle        0x02
+
+		/** HID Class Specific Request to set the current HID report to the device. */
+		#define REQ_SetReport      0x09
+
+		/** HID Class Specific Request to set the device's idle count. */
+		#define REQ_SetIdle        0x0A
+
+		/** HID Class Specific Request to get the current HID report protocol mode. */
+		#define REQ_GetProtocol    0x03
+
+		/** HID Class Specific Request to set the current HID report protocol mode. */
+		#define REQ_SetProtocol    0x0B
+
+		/** Descriptor header type value, to indicate a HID class HID descriptor. */
+		#define DTYPE_HID          0x21
+		
+		/** Descriptor header type value, to indicate a HID class HID report descriptor. */
+		#define DTYPE_Report       0x22
+
+	/* Type Defines: */
+		/** Type define for the HID class specific HID descriptor, to describe the HID device's specifications. Refer to the HID
+		 *  specification for details on the structure elements.
+		 */
+		typedef struct
+		{
+			USB_Descriptor_Header_t               Header;
+				
+			uint16_t                              HIDSpec;
+			uint8_t                               CountryCode;
+		
+			uint8_t                               TotalReportDescriptors;
+
+			uint8_t                               HIDReportType;
+			uint16_t                              HIDReportLength;
+		} USB_Descriptor_HID_t;
+
+		/** Type define for the data type used to store HID report descriptor elements. */
+		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+
+		/** Class state structure. An instance of this structure should be made for each HID interface
+		 *  within the user application, and passed to each of the HID class driver functions as the
+		 *  HIDInterfaceInfo parameter. The contents of this structure should be set to their correct
+		 *  values when used, or ommitted to force the library to use default values.
+		 */
+		typedef struct
+		{
+			uint8_t  InterfaceNumber; /**< Interface number of the HID interface within the device */
+
+			uint8_t  ReportINEndpointNumber; /**< Endpoint number of the HID interface's IN report endpoint */
+			uint16_t ReportINEndpointSize; /**< Size in bytes of the HID interface's IN report endpoint */
+
+			uint8_t  ReportOUTEndpointNumber; /**< Endpoint number of the HID interface's OUT report endpoint, if used */
+			uint16_t ReportOUTEndpointSize;  /**< Size in bytes of the HID interface's OUT report endpoint, if used */
+			
+			uint8_t  ReportBufferSize;
+
+			bool     UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode */
+			uint16_t IdleCount; /**< Report idle period, in ms, set by the host */
+			uint16_t IdleMSRemaining; /**< Total number of ms remaining before the idle period elapses */
+		} USB_ClassInfo_HID_t;
+
+	/* Function Prototypes: */
+		bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+		void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+		void USB_HID_RegisterStartOfFrame(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+		void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo);
+		
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize);
+
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.c b/LUFA/Drivers/USB/Class/Device/MassStorage.c
new file mode 100644
index 000000000..1c41f6046
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.c
@@ -0,0 +1,208 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#define  INCLUDE_FROM_MS_CLASS_C
+#include "MassStorage.h"
+
+static USB_ClassInfo_MS_t* CallbackMSInterfaceInfo;
+
+void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+	if (!(Endpoint_IsSETUPReceived()))
+	  return;
+	  
+	if (USB_ControlRequest.wIndex != MSInterfaceInfo->InterfaceNumber)
+	  return;
+
+	switch (USB_ControlRequest.bRequest)
+	{
+		case REQ_MassStorageReset:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				MSInterfaceInfo->IsMassStoreReset = true;			
+
+				while (!(Endpoint_IsINReady()));
+				Endpoint_ClearIN();
+			}
+
+			break;
+		case REQ_GetMaxLUN:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				Endpoint_Write_Byte(MSInterfaceInfo->TotalLUNs - 1);
+				
+				Endpoint_ClearIN();
+				
+				while (!(Endpoint_IsOUTReceived()));
+				Endpoint_ClearOUT();
+			}
+			
+			break;
+	}
+}
+
+bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+	if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+							         ENDPOINT_DIR_IN, MSInterfaceInfo->DataINEndpointSize,
+							         ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	if (!(Endpoint_ConfigureEndpoint(MSInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+	                                 ENDPOINT_DIR_OUT, MSInterfaceInfo->DataOUTEndpointSize,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	return true;
+}
+
+void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+	if (!(USB_IsConnected))
+	  return;
+
+	Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+		
+	if (Endpoint_IsReadWriteAllowed())
+	{
+		if (USB_MS_ReadInCommandBlock(MSInterfaceInfo))
+		{
+			if (MSInterfaceInfo->CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
+			  Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+			  
+			MSInterfaceInfo->CommandStatus.Status              = CALLBACK_USB_MS_SCSICommandReceived(MSInterfaceInfo) ?
+			                                                      Command_Pass : Command_Fail;
+			MSInterfaceInfo->CommandStatus.Signature           = CSW_SIGNATURE;
+			MSInterfaceInfo->CommandStatus.Tag                 = MSInterfaceInfo->CommandBlock.Tag;
+			MSInterfaceInfo->CommandStatus.DataTransferResidue = MSInterfaceInfo->CommandBlock.DataTransferLength;
+
+			if ((MSInterfaceInfo->CommandStatus.Status == Command_Fail) && (MSInterfaceInfo->CommandStatus.DataTransferResidue))
+			  Endpoint_StallTransaction();
+			
+			USB_MS_ReturnCommandStatus(MSInterfaceInfo);
+			
+			if (MSInterfaceInfo->IsMassStoreReset)
+			{
+				Endpoint_ResetFIFO(MSInterfaceInfo->DataOUTEndpointNumber);
+				Endpoint_ResetFIFO(MSInterfaceInfo->DataINEndpointNumber);
+				
+				Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+				Endpoint_ClearStall();
+				Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+				Endpoint_ClearStall();
+
+				MSInterfaceInfo->IsMassStoreReset = false;
+			}
+		}
+	}
+}
+
+static bool USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+	CallbackMSInterfaceInfo = MSInterfaceInfo;
+	Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock,
+	                        (sizeof(CommandBlockWrapper_t) - MAX_SCSI_COMMAND_LENGTH),
+	                        StreamCallback_AbortOnMassStoreReset);
+
+	if ((MSInterfaceInfo->CommandBlock.Signature         != CBW_SIGNATURE)              ||
+	    (MSInterfaceInfo->CommandBlock.LUN               >= MSInterfaceInfo->TotalLUNs) ||
+		(MSInterfaceInfo->CommandBlock.SCSICommandLength >  MAX_SCSI_COMMAND_LENGTH))
+	{
+		Endpoint_StallTransaction();
+		Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+		Endpoint_StallTransaction();
+		
+		return false;
+	}
+
+	CallbackMSInterfaceInfo = MSInterfaceInfo;
+	Endpoint_Read_Stream_LE(&MSInterfaceInfo->CommandBlock.SCSICommandData,
+	                        MSInterfaceInfo->CommandBlock.SCSICommandLength,
+	                        StreamCallback_AbortOnMassStoreReset);
+							
+	Endpoint_ClearOUT();
+	  
+	if (MSInterfaceInfo->IsMassStoreReset)
+	  return false;
+
+	return true;
+}
+
+static void USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo)
+{
+	Endpoint_SelectEndpoint(MSInterfaceInfo->DataOUTEndpointNumber);
+
+	while (Endpoint_IsStalled())
+	{
+		USB_USBTask();
+
+		if (MSInterfaceInfo->IsMassStoreReset)
+		  return;
+	}
+
+	Endpoint_SelectEndpoint(MSInterfaceInfo->DataINEndpointNumber);
+
+	while (Endpoint_IsStalled())
+	{
+		USB_USBTask();
+
+		if (MSInterfaceInfo->IsMassStoreReset)
+		  return;
+	}
+	
+	CallbackMSInterfaceInfo = MSInterfaceInfo;
+	Endpoint_Write_Stream_LE(&MSInterfaceInfo->CommandStatus, sizeof(CommandStatusWrapper_t),
+	                         StreamCallback_AbortOnMassStoreReset);
+	
+	Endpoint_ClearIN();
+
+	if (MSInterfaceInfo->IsMassStoreReset)
+	  return;
+}
+
+static uint8_t StreamCallback_AbortOnMassStoreReset(void)
+{
+	USB_MS_USBTask(CallbackMSInterfaceInfo);
+
+	if (CallbackMSInterfaceInfo->IsMassStoreReset)
+	  return STREAMCALLBACK_Abort;
+	else
+	  return STREAMCALLBACK_Continue;
+}
diff --git a/LUFA/Drivers/USB/Class/Device/MassStorage.h b/LUFA/Drivers/USB/Class/Device/MassStorage.h
new file mode 100644
index 000000000..c1874b218
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/MassStorage.h
@@ -0,0 +1,127 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#ifndef _MS_CLASS_H_
+#define _MS_CLASS_H_
+
+	/* Includes: */
+		#include "../../USB.h"
+
+		#include <string.h>
+
+	/* Macros: */
+		/** Mass Storage Class specific request to reset the Mass Storage interface, ready for the next command. */
+		#define REQ_MassStorageReset       0xFF
+
+		/** Mass Storage Class specific request to retrieve the total number of Logical Units (drives) in the SCSI device. */
+		#define REQ_GetMaxLUN              0xFE
+
+		/** Maximum length of a SCSI command which can be issued by the device or host in a Mass Storage bulk wrapper. */
+		#define MAX_SCSI_COMMAND_LENGTH    16
+		
+		/** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+		#define CBW_SIGNATURE              0x43425355UL
+
+		/** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */
+		#define CSW_SIGNATURE              0x53425355UL
+		
+		/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
+		#define COMMAND_DIRECTION_DATA_OUT (0 << 7)
+
+		/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
+		#define COMMAND_DIRECTION_DATA_IN  (1 << 7)
+
+	/* Type defines: */
+		/** Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
+		typedef struct
+		{
+			uint32_t Signature; /**< Command block signature, must be CBW_SIGNATURE to indicate a valid Command Block */
+			uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
+			uint32_t DataTransferLength; /** Length of the optional data portion of the issued command, in bytes */
+			uint8_t  Flags; /**< Command block flags, indicating command data direction */
+			uint8_t  LUN; /**< Logical Unit number this command is issued to */
+			uint8_t  SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array */
+			uint8_t  SCSICommandData[MAX_SCSI_COMMAND_LENGTH]; /**< Issued SCSI command in the Command Block */
+		} CommandBlockWrapper_t;
+		
+		/** Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. */
+		typedef struct
+		{
+			uint32_t Signature; /**< Status block signature, must be CSW_SIGNATURE to indicate a valid Command Status */
+			uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper */
+			uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command */
+			uint8_t  Status; /**< Status code of the issued command - a value from the MassStorage_CommandStatusCodes_t enum */
+		} CommandStatusWrapper_t;
+		
+	/* Enums: */
+		/** Enum for the possible command status wrapper return status codes. */
+		enum MassStorage_CommandStatusCodes_t
+		{
+			Command_Pass = 0, /**< Command completed with no error */
+			Command_Fail = 1, /**< Command failed to complete - host may check the exact error via a SCSI REQUEST SENSE command */
+			Phase_Error  = 2  /**< Command failed due to being invalid in the current phase */
+		};
+		
+	/* Type Defines: */
+		/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
+		 *  as set by the host via a class specific request.
+		 */
+		typedef struct
+		{
+			uint8_t  InterfaceNumber; /**< Interface number of the Mass Storage interface within the device */
+
+			uint8_t  DataINEndpointNumber; /**< Endpoint number of the Mass Storage interface's IN data endpoint */
+			uint16_t DataINEndpointSize; /**< Size in bytes of the Mass Storage interface's IN data endpoint */
+
+			uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the Mass Storage interface's OUT data endpoint */
+			uint16_t DataOUTEndpointSize;  /**< Size in bytes of the Mass Storage interface's OUT data endpoint */
+
+			uint8_t  TotalLUNs;
+
+			CommandBlockWrapper_t  CommandBlock;
+			CommandStatusWrapper_t CommandStatus;
+
+			bool IsMassStoreReset;
+		} USB_ClassInfo_MS_t;
+		
+	/* Function Prototypes: */
+		#if defined(INCLUDE_FROM_MS_CLASS_C)
+			static void    USB_MS_ReturnCommandStatus(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static bool    USB_MS_ReadInCommandBlock(USB_ClassInfo_MS_t* MSInterfaceInfo);
+			static uint8_t StreamCallback_AbortOnMassStoreReset(void);
+		#endif
+	
+		void USB_MS_USBTask(USB_ClassInfo_MS_t* MSInterfaceInfo);
+		bool USB_MS_ConfigureEndpoints(USB_ClassInfo_MS_t* MSInterfaceInfo);
+		void USB_MS_ProcessControlPacket(USB_ClassInfo_MS_t* MSInterfaceInfo);
+		
+		bool CALLBACK_USB_MS_SCSICommandReceived(USB_ClassInfo_MS_t* MSInterfaceInfo);
+		
+#endif
diff --git a/LUFA/Drivers/USB/Class/Device/RNDIS.c b/LUFA/Drivers/USB/Class/Device/RNDIS.c
new file mode 100644
index 000000000..49c7df01d
--- /dev/null
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.c
@@ -0,0 +1,456 @@
+/*
+             LUFA Library
+     Copyright (C) Dean Camera, 2009.
+              
+  dean [at] fourwalledcubicle [dot] com
+      www.fourwalledcubicle.com
+*/
+
+/*
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, provided that the above copyright notice appear in all
+  copies and that both that the copyright notice and this
+  permission notice and warranty disclaimer appear in supporting
+  documentation, and that the name of the author not be used in
+  advertising or publicity pertaining to distribution of the
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+#define  INCLUDE_FROM_RNDIS_CLASS_C
+#include "RNDIS.h"
+
+static const uint32_t PROGMEM AdapterSupportedOIDList[]  =
+	{
+		OID_GEN_SUPPORTED_LIST,
+		OID_GEN_PHYSICAL_MEDIUM,
+		OID_GEN_HARDWARE_STATUS,
+		OID_GEN_MEDIA_SUPPORTED,
+		OID_GEN_MEDIA_IN_USE,
+		OID_GEN_MAXIMUM_FRAME_SIZE,
+		OID_GEN_MAXIMUM_TOTAL_SIZE,
+		OID_GEN_LINK_SPEED,
+		OID_GEN_TRANSMIT_BLOCK_SIZE,
+		OID_GEN_RECEIVE_BLOCK_SIZE,
+		OID_GEN_VENDOR_ID,
+		OID_GEN_VENDOR_DESCRIPTION,
+		OID_GEN_CURRENT_PACKET_FILTER,
+		OID_GEN_MAXIMUM_TOTAL_SIZE,
+		OID_GEN_MEDIA_CONNECT_STATUS,
+		OID_GEN_XMIT_OK,
+		OID_GEN_RCV_OK,
+		OID_GEN_XMIT_ERROR,
+		OID_GEN_RCV_ERROR,
+		OID_GEN_RCV_NO_BUFFER,
+		OID_802_3_PERMANENT_ADDRESS,
+		OID_802_3_CURRENT_ADDRESS,
+		OID_802_3_MULTICAST_LIST,
+		OID_802_3_MAXIMUM_LIST_SIZE,
+		OID_802_3_RCV_ERROR_ALIGNMENT,
+		OID_802_3_XMIT_ONE_COLLISION,
+		OID_802_3_XMIT_MORE_COLLISIONS,
+	};
+
+void USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+	if (!(Endpoint_IsSETUPReceived()))
+	  return;
+	  
+	if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->ControlInterfaceNumber)
+	  return;
+
+	switch (USB_ControlRequest.bRequest)
+	{
+		case REQ_SendEncapsulatedCommand:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, USB_ControlRequest.wLength);
+				Endpoint_ClearIN();
+
+				USB_RNDIS_ProcessRNDISControlMessage(RNDISInterfaceInfo);
+			}
+			
+			break;
+		case REQ_GetEncapsulatedResponse:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
+			{
+				Endpoint_ClearSETUP();
+
+				RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+				if (!(MessageHeader->MessageLength))
+				{
+					RNDISInterfaceInfo->RNDISMessageBuffer[0] = 0;
+					MessageHeader->MessageLength = 1;
+				}
+
+				Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->RNDISMessageBuffer, MessageHeader->MessageLength);				
+				Endpoint_ClearOUT();
+
+				MessageHeader->MessageLength = 0;
+			}
+	
+			break;
+	}
+}
+
+bool USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+	if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataINEndpointNumber, EP_TYPE_BULK,
+							         ENDPOINT_DIR_IN, RNDISInterfaceInfo->DataINEndpointSize,
+							         ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber, EP_TYPE_BULK,
+	                                 ENDPOINT_DIR_OUT, RNDISInterfaceInfo->DataOUTEndpointSize,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	if (!(Endpoint_ConfigureEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber, EP_TYPE_INTERRUPT,
+	                                 ENDPOINT_DIR_IN, RNDISInterfaceInfo->NotificationEndpointSize,
+	                                 ENDPOINT_BANK_SINGLE)))
+	{
+		return false;
+	}
+
+	return true;
+}
+
+void USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+	if (!(USB_IsConnected))
+	  return;
+
+	RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+	Endpoint_SelectEndpoint(RNDISInterfaceInfo->NotificationEndpointNumber);
+
+	if (Endpoint_IsINReady() && RNDISInterfaceInfo->ResponseReady)
+	{
+		USB_Request_Header_t Notification = (USB_Request_Header_t)
+			{
+				.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
+				.bRequest      = NOTIF_ResponseAvailable,
+				.wValue        = 0,
+				.wIndex        = 0,
+				.wLength       = 0,
+			};
+		
+		Endpoint_Write_Stream_LE(&Notification, sizeof(Notification), NO_STREAM_CALLBACK);
+
+		Endpoint_ClearIN();
+
+		RNDISInterfaceInfo->ResponseReady = false;
+	}
+	
+	if ((RNDISInterfaceInfo->CurrRNDISState == RNDIS_Data_Initialized) && !(MessageHeader->MessageLength))
+	{
+		RNDIS_PACKET_MSG_t RNDISPacketHeader;
+
+		Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataOUTEndpointNumber);
+
+		if (Endpoint_IsOUTReceived() && !(RNDISInterfaceInfo->FrameIN.FrameInBuffer))
+		{
+			Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+
+			if (RNDISPacketHeader.DataLength > ETHERNET_FRAME_SIZE_MAX)
+			{
+				Endpoint_StallTransaction();
+				return;
+			}
+			
+			Endpoint_Read_Stream_LE(RNDISInterfaceInfo->FrameIN.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+
+			Endpoint_ClearOUT();
+			
+			RNDISInterfaceInfo->FrameIN.FrameLength = RNDISPacketHeader.DataLength;
+
+			RNDISInterfaceInfo->FrameIN.FrameInBuffer = true;
+		}
+		
+		Endpoint_SelectEndpoint(RNDISInterfaceInfo->DataINEndpointNumber);
+		
+		if (Endpoint_IsINReady() && RNDISInterfaceInfo->FrameOUT.FrameInBuffer)
+		{
+			memset(&RNDISPacketHeader, 0, sizeof(RNDIS_PACKET_MSG_t));
+
+			RNDISPacketHeader.MessageType   = REMOTE_NDIS_PACKET_MSG;
+			RNDISPacketHeader.MessageLength = (sizeof(RNDIS_PACKET_MSG_t) + RNDISInterfaceInfo->FrameOUT.FrameLength);
+			RNDISPacketHeader.DataOffset    = (sizeof(RNDIS_PACKET_MSG_t) - sizeof(RNDIS_Message_Header_t));
+			RNDISPacketHeader.DataLength    = RNDISInterfaceInfo->FrameOUT.FrameLength;
+
+			Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_PACKET_MSG_t), NO_STREAM_CALLBACK);
+			Endpoint_Write_Stream_LE(RNDISInterfaceInfo->FrameOUT.FrameData, RNDISPacketHeader.DataLength, NO_STREAM_CALLBACK);
+			Endpoint_ClearIN();
+			
+			RNDISInterfaceInfo->FrameOUT.FrameInBuffer = false;
+		}
+	}
+}							
+
+void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo)
+{
+	/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
+	         this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
+
+	RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+	switch (MessageHeader->MessageType)
+	{
+		case REMOTE_NDIS_INITIALIZE_MSG:
+			RNDISInterfaceInfo->ResponseReady = true;
+			
+			RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			
+			INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;
+			INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);
+			INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;
+			INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;
+			
+			INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;
+			INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;			
+			INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;
+			INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;
+			INITIALIZE_Response->MaxPacketsPerTransfer = 1;
+			INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);
+			INITIALIZE_Response->PacketAlignmentFactor = 0;
+			INITIALIZE_Response->AFListOffset          = 0;
+			INITIALIZE_Response->AFListSize            = 0;
+			
+			RNDISInterfaceInfo->CurrRNDISState = RNDIS_Initialized;
+		
+			break;
+		case REMOTE_NDIS_HALT_MSG:
+			RNDISInterfaceInfo->ResponseReady = false;
+			MessageHeader->MessageLength = 0;
+
+			RNDISInterfaceInfo->CurrRNDISState = RNDIS_Uninitialized;
+
+			break;
+		case REMOTE_NDIS_QUERY_MSG:
+			RNDISInterfaceInfo->ResponseReady = true;
+						
+			RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			uint32_t             Query_Oid      = QUERY_Message->Oid;
+						
+			void*     QueryData                 = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+			                                                                              QUERY_Message->InformationBufferOffset];
+			void*     ResponseData              = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];		
+			uint16_t  ResponseSize;
+
+			QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;
+			QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);
+						
+			if (USB_RNDIS_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, QUERY_Message->InformationBufferLength,
+			                               ResponseData, &ResponseSize))
+			{
+				QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;
+				QUERY_Response->MessageLength          += ResponseSize;
+							
+				QUERY_Response->InformationBufferLength = ResponseSize;
+				QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));
+			}
+			else
+			{				
+				QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+				QUERY_Response->InformationBufferLength = 0;
+				QUERY_Response->InformationBufferOffset = 0;
+			}
+			
+			break;
+		case REMOTE_NDIS_SET_MSG:
+			RNDISInterfaceInfo->ResponseReady = true;
+			
+			RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			uint32_t           SET_Oid      = SET_Message->Oid;
+
+			SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;
+			SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);
+			SET_Response->RequestId         = SET_Message->RequestId;
+
+			void* SetData                   = &RNDISInterfaceInfo->RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
+			                                                                          SET_Message->InformationBufferOffset];
+						
+			if (USB_RNDIS_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, SET_Message->InformationBufferLength))
+			  SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;
+			else
+			  SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
+
+			break;
+		case REMOTE_NDIS_RESET_MSG:
+			RNDISInterfaceInfo->ResponseReady = true;
+			
+			RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+			RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;
+			RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);
+			RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;
+			RESET_Response->AddressingReset     = 0;
+
+			break;
+		case REMOTE_NDIS_KEEPALIVE_MSG:
+			RNDISInterfaceInfo->ResponseReady = true;
+			
+			RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+			RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISInterfaceInfo->RNDISMessageBuffer;
+
+			KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;
+			KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
+			KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;
+			KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;
+			
+			break;
+	}
+}
+
+static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo,
+                                       uint32_t OId, void* QueryData, uint16_t QuerySize,
+                                       void* ResponseData, uint16_t* ResponseSize)
+{
+	switch (OId)
+	{
+		case OID_GEN_SUPPORTED_LIST:
+			*ResponseSize = sizeof(AdapterSupportedOIDList);
+			
+			memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
+			
+			return true;
+		case OID_GEN_PHYSICAL_MEDIUM:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Indicate that the device is a true ethernet link */
+			*((uint32_t*)ResponseData) = 0;
+			
+			return true;
+		case OID_GEN_HARDWARE_STATUS:
+			*ResponseSize = sizeof(uint32_t);
+			
+			*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
+			
+			return true;
+		case OID_GEN_MEDIA_SUPPORTED:
+		case OID_GEN_MEDIA_IN_USE:
+			*ResponseSize = sizeof(uint32_t);
+			
+			*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
+			
+			return true;
+		case OID_GEN_VENDOR_ID:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
+			*((uint32_t*)ResponseData) = 0x00FFFFFF;
+			
+			return true;
+		case OID_GEN_MAXIMUM_FRAME_SIZE:
+		case OID_GEN_TRANSMIT_BLOCK_SIZE:
+		case OID_GEN_RECEIVE_BLOCK_SIZE:
+			*ResponseSize = sizeof(uint32_t);
+			
+			*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
+			
+			return true;
+		case OID_GEN_VENDOR_DESCRIPTION:
+			*ResponseSize = (strlen(RNDISInterfaceInfo->AdapterVendorDescription) + 1);
+			
+			memcpy(ResponseData, RNDISInterfaceInfo->AdapterVendorDescription, *ResponseSize);
+			
+			return true;
+		case OID_GEN_MEDIA_CONNECT_STATUS:
+			*ResponseSize = sizeof(uint32_t);
+			
+			*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
+			
+			return true;
+		case OID_GEN_LINK_SPEED:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Indicate 10Mb/s link speed */
+			*((uint32_t*)ResponseData) = 100000;
+
+			return true;
+		case OID_802_3_PERMANENT_ADDRESS:
+		case OID_802_3_CURRENT_ADDRESS:
+			*ResponseSize = sizeof(MAC_Address_t);
+			
+			memcpy(ResponseData, &RNDISInterfaceInfo->AdapterMACAddress, sizeof(MAC_Address_t));
+
+			return true;
+		case OID_802_3_MAXIMUM_LIST_SIZE:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Indicate only one multicast address supported */
+			*((uint32_t*)ResponseData) = 1;
+		
+			return true;
+		case OID_GEN_CURRENT_PACKET_FILTER:
+			*ResponseSize = sizeof(uint32_t);
+			
+			*((uint32_t*)ResponseData) = RNDISInterfaceInfo->CurrPacketFilter;
+		
+			return true;			
+		case OID_GEN_XMIT_OK:
+		case OID_GEN_RCV_OK:
+		case OID_GEN_XMIT_ERROR:
+		case OID_GEN_RCV_ERROR:
+		case OID_GEN_RCV_NO_BUFFER:
+		case OID_802_3_RCV_ERROR_ALIGNMENT:
+		case OID_802_3_XMIT_ONE_COLLISION:
+		case OID_802_3_XMIT_MORE_COLLISIONS:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Unused statistic OIDs - always return 0 for each */
+			*((uint32_t*)ResponseData) = 0;
+		
+			return true;
+		case OID_GEN_MAXIMUM_TOTAL_SIZE:
+			*ResponseSize = sizeof(uint32_t);
+			
+			/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
+			*((uint32_t*)ResponseData) = (RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
+		
+			return true;
+		default:
+			return false;
+	}
+}
+
+static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId, void* SetData, uint16_t SetSize)
+{
+	switch (OId)
+	{
+		case OID_GEN_CURRENT_PACKET_FILTER:
+			RNDISInterfaceInfo->CurrPacketFilter = *((uint32_t*)SetData);
+			RNDISInterfaceInfo->CurrRNDISState = ((RNDISInterfaceInfo->CurrPacketFilter) ?
+			                                      RNDIS_Data_Initialized : RNDIS_Data_Initialized);
+			
+			return true;
+		case OID_802_3_MULTICAST_LIST:
+			/* Do nothing - throw away the value from the host as it is unused */
+		
+			return true;
+		default:
+			return false;
+	}
+}
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.h b/LUFA/Drivers/USB/Class/Device/RNDIS.h
similarity index 65%
rename from Demos/Device/RNDISEthernet/Lib/RNDIS.h
rename to LUFA/Drivers/USB/Class/Device/RNDIS.h
index 88c9a9eb9..73622a4dc 100644
--- a/Demos/Device/RNDISEthernet/Lib/RNDIS.h
+++ b/LUFA/Drivers/USB/Class/Device/RNDIS.h
@@ -28,26 +28,16 @@
   this software.
 */
 
-/** \file
- *
- *  Header file for RNDIS.c.
- */
-
-#ifndef _RNDIS_H_
-#define _RNDIS_H_
+#ifndef _RNDIS_CLASS_H_
+#define _RNDIS_CLASS_H_
 
 	/* Includes: */
-		#include <avr/io.h>
-		#include <stdbool.h>
-		
-		#include "RNDISEthernet.h"
+		#include <string.h>
+	
+		#include "../../USB.h"
 		#include "RNDISConstants.h"
-		#include "Ethernet.h"
-
+		
 	/* Macros: */
-		/** Physical MAC Address of the USB network adapter */
-		#define ADAPTER_MAC_ADDRESS                   {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}
-	
 		/** Implemented RNDIS Version Major */
 		#define REMOTE_NDIS_VERSION_MAJOR             0x01
 
@@ -60,6 +50,12 @@
 		/** RNDIS request to issue a device-to-host NDIS response */
 		#define REQ_GetEncapsulatedResponse           0x01
 		
+		#define RNDIS_MESSAGE_BUFFER_SIZE             128
+
+		#define ETHERNET_FRAME_SIZE_MAX               1500
+		
+		#define NOTIF_ResponseAvailable               1
+		
 	/* Enums: */
 		/** Enum for the possible NDIS adapter states. */
 		enum RNDIS_States_t
@@ -78,8 +74,14 @@
 			NdisHardwareStatusClosing, /**< Hardware currently closing */
 			NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */
 		};
-
+		
 	/* Type Defines: */
+		/** Type define for a physical MAC address of a device on a network */
+		typedef struct
+		{
+			uint8_t       Octets[6]; /**< Individual bytes of a MAC address */
+		} MAC_Address_t;
+
 		/** Type define for a RNDIS message header, sent before RNDIS messages */
 		typedef struct
 		{
@@ -87,6 +89,14 @@
 			uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */
 		} RNDIS_Message_Header_t;
 
+		/** Type define for an Ethernet frame buffer. */
+		typedef struct
+		{
+			uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */
+			uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */
+			bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */
+		} Ethernet_Frame_Info_t;
+
 		/** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */
 		typedef struct
 		{
@@ -102,7 +112,31 @@
 			uint32_t VcHandle;
 			uint32_t Reserved;
 		} RNDIS_PACKET_MSG_t;
-	
+
+		typedef struct
+		{
+			uint8_t  ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
+
+			uint8_t  DataINEndpointNumber; /**< Endpoint number of the CDC interface's IN data endpoint */
+			uint16_t DataINEndpointSize; /**< Size in bytes of the CDC interface's IN data endpoint */
+
+			uint8_t  DataOUTEndpointNumber; /**< Endpoint number of the CDC interface's OUT data endpoint */
+			uint16_t DataOUTEndpointSize;  /**< Size in bytes of the CDC interface's OUT data endpoint */
+
+			uint8_t  NotificationEndpointNumber; /**< Endpoint number of the CDC interface's IN notification endpoint, if used */
+			uint16_t NotificationEndpointSize;  /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
+			
+			char*         AdapterVendorDescription;
+			MAC_Address_t AdapterMACAddress;
+
+			uint8_t  RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE];
+			bool     ResponseReady;
+			uint8_t  CurrRNDISState;
+			uint32_t CurrPacketFilter;
+			Ethernet_Frame_Info_t FrameIN;
+			Ethernet_Frame_Info_t FrameOUT;
+		} USB_ClassInfo_RNDIS_t;
+		
 		/** Type define for a RNDIS Initialize command message */
 		typedef struct
 		{
@@ -208,19 +242,19 @@
 			uint32_t InformationBufferOffset;
 		} RNDIS_QUERY_CMPLT_t;
 		
-	/* External Variables: */
-		extern uint8_t                 RNDISMessageBuffer[];
-		extern RNDIS_Message_Header_t* MessageHeader;
-		extern bool                    ResponseReady;
-		extern uint8_t                 CurrRNDISState;
-
 	/* Function Prototypes: */
-		void ProcessRNDISControlMessage(void);
-
-		#if defined(INCLUDE_FROM_RNDIS_C)
-			static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
-										 void* ResponseData, uint16_t* ResponseSize);
-			static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);	
+		#if defined(INCLUDE_FROM_RNDIS_CLASS_C)
+			static void USB_RNDIS_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+			static bool USB_RNDIS_ProcessNDISQuery(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, 
+			                                       uint32_t OId, void* QueryData, uint16_t QuerySize,
+										           void* ResponseData, uint16_t* ResponseSize);
+			static bool USB_RNDIS_ProcessNDISSet(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo, uint32_t OId,
+			                                     void* SetData, uint16_t SetSize);	
 		#endif
+
+		void     USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+		bool     USB_RNDIS_ConfigureEndpoints(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+		void     USB_RNDIS_ProcessControlPacket(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
+		void     USB_RNDIS_USBTask(USB_ClassInfo_RNDIS_t* RNDISInterfaceInfo);
 		
 #endif
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h b/LUFA/Drivers/USB/Class/Device/RNDISConstants.h
similarity index 100%
rename from Demos/Device/RNDISEthernet/Lib/RNDISConstants.h
rename to LUFA/Drivers/USB/Class/Device/RNDISConstants.h
diff --git a/LUFA/Drivers/USB/Class/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
similarity index 100%
rename from LUFA/Drivers/USB/Class/HIDParser.c
rename to LUFA/Drivers/USB/Class/Host/HIDParser.c
diff --git a/LUFA/Drivers/USB/Class/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
similarity index 97%
rename from LUFA/Drivers/USB/Class/HIDParser.h
rename to LUFA/Drivers/USB/Class/Host/HIDParser.h
index 49e57c295..4acce2462 100644
--- a/LUFA/Drivers/USB/Class/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -63,7 +63,7 @@
 
 		#include "HIDReportData.h"
 
-		#include "../../../Common/Common.h"
+		#include "../../../../Common/Common.h"
 
 	/* Enable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/HIDReportData.h b/LUFA/Drivers/USB/Class/Host/HIDReportData.h
similarity index 100%
rename from LUFA/Drivers/USB/Class/HIDReportData.h
rename to LUFA/Drivers/USB/Class/Host/HIDReportData.h
diff --git a/LUFA/Drivers/USB/HighLevel/Events.h b/LUFA/Drivers/USB/HighLevel/Events.h
index e6d2beaa7..ded027b12 100644
--- a/LUFA/Drivers/USB/HighLevel/Events.h
+++ b/LUFA/Drivers/USB/HighLevel/Events.h
@@ -267,6 +267,11 @@
 			 *        \ref Group_USBManagement documentation).
 			 */
 			void EVENT_USB_Reset(void);
+			
+			/** Event for the USB start of frame interrupt, firing once each millisecond in either device or host
+			 *  mode, while USB frames are being generated or recieved.
+			 */
+			void EVENT_USB_StartOfFrame(void);
 		#endif
 		
 	/* Private Interface - For use in library only: */
@@ -303,6 +308,7 @@
 				void EVENT_USB_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
 				void EVENT_USB_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
 				void EVENT_USB_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
+				void EVENT_USB_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub);
 			#endif
 	#endif
 
diff --git a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
index 0b9d08223..0ccbe6155 100644
--- a/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
+++ b/LUFA/Drivers/USB/HighLevel/USBInterrupt.c
@@ -180,6 +180,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 
 		EVENT_USB_Reset();
 	}
+	
+	if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI))
+	{
+		USB_INT_Clear(USB_INT_SOFI);
+
+		FrameElapsed = true;
+		
+		EVENT_USB_StartOfFrame();
+	}
 	#endif
 	
 	#if defined(USB_CAN_BE_HOST)
@@ -232,6 +241,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
 
 		USB_ResetInterface();
 	}
+
+	if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI))
+	{
+		USB_INT_Clear(USB_INT_HSOFI);
+
+		FrameElapsed = true;
+		
+		EVENT_USB_StartOfFrame();
+	}
 	#endif
 
 	#if defined(USB_CAN_BE_BOTH)
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.c b/LUFA/Drivers/USB/HighLevel/USBTask.c
index e2b7e91d5..46fcd5709 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.c
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.c
@@ -42,7 +42,7 @@ USB_Request_Header_t USB_ControlRequest;
 volatile uint8_t   USB_HostState;
 #endif
 
-TASK(USB_USBTask)
+void USB_USBTask(void)
 {
 	#if defined(USB_HOST_ONLY)
 		USB_HostTask();
diff --git a/LUFA/Drivers/USB/HighLevel/USBTask.h b/LUFA/Drivers/USB/HighLevel/USBTask.h
index 1e1209a5f..e4c8a02ae 100644
--- a/LUFA/Drivers/USB/HighLevel/USBTask.h
+++ b/LUFA/Drivers/USB/HighLevel/USBTask.h
@@ -38,7 +38,6 @@
 		#include <stdbool.h>
 		#include <stddef.h>
 		
-		#include "../../../Scheduler/Scheduler.h"
 		#include "../LowLevel/LowLevel.h"
 		#include "StdRequestType.h"
 		#include "USBMode.h"
@@ -122,11 +121,11 @@
 			extern volatile uint8_t USB_HostState;
 			#endif
 
-		/* Tasks: */
+		/* Function Prototypes: */
 			/** This is the main USB management task. The USB driver requires that this task be executed
 			 *  continuously when the USB system is active (device attached in host mode, or attached to a host
 			 *  in device mode) in order to manage USB communications. This task may be executed inside an RTOS,
-			 *  scheduler (e.g. the simple LUFA Scheduler), fast timer ISR or the main user application loop.
+			 *  fast timer ISR or the main user application loop.
 			 *
 			 *  The USB task must be serviced within 30ms while in device mode, or within 1ms while in host mode.
 			 *  The task may be serviced at all times, or (for minimum CPU consumption):
@@ -145,7 +144,7 @@
 			 *
 			 *  \ingroup Group_USBManagement
 			 */
-			TASK(USB_USBTask);
+			void USB_USBTask(void);
 
 	/* Private Interface - For use in library only: */
 	#if !defined(__DOXYGEN__)
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index 099022c1c..d02071bbd 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -80,8 +80,6 @@ uint8_t Endpoint_WaitUntilReady(void)
 	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
 	#endif
 
-	USB_INT_Clear(USB_INT_SOFI);
-
 	for (;;)
 	{
 		if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN)
@@ -100,9 +98,9 @@ uint8_t Endpoint_WaitUntilReady(void)
 		else if (Endpoint_IsStalled())
 		  return ENDPOINT_READYWAIT_EndpointStalled;
 			  
-		if (USB_INT_HasOccurred(USB_INT_SOFI))
+		if (FrameElapsed)
 		{
-			USB_INT_Clear(USB_INT_SOFI);
+			FrameElapsed = false;
 
 			if (!(TimeoutMSRem--))
 			  return ENDPOINT_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/LowLevel/Host.c b/LUFA/Drivers/USB/LowLevel/Host.c
index b606515e6..02a1c2171 100644
--- a/LUFA/Drivers/USB/LowLevel/Host.c
+++ b/LUFA/Drivers/USB/LowLevel/Host.c
@@ -210,14 +210,13 @@ uint8_t USB_Host_WaitMS(uint8_t MS)
 	bool    BusSuspended = USB_Host_IsBusSuspended();
 	uint8_t ErrorCode    = HOST_WAITERROR_Successful;
 	
-	USB_INT_Clear(USB_INT_HSOFI);
 	USB_Host_ResumeBus();
 
 	while (MS)
 	{
-		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		if (FrameElapsed)
 		{
-			USB_INT_Clear(USB_INT_HSOFI);
+			FrameElapsed = false;
 			MS--;
 		}
 					
@@ -260,9 +259,10 @@ static void USB_Host_ResetDevice(void)
 	USB_Host_ResetBus();
 	while (!(USB_Host_IsBusResetComplete()));
 
-	USB_INT_Clear(USB_INT_HSOFI);
 	USB_Host_ResumeBus();	
 	
+	FrameElapsed = false;
+
 	for (uint8_t MSRem = 10; MSRem != 0; MSRem--)
 	{
 		/* Workaround for powerless-pull-up devices. After a USB bus reset,
@@ -270,8 +270,10 @@ static void USB_Host_ResetDevice(void)
 		   looked for - if it is found within 10ms, the device is still
 		   present.                                                        */
 
-		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		if (FrameElapsed)
 		{
+			FrameElapsed = false;
+			
 			USB_INT_Clear(USB_INT_DDISCI);
 			break;
 		}
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.c b/LUFA/Drivers/USB/LowLevel/LowLevel.c
index 8b395be98..255a6ef29 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.c
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.c
@@ -38,6 +38,8 @@ volatile uint8_t USB_CurrentMode = USB_MODE_NONE;
 volatile uint8_t USB_Options;
 #endif
 
+volatile bool FrameElapsed;
+
 void USB_Init(
                #if defined(USB_CAN_BE_BOTH)
                const uint8_t Mode
@@ -150,6 +152,8 @@ void USB_ResetInterface(void)
 	USB_INT_DisableAllInterrupts();
 	USB_INT_ClearAllInterrupts();
 
+	FrameElapsed = false;
+
 	USB_IsConnected = false;
 
 	#if defined(USB_CAN_BE_HOST)
@@ -224,6 +228,7 @@ void USB_ResetInterface(void)
 	#if defined(USB_DEVICE_ONLY)	
 	USB_INT_Enable(USB_INT_SUSPEND);
 	USB_INT_Enable(USB_INT_EORSTI);
+	USB_INT_Enable(USB_INT_SOFI);
 
 	#if defined(CONTROL_ONLY_DEVICE)
 	UENUM = ENDPOINT_CONTROLEP;
@@ -240,11 +245,13 @@ void USB_ResetInterface(void)
 	
 	USB_INT_Enable(USB_INT_SRPI);
 	USB_INT_Enable(USB_INT_BCERRI);
+	USB_INT_Enable(USB_INT_HSOFI);
 	#else
 	if (USB_CurrentMode == USB_MODE_DEVICE)
 	{
 		USB_INT_Enable(USB_INT_SUSPEND);
 		USB_INT_Enable(USB_INT_EORSTI);
+		USB_INT_Enable(USB_INT_SOFI);
 
 		#if defined(CONTROL_ONLY_DEVICE)
 		UENUM = ENDPOINT_CONTROLEP;
@@ -262,6 +269,7 @@ void USB_ResetInterface(void)
 		
 		USB_INT_Enable(USB_INT_SRPI);
 		USB_INT_Enable(USB_INT_BCERRI);
+		USB_INT_Enable(USB_INT_HSOFI);
 	}
 	#endif
 }
diff --git a/LUFA/Drivers/USB/LowLevel/LowLevel.h b/LUFA/Drivers/USB/LowLevel/LowLevel.h
index 41b0ff5f6..4279ca315 100644
--- a/LUFA/Drivers/USB/LowLevel/LowLevel.h
+++ b/LUFA/Drivers/USB/LowLevel/LowLevel.h
@@ -350,6 +350,9 @@
 				  return USB_MODE_HOST;
 			}
 			#endif
+		
+		/* External Variables: */
+			extern volatile bool FrameElapsed;
 			
 	#endif
 	
diff --git a/LUFA/Drivers/USB/LowLevel/Pipe.c b/LUFA/Drivers/USB/LowLevel/Pipe.c
index 71a33d62f..720da1772 100644
--- a/LUFA/Drivers/USB/LowLevel/Pipe.c
+++ b/LUFA/Drivers/USB/LowLevel/Pipe.c
@@ -76,8 +76,6 @@ uint8_t Pipe_WaitUntilReady(void)
 	uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
 	#endif
 
-	USB_INT_Clear(USB_INT_HSOFI);
-
 	for (;;)
 	{
 		if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
@@ -96,9 +94,9 @@ uint8_t Pipe_WaitUntilReady(void)
 		else if (!(USB_IsConnected))
 		  return PIPE_READYWAIT_DeviceDisconnected;
 			  
-		if (USB_INT_HasOccurred(USB_INT_HSOFI))
+		if (FrameElapsed)
 		{
-			USB_INT_Clear(USB_INT_HSOFI);
+			FrameElapsed = false;
 
 			if (!(TimeoutMSRem--))
 			  return PIPE_READYWAIT_Timeout;
diff --git a/LUFA/Drivers/USB/USB.h b/LUFA/Drivers/USB/USB.h
index 6d66c4d14..3c8f06237 100644
--- a/LUFA/Drivers/USB/USB.h
+++ b/LUFA/Drivers/USB/USB.h
@@ -49,7 +49,6 @@
  *    - LUFA/Drivers/USB/HighLevel/USBInterrupt.c
  *    - LUFA/Drivers/USB/HighLevel/USBTask.c
  *    - LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
- *    - LUFA/Drivers/USB/Class/HIDParser.c
  *
  *  \section Module Description
  *  Functions, macros, variables, enums and types related to the management of USB communications.
@@ -97,7 +96,6 @@
 		#endif
 		
 		#include "HighLevel/ConfigDescriptor.h"
-		#include "Class/HIDParser.h"
 		
 #endif
 
diff --git a/LUFA/MemoryAllocator/DynAlloc.c b/LUFA/MemoryAllocator/DynAlloc.c
deleted file mode 100644
index 4f1c82241..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2009.
-              
-  dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
-*/
-
-/*
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, provided that the above copyright notice appear in all
-  copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-#define  INCLUDE_FROM_DYNALLOC_C
-#include "DynAlloc.h"
-
-struct
-{
-	char    Mem_Heap[NUM_BLOCKS * BLOCK_SIZE];
-	void*   Mem_Handles[NUM_HANDLES];
-	uint8_t Mem_Block_Flags[(NUM_BLOCKS / 4) + ((NUM_BLOCKS % 4) ? 1 : 0)];
-	uint8_t FlagMaskLookupMask[4];
-	uint8_t FlagMaskLookupNum[4];
-} Mem_MemData = {.FlagMaskLookupMask = {(3 << 0), (3 << 2), (3 << 4), (3 << 6)},
-                 .FlagMaskLookupNum  = {      0,        2,        4,        6}};
-
-static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum)
-{
-	const Block_Number_t BlockIndex    = (BlockNum >> 2);
-	const uint8_t        FlagMask      = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
-	const uint8_t        FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
-	return ((Mem_MemData.Mem_Block_Flags[BlockIndex] & FlagMask) >> FlagMaskShift);
-}
-
-static void Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags)
-{
-	const Block_Number_t BlockIndex    = (BlockNum >> 2);
-	const uint8_t        FlagMask      = Mem_MemData.FlagMaskLookupMask[BlockNum & 0x03];
-	const uint8_t        FlagMaskShift = Mem_MemData.FlagMaskLookupNum[BlockNum & 0x03];
-
-	Mem_MemData.Mem_Block_Flags[BlockIndex] &= ~FlagMask;
-	Mem_MemData.Mem_Block_Flags[BlockIndex] |= (Flags << FlagMaskShift);
-}
-
-static inline void Mem_Defrag(void)
-{
-	Block_Number_t FreeStartBlock = 0;
-	char*          FreeStartPtr   = NULL;
-	char*          UsedStartPtr   = NULL;
-	Block_Number_t CurrBlock;
-	
-	for (CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
-	{
-		if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
-		{
-			FreeStartPtr   = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
-			FreeStartBlock = CurrBlock;
-			break;
-		}
-	}
-	
-	if (FreeStartPtr == NULL)
-	  return;
-
-	while (++CurrBlock < NUM_BLOCKS)
-	{
-		uint8_t CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
-	
-		if (CurrBlockFlags & BLOCK_USED_MASK)
-		{
-			UsedStartPtr = &Mem_MemData.Mem_Heap[CurrBlock * BLOCK_SIZE];
-		
-			for (Handle_Number_t HandleNum = 0; HandleNum < NUM_HANDLES; HandleNum++)
-			{
-				if (Mem_MemData.Mem_Handles[HandleNum] == UsedStartPtr)
-				{
-					Mem_MemData.Mem_Handles[HandleNum] = FreeStartPtr;
-					break;
-				}
-			}
-
-			memcpy(FreeStartPtr, UsedStartPtr, BLOCK_SIZE);
-			FreeStartPtr += BLOCK_SIZE;
-			  
-			Mem_SetBlockFlags(FreeStartBlock++, CurrBlockFlags);
-			Mem_SetBlockFlags(CurrBlock, 0);
-		}
-	}
-}
-
-static inline bool Mem_FindFreeBlocks(Block_Number_t* const RetStartPtr, const Block_Number_t Blocks)
-{
-	Block_Number_t FreeInCurrSec = 0;
-
-	for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
-	{
-		if (Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK)
-		  FreeInCurrSec = 0;
-		else
-		  FreeInCurrSec++;
-
-		if (FreeInCurrSec >= Blocks)
-		{
-			*RetStartPtr = CurrBlock;
-			return true;
-		}
-	}
-
-	return false;
-}
-
-Mem_Handle_t Mem_Alloc(const Alloc_Size_t Bytes)
-{
-	Block_Number_t ReqBlocks = (Bytes / BLOCK_SIZE);
-	Block_Number_t StartBlock;
-	
-	if (Bytes % BLOCK_SIZE)
-	  ReqBlocks++;
-	
-	if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
-	{
-		Mem_Defrag();
-		
-		if (!(Mem_FindFreeBlocks(&StartBlock, ReqBlocks)))
-		  return NULL;	
-	}
-
-	for (Block_Number_t UsedBlock = 0; UsedBlock < (ReqBlocks - 1); UsedBlock++)
-	  Mem_SetBlockFlags((StartBlock + UsedBlock), (BLOCK_USED_MASK | BLOCK_LINKED_MASK));
-
-	Mem_SetBlockFlags((StartBlock + (ReqBlocks - 1)), BLOCK_USED_MASK);
-	
-	for (Handle_Number_t AllocEntry = 0; AllocEntry < NUM_HANDLES; AllocEntry++)
-	{
-		Mem_Handle_t CurrHdl = (Mem_Handle_t)&Mem_MemData.Mem_Handles[AllocEntry];
-	
-		if (DEREF(CurrHdl, void*) == NULL)
-		{
-			DEREF(CurrHdl, void*) = &Mem_MemData.Mem_Heap[StartBlock * BLOCK_SIZE];
-			return CurrHdl;
-		}
-	}
-
-	return NULL;
-}
-
-Mem_Handle_t Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes)
-{
-	Mem_Free(CurrAllocHdl);
-	return Mem_Alloc(Bytes);
-}
-
-Mem_Handle_t Mem_Calloc(const Alloc_Size_t Bytes)
-{
-	Mem_Handle_t AllocHdl = Mem_Alloc(Bytes);
-	
-	if (AllocHdl != NULL)
-	  memset(DEREF(AllocHdl, void*), 0x00, Bytes);
-
-	return AllocHdl;
-}
-
-void Mem_Free(Mem_Handle_t CurrAllocHdl)
-{
-	char*          MemBlockPtr = DEREF(CurrAllocHdl, char*);
-	Block_Number_t CurrBlock   = ((uint16_t)(MemBlockPtr - Mem_MemData.Mem_Heap) / BLOCK_SIZE);
-	uint8_t        CurrBlockFlags;
-
-	if ((CurrAllocHdl == NULL) || (MemBlockPtr == NULL))
-	  return;
-
-	do
-	{
-		CurrBlockFlags = Mem_GetBlockFlags(CurrBlock);
-		Mem_SetBlockFlags(CurrBlock, 0);
-
-		CurrBlock++;
-	}
-	while (CurrBlockFlags & BLOCK_LINKED_MASK);
-	
-	DEREF(CurrAllocHdl, void*) = NULL;
-}
-
-Block_Number_t Mem_TotalFreeBlocks(void)
-{
-	Block_Number_t FreeBlocks = 0;
-	
-	for (Block_Number_t CurrBlock = 0; CurrBlock < NUM_BLOCKS; CurrBlock++)
-	{
-		if (!(Mem_GetBlockFlags(CurrBlock) & BLOCK_USED_MASK))
-		  FreeBlocks++;
-	}
-	
-	return FreeBlocks;
-}
-
-Handle_Number_t Mem_TotalFreeHandles(void)
-{
-	Handle_Number_t FreeHandles = 0;
-	
-	for (Handle_Number_t CurrHandle = 0; CurrHandle < NUM_HANDLES; CurrHandle++)
-	{
-		if (Mem_MemData.Mem_Handles[CurrHandle] == NULL)
-		  FreeHandles++;
-	}
-	
-	return FreeHandles;
-}
diff --git a/LUFA/MemoryAllocator/DynAlloc.h b/LUFA/MemoryAllocator/DynAlloc.h
deleted file mode 100644
index acbfbd18a..000000000
--- a/LUFA/MemoryAllocator/DynAlloc.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2009.
-              
-  dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
-*/
-
-/*
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, provided that the above copyright notice appear in all
-  copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/** \file
- *
- *  Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- *  the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- *  management memory overhead.
- */
-
-/** @defgroup Group_MemoryAllocator Dynamic Block Memory Allocator - LUFA/MemoryAllocator/DynAlloc.h
- *
- *  \section Sec_Dependencies Module Source Dependencies
- *  The following files must be built with any user project that uses this module:
- *    - LUFA/MemoryAllocator/DynAlloc.c
- *
- *  \section Module Description
- *  Dynamic, auto-defragmenting block memory allocator library. This library provides a convenient replacement for
- *  the standard avr-libc dynamic memory allocation routines. Memory is handed out in block chunks, to reduce the
- *  management memory overhead.
- *
- *  Unlike the normal memory allocation routines, this library gives out handles to memory which must be dereferenced
- *  at the exact time of use, rather than handing back direct memory pointers. By using library managed handles
- *  instead of pointers, allocated memory blocks can be shifted around as needed transparently to defragment the
- *  memory as more blocks are requested.
- *
- *  The memory heap is static, thus the total memory usage of the compiled application (as reported by the avr-size
- *  tool of the AVR-GCC toolchain) includes the dynamic memory heap.
- *
- *  The constants NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined in the project makefile (and passed to the
- *  preprocessor via the -D GCC switch) for this library to compile.
- *
- *  NUM_BLOCKS indicates the number of memory blocks in the memory psudoheap which can be chained together and handed
- *  to the application via a memory handle. NUM_HANDLES is the maximum number of memory handles (pointing to one or
- *  more chained memory blocks) which can be handed out simultaneously before requiring a handle (and its associated
- *  memory) to be freed. BLOCK_SIZE gives the number of bytes in each memory block. 
- *
- *  @{
- */
-
-#ifndef __DYN_ALLOC__
-#define __DYN_ALLOC__
-
-	/* Includes : */
-		#include <avr/io.h>
-		#include <stdbool.h>
-		#include <string.h>
-	
-	/* Preprocessor Checks: */
-		#if (!defined(NUM_BLOCKS) || !defined(BLOCK_SIZE) || !defined(NUM_HANDLES))
-			#error NUM_BLOCKS, BLOCK_SIZE and NUM_HANDLES must be defined before use via makefile.
-		#endif
-
-	/* Public Interface - May be used in end-application: */
-		/* Macros: */
-			/** Macro to dereference a given memory handle into the given type. The given type should be a pointer
-			 *  if the memory is to contain an array of items, or should be a standard type (such as a primitive or
-			 *  structure) if the memory is to hold a single item of a single type. */
-			#define DEREF(handle, type)       (*(type*)handle)
-			
-			/** Constant, giving the total heap size in bytes. */
-			#define ALLOCABLE_BYTES           (1UL * NUM_BLOCKS * BLOCK_SIZE)
-		
-		/* Type Defines: */
-			/** Memory handle type, used to store handles given by the library functions. */
-			typedef const void** Mem_Handle_t;
-			
-			#if (ALLOCABLE_BYTES > 0xFFFF) || defined(__DOXYGEN__)
-				/** Type define for the size (in bytes) for an allocation for passing to the library functions.
-				 *  The exact type width varies depending on the value of ALLOCABLE_BYTES to ensure that a single
-				 *  allocation can request the entire heap if needed.
-				 */
-				typedef uint32_t Alloc_Size_t;
-			#elif (ALLOCABLE_BYTES > 0xFF)
-				typedef uint16_t Alloc_Size_t;
-			#else			
-				typedef uint8_t  Alloc_Size_t;
-			#endif
-
-			#if (NUM_BLOCKS > 0xFFFF) || defined(__DOXYGEN__)
-				/** Type define for a block number in the heap. The exact type width varies depending on the
-				 *   value of NUM_BLOCKS to ensure that the type can store an index to any block in the block pool.
-				 */
-				typedef uint32_t Block_Number_t;
-			#elif (NUM_BLOCKS > 0xFF)
-				typedef uint16_t Block_Number_t;
-			#else
-				typedef uint8_t  Block_Number_t;
-			#endif
-
-			#if (NUM_HANDLES > 0xFFFF) || defined(__DOXYGEN__)
-				/** Type define for a handle number. The exact type width varies depending on the value of NUM_HANDLES
-				 *  to ensure that the type can store the index of any handle in the handle pool.
-				 */
-				typedef uint32_t Handle_Number_t;
-			#elif (NUM_HANDLES > 0xFF)
-				typedef uint16_t Handle_Number_t;
-			#else			
-				typedef uint8_t  Handle_Number_t;
-			#endif
-			
-		/* Function Prototypes: */
-			/** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
-			 *  returns a handle to the newly allocated memory.
-			 *
-			 *  \param Bytes  The number of bytes requested to be allocated from the heap
-			 *
-			 *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
-			 */
-			Mem_Handle_t    Mem_Alloc(const Alloc_Size_t Bytes);
-			
-			/** Allocates a given number of blocks from the heap (calculated from the requested number of bytes) and
-			 *  returns a handle to the newly allocated memory. Calloced memory is automatically cleared to all 0x00
-			 *  values at the time of allocation.
-			 *
-			 *  \param Bytes  The number of pre-cleared bytes requested to be allocated from the heap
-			 *
-			 *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
-			 */
-			Mem_Handle_t    Mem_Calloc(const Alloc_Size_t Bytes);
-
-			/** Deallocates a given memory handle, and attempts to allocates the given number of blocks from the heap
-			 *  (calculated from the requested number of bytes) immediately following the deallocation. The new memory
-			 *  may be located in the same area as the previous memory, but this is not guaranteed.
-			 *
-			 *  \param CurrAllocHdl  Handle to an already allocated section of memory in the heap to deallocate
-			 *  \param Bytes         The number of bytes requested to be allocated from the heap following the
-			 *                       deallocation
-			 *
-			 *  \return NULL handle if the allocation fails, or handle to the allocated memory if the allocation succeeds
-			 *
-			 *  \warning Even if the allocation fails, the deallocation will still occur. Care should be taken to ensure
-			 *           that the previously allocated memory is not used following an unsuccessful realloc().
-			 */
-			Mem_Handle_t    Mem_Realloc(Mem_Handle_t CurrAllocHdl, const Alloc_Size_t Bytes);
-			
-			/** Deallocates a given previously allocated section of memory from the heap.
-			 *
-			 *  \param CurrAllocHdl  Handle to a previously allocated section of memory in the heap
-			 */
-			void            Mem_Free(Mem_Handle_t CurrAllocHdl);
-			
-			/** Returns the total number of unallocated blocks in the heap.
-			 *
-			 *  \return Number of free blocks in the heap, as a Block_Number_t integer
-			 */
-			Block_Number_t  Mem_TotalFreeBlocks(void);
-
-			/** Returns the total number of unallocated handles in the handle pool.
-			 *
-			 *  \return Number of free handles in the handle pool, as a Handle_Number_t integer
-			 */
-			Handle_Number_t Mem_TotalFreeHandles(void);
-		
-	/* Private Interface - For use in library only: */
-	#if !defined(__DOXYGEN__)
-		/* Macros: */
-			#define BLOCK_USED_MASK           (1 << 0)
-			#define BLOCK_LINKED_MASK         (1 << 1)
-			
-		/* Function Prototypes: */
-			#if defined(INCLUDE_FROM_DYNALLOC_C)
-				static uint8_t Mem_GetBlockFlags(const Block_Number_t BlockNum);
-				static void    Mem_SetBlockFlags(const Block_Number_t BlockNum, const uint8_t Flags);
-				static void    Mem_Defrag(void);
-			#endif
-	#endif
-	
-#endif
-
-/** @} */
diff --git a/LUFA/Scheduler/Scheduler.c b/LUFA/Scheduler/Scheduler.c
deleted file mode 100644
index ff8946a0d..000000000
--- a/LUFA/Scheduler/Scheduler.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2009.
-              
-  dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
-*/
-
-/*
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, provided that the above copyright notice appear in all
-  copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-#include "Scheduler.h"
-
-volatile SchedulerDelayCounter_t Scheduler_TickCounter;
-volatile uint8_t                 Scheduler_TotalTasks;
-
-bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter)
-{
-	SchedulerDelayCounter_t CurrentTickValue_LCL;
-	SchedulerDelayCounter_t DelayCounter_LCL;
-	
-	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
-	{
-		CurrentTickValue_LCL = Scheduler_TickCounter;
-	}
-	
-	DelayCounter_LCL = *DelayCounter;
-	
-	if (CurrentTickValue_LCL >= DelayCounter_LCL)
-	{
-		if ((CurrentTickValue_LCL - DelayCounter_LCL) >= Delay)
-		{
-			*DelayCounter = CurrentTickValue_LCL;
-			return true;
-		}
-	}
-	else
-	{
-		if (((MAX_DELAYCTR_COUNT - DelayCounter_LCL) + CurrentTickValue_LCL) >= Delay)
-		{
-			*DelayCounter = CurrentTickValue_LCL;
-			return true;
-		}	
-	}
-	
-	return false;
-}
-
-void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus)
-{
-	TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-					
-	while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
-	{
-		if (CurrTask->Task == Task)
-		{
-			CurrTask->TaskStatus = TaskStatus;
-			break;
-		}
-		
-		CurrTask++;
-	}
-}
-
-void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus)
-{
-	TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-					
-	while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
-	{
-		if (CurrTask->GroupID == GroupID)
-		  CurrTask->TaskStatus = TaskStatus;
-		
-		CurrTask++;
-	}
-}
diff --git a/LUFA/Scheduler/Scheduler.h b/LUFA/Scheduler/Scheduler.h
deleted file mode 100644
index 0da80bb27..000000000
--- a/LUFA/Scheduler/Scheduler.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
-             LUFA Library
-     Copyright (C) Dean Camera, 2009.
-              
-  dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
-*/
-
-/*
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, provided that the above copyright notice appear in all
-  copies and that both that the copyright notice and this
-  permission notice and warranty disclaimer appear in supporting
-  documentation, and that the name of the author not be used in
-  advertising or publicity pertaining to distribution of the
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/** \file
- *
- *  Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- *  to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- */
- 
-/** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h
- *
- *  \section Sec_Dependencies Module Source Dependencies
- *  The following files must be built with any user project that uses this module:
- *    - LUFA/Scheduler/Scheduler.c
- *
- *  \section Module Description
- *  Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
- *  to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
- *
- *  For a task to yield it must return, thus each task should have persistent data marked with the static attribute.
- *
- *  Usage Example:
- *  \code
- *      #include <LUFA/Scheduler/Scheduler.h>
- *      
- *      TASK(MyTask1);
- *      TASK(MyTask2);
- *      
- *      TASK_LIST
- *      {
- *      	{ .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1  },
- *      	{ .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1  },
- *      }
- *
- *      int main(void)
- *      {
- *      	Scheduler_Start();
- *      }
- *
- *      TASK(MyTask1)
- *      {
- *      	// Implementation Here
- *      }
- *
- *      TASK(MyTask2)
- *      {
- *      	// Implementation Here
- *      }
- *  \endcode
- *
- *  @{
- */
- 
-#ifndef __SCHEDULER_H__
-#define __SCHEDULER_H__
-
-	/* Includes: */
-		#include <avr/io.h>
-		#include <stdbool.h>
-		
-		#include <util/atomic.h>
-
-		#include "../Common/Common.h"
-
-	/* Enable C linkage for C++ Compilers: */
-		#if defined(__cplusplus)
-			extern "C" {
-		#endif
-
-	/* Public Interface - May be used in end-application: */
-		/* Macros: */
-			/** Creates a new scheduler task body or prototype. Should be used in the form:
-			 *  \code
-			 *      TASK(TaskName); // Prototype
-			 *
-			 *      TASK(TaskName)
-			 *      {
-			 *           // Task body
-			 *      }
-			 *  \endcode
-			 */
-			#define TASK(name)                        void name (void)
-			
-			/** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list
-			 *  should be encased in curly braces and ended with a comma.
-			 *
-			 *  Usage Example:
-			 *  \code
-			 *      TASK_LIST
-			 *      {
-			 *           { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
-			 *           // More task entries here
-			 *      }
-			 *  \endcode
-			 */
-			#define TASK_LIST                         TaskEntry_t Scheduler_TaskList[] = 
-			
-			/** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type
-			 *  SchedulerDelayCounter_t.
-			 */
-			#define TASK_MAX_DELAY                    (MAX_DELAYCTR_COUNT - 1)
-
-			/** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
-			#define TASK_RUN                          true
-
-			/** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
-			#define TASK_STOP                         false
-			
-		/* Pseudo-Function Macros: */
-			#if defined(__DOXYGEN__)
-				/** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end
-				 *  of the user application's main() function, as it can never return to the calling function.
-				 */
-				void Scheduler_Start(void);
-				
-				/** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself
-				 *  is started. This must be executed before any scheduler function calls other than Scheduler_Start(),
-				 *  and can be omitted if no such functions could be called before the scheduler is started.
-				 */
-				void Scheduler_Init(void);
-			#else
-				#define Scheduler_Start()                 Scheduler_GoSchedule(TOTAL_TASKS);
-				
-				#define Scheduler_Init()                  Scheduler_InitScheduler(TOTAL_TASKS);
-			#endif
-
-		/* Type Defines: */
-			/** Type define for a pointer to a scheduler task. */
-			typedef void (*TaskPtr_t)(void);
-			
-			/** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay
-			 *  possible.
-			 */
-			typedef uint16_t SchedulerDelayCounter_t;
-			
-			/** Structure for holding a single task's information in the scheduler task list. */
-			typedef struct
-			{
-				TaskPtr_t Task;       /**< Pointer to the task to execute. */
-				bool      TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */
-				uint8_t   GroupID;    /**< Group ID of the task so that its status can be changed as a group. */
-			} TaskEntry_t;			
-
-		/* Global Variables: */
-			/** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type
-			 *  TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler
-			 *  functions should be used instead of direct manipulation.
-			 */
-			extern          TaskEntry_t               Scheduler_TaskList[];
-			
-			/** Contains the total number of tasks in the task list, irrespective of if the task's status is set to
-			 *  TASK_RUN or TASK_STOP.
-			 *
-			 *  \note This value should be treated as read-only, and never altered in user-code.
-			 */
-			extern volatile uint8_t                   Scheduler_TotalTasks;
-
-			/**  Contains the current scheduler tick count, for use with the delay functions. If the delay functions
-			 *   are used in the user code, this should be incremented each tick period so that the delays can be
-			 *   calculated.
-			 */
-			extern volatile SchedulerDelayCounter_t   Scheduler_TickCounter;
-
-		/* Inline Functions: */
-			/** Resets the delay counter value to the current tick count. This should be called to reset the period
-			 *  for a delay in a task which is dependant on the current tick value.
-			 *
-			 *  \param DelayCounter  Counter which is storing the starting tick count for a given delay.
-			 */
-			static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
-			                                        ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
-			static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
-			{
-				ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
-				{
-					*DelayCounter = Scheduler_TickCounter;
-				}
-			}
-		
-		/* Function Prototypes: */
-			/** Determines if the given tick delay has elapsed, based on the given .
-			 *
-			 *  \param Delay         The delay to test for, measured in ticks
-			 *  \param DelayCounter  The counter which is storing the starting tick value for the delay
-			 *
-			 *  \return Boolean true if the delay has elapsed, false otherwise
-			 *
-			 *  Usage Example:
-			 *  \code
-			 *      static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up
-			 *				 
-			 *      // Task runs every 10000 ticks, 10 seconds for this demo
-			 *      if (Scheduler_HasDelayElapsed(10000, &DelayCounter))
-			 *      {
-			 *           // Code to execute after delay interval elapsed here
-			 *      }
-			 *  \endcode
-			 */
-			bool Scheduler_HasDelayElapsed(const uint16_t Delay,
-			                               SchedulerDelayCounter_t* const DelayCounter)
-										   ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2);
-			
-			/** Sets the task mode for a given task.
-			 *
-			 *  \param Task        Name of the task whose status is to be changed
-			 *  \param TaskStatus  New task status for the task (TASK_RUN or TASK_STOP)
-			 */
-			void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus);
-			
-			/** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their
-			 *  statuses changed at once.
-			 *
-			 *  \param GroupID     Value of the task group ID whose status is to be changed
-			 *  \param TaskStatus  New task status for tasks in the specified group (TASK_RUN or TASK_STOP)
-			 */
-			void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus);
-
-	/* Private Interface - For use in library only: */		
-	#if !defined(__DOXYGEN__)
-		/* Macros: */
-			#define TOTAL_TASKS                       (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t))
-			#define MAX_DELAYCTR_COUNT                0xFFFF
-
-		/* Inline Functions: */
-			static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE;
-			static inline void Scheduler_InitScheduler(const uint8_t TotalTasks)
-			{
-				Scheduler_TotalTasks = TotalTasks;
-			}
-		
-			static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE;
-			static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)
-			{
-				Scheduler_InitScheduler(TotalTasks);
-
-				for (;;)
-				{
-					TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
-					
-					while (CurrTask != &Scheduler_TaskList[TotalTasks])
-					{
-						if (CurrTask->TaskStatus == TASK_RUN)
-						  CurrTask->Task();
-
-						CurrTask++;
-					}
-				}
-			}
-	#endif
-		
-	/* Disable C linkage for C++ Compilers: */
-		#if defined(__cplusplus)
-			}
-		#endif
-		
-#endif
-
-/** @} */
diff --git a/LUFA/SchedulerOverview.txt b/LUFA/SchedulerOverview.txt
deleted file mode 100644
index 5c031feac..000000000
--- a/LUFA/SchedulerOverview.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-/** \file
- *
- *  This file contains special DoxyGen information for the generation of the main page and other special
- *  documentation pages. It is not a project source file.
- */
-
-/** \page Page_SchedulerOverview LUFA Scheduler Overview
- *
- *  The LUFA library comes with a small, basic round-robbin scheduler which allows for small "tasks" to be executed
- *  continuously in sequence, and enabled/disabled at runtime. Unlike a conventional, complex RTOS scheduler, the
- *  LUFA scheduler is very simple in design and operation and is essentially a loop conditionally executing a series
- *  of functions.
- *
- *  Each LUFA scheduler task should be written similar to an ISR; it should execute quickly (so that no one task
- *  hogs the processor, preventing another from running before some sort of timeout is exceeded). Unlike normal RTOS
- *  tasks, each LUFA scheduler task is a regular function, and thus must be designed to be called, and designed to
- *  return to the calling scheduler function repeatedly. Data which must be preserved between task calls should be
- *  declared as global or (preferably) as a static local variable inside the task.
- *
- *  The scheduler consists of a task list, listing all the tasks which can be executed by the scheduler. Once started,
- *  each task is then called one after another, unless the task is stopped by another running task or interrupt.
- *
- *
- *  If desired, the LUFA scheduler <b>does not need to be used</b> in a LUFA powered application. A more conventional
- *  approach to application design can be used, or a proper scheduling RTOS inserted in the place of the LUFA scheduler.
- *  In the case of the former the USB task must be run manually repeatedly to maintain USB communications, and in the
- *  case of the latter a proper RTOS task must be set up to do the same.
- *
- *
- *  For more information on the LUFA scheduler, see the Scheduler.h file documentation.
- */
diff --git a/LUFA/makefile b/LUFA/makefile
index fc0009793..20f943aa0 100644
--- a/LUFA/makefile
+++ b/LUFA/makefile
@@ -15,13 +15,9 @@ LUFA_SRC_FILES =     ./Drivers/USB/LowLevel/DevChapter9.c        \
                      ./Drivers/USB/LowLevel/LowLevel.c           \
                      ./Drivers/USB/LowLevel/Pipe.c               \
                      ./Drivers/USB/HighLevel/Events.c            \
-                     ./Drivers/USB/HighLevel/StdDescriptors.c    \
                      ./Drivers/USB/HighLevel/USBInterrupt.c      \
                      ./Drivers/USB/HighLevel/USBTask.c           \
-                     ./Drivers/USB/Class/ConfigDescriptor.c      \
-                     ./Drivers/USB/Class/HIDParser.c             \
-                     ./Scheduler/Scheduler.c                     \
-                     ./MemoryAllocator/DynAlloc.c                \
+                     ./Drivers/USB/HighLevel/ConfigDescriptor.c  \
                      ./Drivers/Board/Temperature.c               \
                      ./Drivers/Peripheral/Serial.c               \
                      ./Drivers/Peripheral/SerialStream.c         \
diff --git a/Projects/Magstripe/Descriptors.c b/Projects/Magstripe/Descriptors.c
index 1dee58676..52b2c098f 100644
--- a/Projects/Magstripe/Descriptors.c
+++ b/Projects/Magstripe/Descriptors.c
@@ -142,7 +142,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			
 			.HIDSpec                = VERSION_BCD(01.11),
 			.CountryCode            = 0x00,
-			.TotalHIDDescriptors    = 1,
+			.TotalReportDescriptors = 1,
 			.HIDReportType          = DTYPE_Report,
 			.HIDReportLength        = sizeof(KeyboardReport)
 		},
diff --git a/Projects/Magstripe/Descriptors.h b/Projects/Magstripe/Descriptors.h
index 9948085a5..0fff2c2a8 100644
--- a/Projects/Magstripe/Descriptors.h
+++ b/Projects/Magstripe/Descriptors.h
@@ -38,34 +38,12 @@
 #define _DESCRIPTORS_H_
 
 	/* Includes: */
-		#include <LUFA/Drivers/USB/USB.h>
-
 		#include <avr/pgmspace.h>
 
-	/* Type Defines: */
-		/** Type define for the HID class specific HID descriptor. A HID descriptor is used in HID class devices
-		 *  to give information about the HID device, including the HID specification used, and the report descriptors
-		 *  the device contains to describe how the HID device should be controlled.
-		 */
-		typedef struct
-		{
-			USB_Descriptor_Header_t Header; /**< Standard USB descriptor header */
-				
-			uint16_t                HIDSpec; /**< HID specification implemented by the device, in BCD form */
-			uint8_t                 CountryCode; /**< Country code for the country the HID device is localised for */
-		
-			uint8_t                 TotalHIDDescriptors; /**< Total number of HID reports linked to this HID interface */
-
-			uint8_t                 HIDReportType; /**< Type of the first HID report descriptor */
-			uint16_t                HIDReportLength; /**< Length of the first HID report descriptor */
-		} USB_Descriptor_HID_t;
-
-		/** Type define for the data type used for the HID Report descriptor data elements. A HID report
-		 *  descriptor contains an array of this data type, indicating how the reports from and to the
-		 *  device are formatted and how the report data is to be used by the host.
-		 */
-		typedef uint8_t USB_Descriptor_HIDReport_Datatype_t;
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
+	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
 		 *  vary between devices, and which describe the device's usage to the host.
@@ -85,14 +63,8 @@
 		/** Size of the keyboard report endpoints, in bytes. */
 		#define KEYBOARD_EPSIZE              8
 
-		/** Descriptor type value for a HID descriptor. */
-		#define DTYPE_HID                    0x21
-
-		/** Descriptor type value for a HID report. */
-		#define DTYPE_Report                 0x22
-
 	/* Function Prototypes: */
 		uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
-											ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+		                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
 
 #endif
diff --git a/Projects/Magstripe/Magstripe.c b/Projects/Magstripe/Magstripe.c
index e860d5aca..5cd107e9a 100644
--- a/Projects/Magstripe/Magstripe.c
+++ b/Projects/Magstripe/Magstripe.c
@@ -28,60 +28,37 @@
   arising out of or in connection with the use or performance of
   this software.
 */
-
-/** \file
- *
- *  Main source file for the MagStripe application. This file contains the code which drives
- *  the USB keyboard interface from the magnetic card stripe reader device.
- */
  
 #include "Magstripe.h"
 
-/* Scheduler Task List */
-TASK_LIST
-{
-	{ .Task = USB_USBTask          , .TaskStatus = TASK_STOP },
-	{ .Task = USB_Keyboard_Report  , .TaskStatus = TASK_STOP },
-	{ .Task = Magstripe_Read       , .TaskStatus = TASK_STOP },
-};
-
-/* Global Variables */
-/** Indicates if the device is using Report Protocol mode, instead of Boot Protocol mode. Boot Protocol mode
- *  is a special reporting mode used by compatible PC BIOS to support USB keyboards before a full OS and USB
- *  driver has been loaded, by using predefined report structures indicated in the USB HID standard.
- */
-bool UsingReportProtocol = true;
+BitBuffer_t TrackDataBuffers[3];
 
-/** Total idle period in milliseconds set by the host via a SetIdle request, used to silence the report endpoint
- *  until the report data changes or the idle period elapsed. Generally used to implement hardware key repeats, or
- *  by some BIOS to reduce the number of reports when in Boot Protocol mode.
- */
-uint8_t IdleCount = 0;
-
-/** Milliseconds remaining counter for the HID class SetIdle and GetIdle requests, used to silence the report
- *  endpoint for an amount of time indicated by the host or until the report changes.
- */
-uint16_t IdleMSRemaining = 0;
-
-/** Circular buffer to hold the read bits from track 1 of the inserted magnetic card. */
-BitBuffer_t Track1Data;
+USB_ClassInfo_HID_t Keyboard_HID_Interface =
+	{
+		.InterfaceNumber         = 0,
 
-/** Circular buffer to hold the read bits from track 2 of the inserted magnetic card. */
-BitBuffer_t Track2Data;
+		.ReportINEndpointNumber  = KEYBOARD_EPNUM,
+		.ReportINEndpointSize    = KEYBOARD_EPSIZE,
+	};
 
-/** Circular buffer to hold the read bits from track 3 of the inserted magnetic card. */
-BitBuffer_t Track3Data;
+int main(void)
+{
+	SetupHardware();
+	
+	for (uint8_t Buffer = 0; Buffer < 3; Buffer++)
+	  BitBuffer_Init(&TrackDataBuffers[Buffer]);
 
-/** Delay counter between successive key strokes. This is to prevent the OS from ignoring multiple keys in a short
- *  period of time due to key repeats. Two milliseconds works for most OSes.
- */
-uint8_t KeyDelayRemaining;
+	for (;;)
+	{
+		if (Magstripe_GetStatus() & MAG_CARDPRESENT)
+		  ReadMagstripeData();
 
+		USB_HID_USBTask(&Keyboard_HID_Interface);
+		USB_USBTask();
+	}
+}
 
-/** Main program entry point. This routine configures the hardware required by the application, then
- *  starts the scheduler to run the application tasks.
- */
-int main(void)
+void SetupHardware(void)
 {
 	/* Disable watchdog if enabled by bootloader/fuses */
 	MCUSR &= ~(1 << WDRF);
@@ -92,330 +69,97 @@ int main(void)
 
 	/* Hardware Initialization */
 	Magstripe_Init();
-	
-	/* Buffer Initialization */
-	BitBuffer_Init(&Track1Data);
-	BitBuffer_Init(&Track2Data);
-	BitBuffer_Init(&Track3Data);
-	
-	/* Millisecond timer initialization, with output compare interrupt enabled for the idle timing */
-	OCR0A  = 0xFA;
-	TCCR0A = (1 << WGM01);
-	TCCR0B = ((1 << CS01) | (1 << CS00));
-	TIMSK0 = (1 << OCIE0A);
-	
-	/* Initialize Scheduler so that it can be used */
-	Scheduler_Init();
-
-	/* Initialize USB Subsystem */
 	USB_Init();
-	
-	/* Scheduling - routine never returns, so put this last in the main function */
-	Scheduler_Start();
 }
 
-/** Event handler for the USB_Connect event. This starts the USB task. */
-void EVENT_USB_Connect(void)
+void ReadMagstripeData(void)
 {
-	/* Start USB management task */
-	Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
-}
+	/* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */
+	const struct
+	{
+		uint8_t ClockMask;
+		uint8_t DataMask;	
+	} TrackInfo[] = {{MAG_T1_CLOCK, MAG_T1_DATA},
+	                 {MAG_T2_CLOCK, MAG_T2_DATA},
+	                 {MAG_T3_CLOCK, MAG_T3_DATA}};
 
-/** Event handler for the USB_Disconnect event. This stops the USB and keyboard report tasks. */
-void EVENT_USB_Disconnect(void)
-{
-	/* Stop running keyboard reporting, card reading and USB management tasks */
-	Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_STOP);
-	Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
-	Scheduler_SetTaskMode(Magstripe_Read, TASK_STOP);
+	uint8_t Magstripe_Prev = 0;
+	uint8_t Magstripe_LCL  = Magstripe_GetStatus();
+
+	while (Magstripe_LCL & MAG_CARDPRESENT)
+	{
+		for (uint8_t Track = 0; Track < 3; Track++)
+		{
+			bool DataPinLevel      = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);
+			bool ClockPinLevel     = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);
+			bool ClockLevelChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);
+		
+			if (ClockPinLevel && ClockLevelChanged)
+			  BitBuffer_StoreNextBit(&TrackDataBuffers[Track], DataPinLevel);
+		}
+
+		Magstripe_Prev = Magstripe_LCL;
+		Magstripe_LCL  = Magstripe_GetStatus();
+	}
 }
 
-/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
- *  to relay reports to the host, and starts the keyboard report task.
- */
 void EVENT_USB_ConfigurationChanged(void)
 {
-	/* Setup Keyboard Keycode Report Endpoint */
-	Endpoint_ConfigureEndpoint(KEYBOARD_EPNUM, EP_TYPE_INTERRUPT,
-		                       ENDPOINT_DIR_IN, KEYBOARD_EPSIZE,
-	                           ENDPOINT_BANK_SINGLE);
-	
-	/* Default to report protocol on connect */
-	UsingReportProtocol = true;
-
-	/* Start Keyboard reporting and card reading tasks */
-	Scheduler_SetTaskMode(USB_Keyboard_Report, TASK_RUN);
-	Scheduler_SetTaskMode(Magstripe_Read, TASK_RUN);
+	USB_HID_ConfigureEndpoints(&Keyboard_HID_Interface);
 }
 
-/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library, so that they can be handled appropriately
- *  for the application.
- */
 void EVENT_USB_UnhandledControlPacket(void)
 {
-	/* Handle HID Class specific requests */
-	switch (USB_ControlRequest.bRequest)
-	{
-		case REQ_GetReport:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				USB_KeyboardReport_Data_t KeyboardReportData;
-
-				/* Create the next keyboard report for transmission to the host */
-				GetNextReport(&KeyboardReportData);
-
-				Endpoint_ClearSETUP();
-	
-				/* Write the report data to the control endpoint */
-				Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
-				
-				/* Finalize the stream transfer to send the last packet or clear the host abort */
-				Endpoint_ClearOUT();
-			}
-		
-			break;
-		case REQ_GetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Write the current protocol flag to the host */
-				Endpoint_Write_Byte(UsingReportProtocol);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-			
-			break;
-		case REQ_SetProtocol:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-
-				/* Set or clear the flag depending on what the host indicates that the current Protocol should be */
-				UsingReportProtocol = (USB_ControlRequest.wValue != 0x0000);
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_SetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
-			{
-				Endpoint_ClearSETUP();
-				
-				/* Get idle period in MSB */
-				IdleCount = (USB_ControlRequest.wValue >> 8);
-				
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsINReady()));
-				Endpoint_ClearIN();
-			}
-			
-			break;
-		case REQ_GetIdle:
-			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
-			{		
-				Endpoint_ClearSETUP();
-				
-				/* Write the current idle duration to the host */
-				Endpoint_Write_Byte(IdleCount);
-				
-				/* Send the flag to the host */
-				Endpoint_ClearIN();
-
-				/* Acknowledge status stage */
-				while (!(Endpoint_IsOUTReceived()));
-				Endpoint_ClearOUT();
-			}
-
-			break;
-	}
+	USB_HID_ProcessControlPacket(&Keyboard_HID_Interface);
 }
 
-/** ISR for the timer 0 compare vector. This ISR fires once each millisecond, and decrements the counter indicating
- *  the number of milliseconds left to idle (not send the host reports) if the device has been instructed to idle
- *  by the host via a SetIdle class specific request.
- */
-ISR(TIMER0_COMPA_vect, ISR_BLOCK)
+void EVENT_USB_StartOfFrame(void)
 {
-	/* One millisecond has elapsed, decrement the idle time remaining counter if it has not already elapsed */
-	if (IdleMSRemaining)
-	  IdleMSRemaining--;
-	  
-	if (KeyDelayRemaining)
-	  KeyDelayRemaining--;
+	USB_HID_RegisterStartOfFrame(&Keyboard_HID_Interface);
 }
 
-/** Constructs a keyboard report indicating the currently pressed keyboard keys to the host.
- *
- *  \param ReportData  Pointer to a USB_KeyboardReport_Data_t report structure where the resulting report should
- *                     be stored
- *
- *  \return Boolean true if the current report is different to the previous report, false otherwise
- */
-bool GetNextReport(USB_KeyboardReport_Data_t* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
 {
-	static bool OddReport   = false;
-	static bool MustRelease = false;
-	
-	BitBuffer_t* Buffer     = NULL;
-
-	/* Clear the report contents */
-	memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t));
+	static bool IsKeyReleaseReport;
+	static bool IsNewlineReport;
 
-	/* Get the next non-empty track data buffer */
-	if (Track1Data.Elements)
-	  Buffer = &Track1Data;
-	else if (Track2Data.Elements)
-	  Buffer = &Track2Data;			
-	else if (Track3Data.Elements)
-	  Buffer = &Track3Data;
-
-	if (Buffer != NULL)
-	{
-		/* Toggle the odd report number indicator */
-		OddReport   = !OddReport;
+	BitBuffer_t*               Buffer         = NULL;
+	USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
 		
-		/* Set the flag indicating that a null report must eventually be sent to release all pressed keys */
-		MustRelease = true;
-
-		/* Only send the next key on odd reports, so that they are interspersed with null reports to release keys */
-		if (OddReport)
-		{
-			/* Set the report key code to the key code for the next data bit */
-			ReportData->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;
-			
-			/* If buffer is now empty, a new line must be sent instead of the terminating bit */
-			if (!(Buffer->Elements))
-			{
-				/* Set the keycode to the code for an enter key press */
-				ReportData->KeyCode = KEY_ENTER;				
-			}
-		}
+	/* Key reports must be interleaved with 0 Key Code reports to release the keys, or repeated keys will be ignored */
+	IsKeyReleaseReport = !IsKeyReleaseReport;	
 
-		return true;
-	}
-	else if (MustRelease)
+	if (IsKeyReleaseReport)
 	{
-		/* Leave key code to null (0), to release all pressed keys */
-		return true;
+		KeyboardReport->KeyCode = 0;
 	}
-	
-	return false;
-}
-
-/** Task to read out data from inserted magnetic cards and place the separate track data into their respective
- *  data buffers for later sending to the host as keyboard key presses.
- */
-TASK(Magstripe_Read)
-{
-	/* Arrays to hold the buffer pointers, clock and data bit masks for the separate card tracks */
-	const struct
+	else if (IsNewlineReport)
 	{
-		BitBuffer_t* Buffer;
-		uint8_t      ClockMask;
-		uint8_t      DataMask;	
-	} TrackInfo[] = {{&Track1Data, MAG_T1_CLOCK, MAG_T1_DATA},
-	                 {&Track2Data, MAG_T2_CLOCK, MAG_T2_DATA},
-	                 {&Track3Data, MAG_T3_CLOCK, MAG_T3_DATA}};
-
-	/* Previous magnetic card control line' status, for later comparison */
-	uint8_t Magstripe_Prev = 0;
-	
-	/* Buffered current card reader control line' status */
-	uint8_t Magstripe_LCL  = Magstripe_GetStatus();
-
-	/* Exit the task early if no card is present in the reader */
-	if (!(Magstripe_LCL & MAG_CARDPRESENT))
-	  return;
-
-	/* Read out card data while a card is present */
-	while (Magstripe_LCL & MAG_CARDPRESENT)
+		IsNewlineReport = false;
+		KeyboardReport->KeyCode = KEY_ENTER;
+	}
+	else
 	{
-		/* Read out the next bit for each track of the card */
-		for (uint8_t Track = 0; Track < 3; Track++)
-		{
-			/* Current data line status for the current card track */
-			bool DataLevel    = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);
-
-			/* Current clock line status for the current card track */
-			bool ClockLevel   = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);
-
-			/* Current track clock transition check */
-			bool ClockChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);
-		
-			/* Sample the next bit on the falling edge of the track's clock line, store key code into the track's buffer */
-			if (ClockLevel && ClockChanged)
-			  BitBuffer_StoreNextBit(TrackInfo[Track].Buffer, DataLevel);
-		}
-
-		/* Retain the current card reader control line states for later edge detection */
-		Magstripe_Prev = Magstripe_LCL;
+		if (TrackDataBuffers[0].Elements)
+		  Buffer = &TrackDataBuffers[0];
+		else if (TrackDataBuffers[1].Elements)
+		  Buffer = &TrackDataBuffers[1];			
+		else if (TrackDataBuffers[2].Elements)
+		  Buffer = &TrackDataBuffers[2];
+		else
+		  return 0;
+
+		KeyboardReport->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;
 		
-		/* Retrieve the new card reader control line states */
-		Magstripe_LCL  = Magstripe_GetStatus();
+		/* If buffer now empty, next report must be a newline to seperate track data */
+		if (!(Buffer->Elements))
+		  IsNewlineReport = true;
 	}
 	
-	/* Add terminators to the end of each track buffer */
-	BitBuffer_StoreNextBit(&Track1Data, 0);
-	BitBuffer_StoreNextBit(&Track2Data, 0);
-	BitBuffer_StoreNextBit(&Track3Data, 0);
+	return sizeof(USB_KeyboardReport_Data_t);
 }
 
-/** Task for the magnetic card reading and keyboard report generation. This task waits until a card is inserted,
- *  then reads off the card data and sends it to the host as a series of keyboard key presses via keyboard reports.
- */
-TASK(USB_Keyboard_Report)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
 {
-	USB_KeyboardReport_Data_t KeyboardReportData;
-	bool                      SendReport = false;
-	
-	/* Check if the USB system is connected to a host */
-	if (USB_IsConnected)
-	{
-		/* Select the Keyboard Report Endpoint */
-		Endpoint_SelectEndpoint(KEYBOARD_EPNUM);
-
-		/* Check if Keyboard Endpoint Ready for Read/Write */
-		if (Endpoint_IsReadWriteAllowed())
-		{
-			/* Only fetch the next key to send once the period between key presses has elapsed */
-			if (!(KeyDelayRemaining))
-			{
-				/* Create the next keyboard report for transmission to the host */
-				SendReport = GetNextReport(&KeyboardReportData);
-			}
-			
-			/* Check if the idle period is set and has elapsed */
-			if (IdleCount && !(IdleMSRemaining))
-			{
-				/* Idle period elapsed, indicate that a report must be sent */
-				SendReport = true;
-				
-				/* Reset the idle time remaining counter, must multiply by 4 to get the duration in milliseconds */
-				IdleMSRemaining = (IdleCount << 2);
-			}
-
-			/* Write the keyboard report if a report is to be sent to the host */
-			if (SendReport)
-			{
-				/* Write Keyboard Report Data */
-				Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(USB_KeyboardReport_Data_t));
-
-				/* Finalize the stream transfer to send the last packet */
-				Endpoint_ClearIN();
-
-				/* Reset the key delay period counter */
-				KeyDelayRemaining = 2;
-			}
-		}
-	}
+	// Unused (but mandatory for the HID class driver) in this demo, since there are no Host->Device reports
 }
diff --git a/Projects/Magstripe/Magstripe.h b/Projects/Magstripe/Magstripe.h
index c700bcaff..b0e47d596 100644
--- a/Projects/Magstripe/Magstripe.h
+++ b/Projects/Magstripe/Magstripe.h
@@ -40,46 +40,17 @@
 	/* Includes: */
 		#include <avr/io.h>
 		#include <avr/wdt.h>
-		#include <avr/interrupt.h>
 		#include <avr/power.h>
-		#include <stdbool.h>
-		#include <string.h>
 
 		#include "Descriptors.h"
-
 		#include "Lib/MagstripeHW.h"
 		#include "Lib/CircularBitBuffer.h"
 
-		#include <LUFA/Version.h>                    // Library Version Information
-		#include <LUFA/Drivers/USB/USB.h>            // USB Functionality
-		#include <LUFA/Scheduler/Scheduler.h>        // Simple scheduler for task management
-
-		
-	/* Task Definitions: */
-		/** Task definition for the keyboard and magnetic card reading task. */
-		TASK(USB_Keyboard_Report);
-		
-		TASK(Magstripe_Read);
+		#include <LUFA/Version.h>
+		#include <LUFA/Drivers/USB/USB.h>
+		#include <LUFA/Drivers/USB/Class/Device/HID.h>
 
 	/* Macros: */
-		/** HID Class Specific Request to get the current HID report from the device. */
-		#define REQ_GetReport      0x01
-
-		/** HID Class Specific Request to get the current device idle count. */
-		#define REQ_GetIdle        0x02
-
-		/** HID Class Specific Request to set the current HID report to the device. */
-		#define REQ_SetReport      0x09
-
-		/** HID Class Specific Request to set the device's idle count. */
-		#define REQ_SetIdle        0x0A
-
-		/** HID Class Specific Request to get the current HID report protocol mode. */
-		#define REQ_GetProtocol    0x03
-
-		/** HID Class Specific Request to set the current HID report protocol mode. */
-		#define REQ_SetProtocol    0x0B
-		
 		/** HID keyboard keycode to indicate that the "1" key is currently pressed. */
 		#define KEY_1              30
 
@@ -102,11 +73,15 @@
 		} USB_KeyboardReport_Data_t;
 	
 	/* Function Prototypes: */
-		void EVENT_USB_Connect(void);
-		void EVENT_USB_Disconnect(void);
+		void SetupHardware(void);
+		void ReadMagstripeData(void);
+		
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
-	
-		bool GetNextReport(USB_KeyboardReport_Data_t* ReportData);
+		void EVENT_USB_StartOfFrame(void);
+
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		                                                   void* ReportData, uint16_t ReportSize);
 		
 #endif
diff --git a/Projects/Magstripe/makefile b/Projects/Magstripe/makefile
index 962c999b3..138456fe8 100644
--- a/Projects/Magstripe/makefile
+++ b/Projects/Magstripe/makefile
@@ -126,7 +126,6 @@ LUFA_PATH = ../..
 SRC = $(TARGET).c                                                 \
 	  Descriptors.c                                               \
 	  Lib/CircularBitBuffer.c                                     \
-	  $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c               \
@@ -137,7 +136,7 @@ SRC = $(TARGET).c                                                 \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c      \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c           \
 	  $(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c  \
-	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c             \
+	  $(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/HID.c            \
 
 
 # List C++ source files here. (C dependencies are automatically generated.)
-- 
GitLab