diff --git a/Demos/Device/GenericHID/Descriptors.c b/Demos/Device/GenericHID/Descriptors.c
index ca1a110e7c360f6c0341808320ad28bd1880552f..6988166b318dd6b169b6cafeaedbd1bf81008cf0 100644
--- a/Demos/Device/GenericHID/Descriptors.c
+++ b/Demos/Device/GenericHID/Descriptors.c
@@ -119,7 +119,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.InterfaceNumber        = 0x00,
 			.AlternateSetting       = 0x00,
 			
-			.TotalEndpoints         = 2,
+			.TotalEndpoints         = 1,
 				
 			.Class                  = 0x03,
 			.SubClass               = 0x00,
@@ -148,16 +148,6 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.EndpointSize           = GENERIC_EPSIZE,
 			.PollingIntervalMS      = 0x02
 		},
-
-	.GenericOUTEndpoint = 
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-										 
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | GENERIC_OUT_EPNUM),
-			.Attributes             = EP_TYPE_INTERRUPT,
-			.EndpointSize           = GENERIC_EPSIZE,
-			.PollingIntervalMS      = 0x02
-		}
 };
 
 /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
diff --git a/Demos/Device/GenericHID/Descriptors.h b/Demos/Device/GenericHID/Descriptors.h
index bc4c68ae6b08d0fb0a75c3c9daf51f54d3b3bc2e..01db53e410155915c7321dea9f6c4a1a2cc65ed7 100644
--- a/Demos/Device/GenericHID/Descriptors.h
+++ b/Demos/Device/GenericHID/Descriptors.h
@@ -53,16 +53,12 @@
 			USB_Descriptor_Interface_t            Interface;
 			USB_Descriptor_HID_t                  GenericHID;
 	        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
 
-		/** Endpoint number of the Generic HID reporting OUT endpoint. */
-		#define GENERIC_OUT_EPNUM         2
-
 		/** Size in bytes of the Generic HID reporting endpoint. */
 		#define GENERIC_EPSIZE            8
 		
diff --git a/Demos/Device/GenericHID/GenericHID.c b/Demos/Device/GenericHID/GenericHID.c
index b933e4506b224e6aea290534f29410a51f082b20..172df7fa71caf1d73d310a46bdff2c06bccb8ccf 100644
--- a/Demos/Device/GenericHID/GenericHID.c
+++ b/Demos/Device/GenericHID/GenericHID.c
@@ -47,9 +47,6 @@ USB_ClassInfo_HID_t Generic_HID_Interface =
 		.ReportINEndpointNumber  = GENERIC_IN_EPNUM,
 		.ReportINEndpointSize    = GENERIC_EPSIZE,
 		
-		.ReportOUTEndpointNumber = GENERIC_OUT_EPNUM,
-		.ReportOUTEndpointSize   = GENERIC_EPSIZE,
-		
 		.ReportINBufferSize      = GENERIC_REPORT_SIZE,
 
 		.UsingReportProtocol     = true,
@@ -133,7 +130,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes written in the report (or zero if no report is to be sent
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
 	// Create generic HID report here
 	
@@ -146,7 +143,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to a buffer where the created report has been stored
  *  \param ReportSize  Size in bytes of the received HID report
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
 	// Process received generic HID report here
 }
diff --git a/Demos/Device/GenericHID/GenericHID.h b/Demos/Device/GenericHID/GenericHID.h
index b68dc4c24c473115fd97595e391370c85f34a49d..5ea084c7e53987051ebc759c64f68e73cd62f31e 100644
--- a/Demos/Device/GenericHID/GenericHID.h
+++ b/Demos/Device/GenericHID/GenericHID.h
@@ -72,8 +72,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
-		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, 
 		                                                   void* ReportData, uint16_t ReportSize);
 		
 #endif
diff --git a/Demos/Device/Joystick/Joystick.c b/Demos/Device/Joystick/Joystick.c
index 66cb808d0fd213cdf7237a4daa63dbd71f3df1d0..1cf59bbfd46c3d7f7e9e17f98f478f3b49ebfb82 100644
--- a/Demos/Device/Joystick/Joystick.c
+++ b/Demos/Device/Joystick/Joystick.c
@@ -132,7 +132,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes written in the report (or zero if no report is to be sent
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
 	USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;
 	
@@ -164,7 +164,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to a buffer where the created report has been stored
  *  \param ReportSize  Size in bytes of the received HID report
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
 	// 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 9db357b40338f2c205abdcfa9724f8b25fec84a5..4209f4d7edba331f41a07970d67f98ec9e3245e8 100644
--- a/Demos/Device/Joystick/Joystick.h
+++ b/Demos/Device/Joystick/Joystick.h
@@ -83,8 +83,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
-		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, 
 		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/Demos/Device/Keyboard/Descriptors.c b/Demos/Device/Keyboard/Descriptors.c
index ddd19fc8cf582c3d26daef5b6d44e5b5f2f6511c..8914909d772b18e5185112a170489da745e0ba3b 100644
--- a/Demos/Device/Keyboard/Descriptors.c
+++ b/Demos/Device/Keyboard/Descriptors.c
@@ -136,7 +136,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.InterfaceNumber        = 0x00,
 			.AlternateSetting       = 0x00,
 			
-			.TotalEndpoints         = 2,
+			.TotalEndpoints         = 1,
 				
 			.Class                  = 0x03,
 			.SubClass               = 0x01,
@@ -165,16 +165,6 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.EndpointSize           = KEYBOARD_EPSIZE,
 			.PollingIntervalMS      = 0x04
 		},
-
-	.KeyboardLEDsEndpoint = 
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | KEYBOARD_LEDS_EPNUM),
-			.Attributes             = EP_TYPE_INTERRUPT,
-			.EndpointSize           = KEYBOARD_EPSIZE,
-			.PollingIntervalMS      = 0x04
-		}
 };
 
 /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
diff --git a/Demos/Device/Keyboard/Descriptors.h b/Demos/Device/Keyboard/Descriptors.h
index 0a95ca06e8dae2f79f7029e6c82596b22a0b2334..40b358caa07bece1774c7587b0d64f69e67d5d67 100644
--- a/Demos/Device/Keyboard/Descriptors.h
+++ b/Demos/Device/Keyboard/Descriptors.h
@@ -54,15 +54,11 @@
 			USB_Descriptor_Interface_t            Interface;
 			USB_Descriptor_HID_t                  KeyboardHID;
 	        USB_Descriptor_Endpoint_t             KeyboardEndpoint;
-	        USB_Descriptor_Endpoint_t             KeyboardLEDsEndpoint;
 		} USB_Descriptor_Configuration_t;
 					
 	/* Macros: */
 		/** Endpoint number of the Keyboard HID reporting IN endpoint. */
 		#define KEYBOARD_EPNUM               1
-
-		/** Endpoint number of the Keyboard HID reporting OUT endpoint. */
-		#define KEYBOARD_LEDS_EPNUM          2
 		
 		/** Size in bytes of the Keyboard HID reporting IN and OUT endpoints. */		
 		#define KEYBOARD_EPSIZE              8
diff --git a/Demos/Device/Keyboard/Keyboard.c b/Demos/Device/Keyboard/Keyboard.c
index 923dd717695adf32000354a89c0715916ece7afe..bebad12e03195bf7ec53a99a50fe7beb0c6a0bfb 100644
--- a/Demos/Device/Keyboard/Keyboard.c
+++ b/Demos/Device/Keyboard/Keyboard.c
@@ -48,9 +48,6 @@ USB_ClassInfo_HID_t Keyboard_HID_Interface =
         .ReportINEndpointNumber  = KEYBOARD_EPNUM,
         .ReportINEndpointSize    = KEYBOARD_EPSIZE,
 
-        .ReportOUTEndpointNumber = KEYBOARD_LEDS_EPNUM,
-        .ReportOUTEndpointSize   = KEYBOARD_EPSIZE,
-        
 		.ReportINBufferSize      = sizeof(USB_KeyboardReport_Data_t),
 
         .IdleCount               = 500,
@@ -136,7 +133,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes written in the report (or zero if no report is to be sent
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
     USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
     
@@ -168,7 +165,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to a buffer where the created report has been stored
  *  \param ReportSize  Size in bytes of the received HID report
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
     uint8_t  LEDMask   = LEDS_NO_LEDS;
     uint8_t* LEDReport = (uint8_t*)ReportData;
diff --git a/Demos/Device/Keyboard/Keyboard.h b/Demos/Device/Keyboard/Keyboard.h
index e04ae9e340bfa4ee5cb25e4ff284d512a8715db6..1b4bb7092a66e7bb2a7ee4bcbe92438c868c09ff 100644
--- a/Demos/Device/Keyboard/Keyboard.h
+++ b/Demos/Device/Keyboard/Keyboard.h
@@ -86,8 +86,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
-		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, 
 		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/Demos/Device/KeyboardMouse/Descriptors.c b/Demos/Device/KeyboardMouse/Descriptors.c
index 145708db9361235be254b4585c6267ec06f64319..c9a778feb2d57a5ff528694a3d9170f0b21500c0 100644
--- a/Demos/Device/KeyboardMouse/Descriptors.c
+++ b/Demos/Device/KeyboardMouse/Descriptors.c
@@ -169,7 +169,7 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.InterfaceNumber        = 0x00,
 			.AlternateSetting       = 0x00,
 			
-			.TotalEndpoints         = 2,
+			.TotalEndpoints         = 1,
 				
 			.Class                  = 0x03,
 			.SubClass               = 0x01,
@@ -199,16 +199,6 @@ USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.PollingIntervalMS      = 0x02
 		},
 
-	.KeyboardOutEndpoint = 
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
-			.EndpointAddress        = (ENDPOINT_DESCRIPTOR_DIR_OUT | KEYBOARD_OUT_EPNUM),
-			.Attributes             = EP_TYPE_INTERRUPT,
-			.EndpointSize           = HID_EPSIZE,
-			.PollingIntervalMS      = 0x02
-		},
-
 	.MouseInterface = 
 		{
 			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
diff --git a/Demos/Device/KeyboardMouse/Descriptors.h b/Demos/Device/KeyboardMouse/Descriptors.h
index 152e5111af8e636745d225cb718a57200bd9cb29..1dcad086e2005db8a8077f1b425dd4413bbcea30 100644
--- a/Demos/Device/KeyboardMouse/Descriptors.h
+++ b/Demos/Device/KeyboardMouse/Descriptors.h
@@ -54,7 +54,6 @@
 			USB_Descriptor_Interface_t            KeyboardInterface;
 			USB_Descriptor_HID_t                  KeyboardHID;
 	        USB_Descriptor_Endpoint_t             KeyboardInEndpoint;
-	        USB_Descriptor_Endpoint_t             KeyboardOutEndpoint;
 			USB_Descriptor_Interface_t            MouseInterface;
 			USB_Descriptor_HID_t                  MouseHID;
 	        USB_Descriptor_Endpoint_t             MouseInEndpoint;
@@ -64,9 +63,6 @@
 		/** Endpoint number of the Keyboard HID reporting IN endpoint. */
 		#define KEYBOARD_IN_EPNUM         1
 
-		/** Endpoint number of the Keyboard HID reporting OUT endpoint. */
-		#define KEYBOARD_OUT_EPNUM        2
-
 		/** Endpoint number of the Mouse HID reporting IN endpoint. */
 		#define MOUSE_IN_EPNUM            3
 
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.c b/Demos/Device/KeyboardMouse/KeyboardMouse.c
index e68a247938831025059f5aa5f2e41357b58c7652..5cea5558097bc711cf1eae9ff622c356618e3377 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.c
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.c
@@ -48,9 +48,6 @@ USB_ClassInfo_HID_t Keyboard_HID_Interface =
 
 		.ReportINEndpointNumber  = KEYBOARD_IN_EPNUM,
 		.ReportINEndpointSize    = HID_EPSIZE,
-
-		.ReportOUTEndpointNumber = KEYBOARD_OUT_EPNUM,
-		.ReportOUTEndpointSize   = HID_EPSIZE,
 		
 		.ReportINBufferSize      = sizeof(USB_KeyboardReport_Data_t),
 
@@ -70,9 +67,6 @@ USB_ClassInfo_HID_t Mouse_HID_Interface =
 		.ReportINEndpointSize    = HID_EPSIZE,
 
 		.ReportINBufferSize      = sizeof(USB_MouseReport_Data_t),
-
-		.ReportOUTEndpointNumber = 0,
-		.ReportOUTEndpointSize   = 0,
 	};
 
 /** Main program entry point. This routine contains the overall program flow, including initial
@@ -162,7 +156,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes written in the report (or zero if no report is to be sent
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
 	uint8_t JoyStatus_LCL    = Joystick_GetStatus();
 	uint8_t ButtonStatus_LCL = Buttons_GetStatus();
@@ -221,7 +215,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to a buffer where the created report has been stored
  *  \param ReportSize  Size in bytes of the received HID report
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
 	if (HIDInterfaceInfo == &Keyboard_HID_Interface)
 	{
diff --git a/Demos/Device/KeyboardMouse/KeyboardMouse.h b/Demos/Device/KeyboardMouse/KeyboardMouse.h
index 9afe7646bc1d9bfddfc415c7af30005aa34634ad..74b1c9e5f2e8c7718db408f51be09cd75f53012d 100644
--- a/Demos/Device/KeyboardMouse/KeyboardMouse.h
+++ b/Demos/Device/KeyboardMouse/KeyboardMouse.h
@@ -90,8 +90,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
-		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, 
 		                                                   void* ReportData, uint16_t ReportSize);
 		
 #endif
diff --git a/Demos/Device/Mouse/Mouse.c b/Demos/Device/Mouse/Mouse.c
index 1bc62dac69b653cd399861c8dccbb8d26ee641ed..f5bd931d175612e070b0e95712d872d9eafc10d5 100644
--- a/Demos/Device/Mouse/Mouse.c
+++ b/Demos/Device/Mouse/Mouse.c
@@ -130,7 +130,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes written in the report (or zero if no report is to be sent
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
 	USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData;
 		
@@ -162,7 +162,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to a buffer where the created report has been stored
  *  \param ReportSize  Size in bytes of the received HID report
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
 	// 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 62d6d832367e7851d2c1af85d7969a72460bd856..6de20ee797a8016024b75dfa24b007609480e6d2 100644
--- a/Demos/Device/Mouse/Mouse.h
+++ b/Demos/Device/Mouse/Mouse.h
@@ -85,8 +85,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(void);
 
-		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData);
-		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo,
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, 
 		                                                   void* ReportData, uint16_t ReportSize);
 
 #endif
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.c b/LUFA/Drivers/USB/Class/Device/CDC.c
index d27b0d2edcdda0aca050dcdd6cbfe7ea8d7425e1..dface2a6db50eb102f95934c3baedf531cbb9798 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.c
+++ b/LUFA/Drivers/USB/Class/Device/CDC.c
@@ -169,7 +169,7 @@ uint8_t USB_CDC_ReceiveByte(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
 	return DataByte;
 }
 
-void USB_CDC_SendSerialLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
+void USB_CDC_SendSerialLineStateChange(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask)
 {
 	Endpoint_SelectEndpoint(CDCInterfaceInfo->NotificationEndpointNumber);
 	
diff --git a/LUFA/Drivers/USB/Class/Device/CDC.h b/LUFA/Drivers/USB/Class/Device/CDC.h
index 3e67b1b6b63dca6e6b749f726ea8cc8282337971..ee9e3767dbc6e45843596db361e027d2a8b938f6 100644
--- a/LUFA/Drivers/USB/Class/Device/CDC.h
+++ b/LUFA/Drivers/USB/Class/Device/CDC.h
@@ -167,7 +167,7 @@
 			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; /**< Current control line state, as set by the host */
+			uint8_t  ControlLineState; /**< Current control line states, as set by the host */
 
 			struct
 			{
@@ -195,7 +195,7 @@
 		 *  \ref EVENT_USB_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the
 		 *  given CDC interface is selected.
 		 *
-		 *  \param CDCInterfaceInfo  Pointer to a structure containing an CDC Class configuration and state.
+		 *  \param CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 		 *
 		 *  \return Boolean true if the endpoints were sucessfully configured, false otherwise
 		 */
@@ -204,25 +204,41 @@
 		/** Processes incomming control requests from the host, that are directed to the given CDC class interface. This should be
 		 *  linked to the library \ref EVENT_USB_UnhandledControlPacket() event.
 		 *
-		 *  \param CDCInterfaceInfo  Pointer to a structure containing an CDC Class configuration and state.
+		 *  \param CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 		 */
 		void USB_CDC_ProcessControlPacket(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
 
 		/** General management task for a given CDC class interface, required for the correct operation of the interface. This should
 		 *  be called frequently in the main program loop, before the master USB management task \ref USB_USBTask().
 		 *
-		 *  \param CDCInterfaceInfo  Pointer to a structure containing an CDC Class configuration and state.
+		 *  \param CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
 		 */
 		void USB_CDC_USBTask(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
 
-		void     EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
-		void     EVENT_USB_CDC_ControLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		/** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a
+		 *  line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the
+		 *  user program by declaring a handler function with the same name and parameters listed here. The new line encoding
+		 *  settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter.
+		 *
+		 *  \param CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
+		 */
+		void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
+		
+		/** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a
+		 *  control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the
+		 *  user program by declaring a handler function with the same name and parameters listed here. The new control line states
+		 *  are available in the ControlLineState value inside the CDC interface structure passed as a parameter, set as a mask of
+		 *  CDC_CONTROL_LINE_OUT_* masks.
+		 *
+		 *  \param CDCInterfaceInfo  Pointer to a structure containing a CDC Class configuration and state.
+		 */		
+		void EVENT_USB_CDC_ControLineStateChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
 
 		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);
+		void     USB_CDC_SendSerialLineStateChange(USB_ClassInfo_CDC_t* CDCInterfaceInfo, uint16_t LineStateMask);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/Device/HID.c b/LUFA/Drivers/USB/Class/Device/HID.c
index 5f8ccfbaef16e7410b714c26afc8bf65329b6c0e..06992189f323d6315357da197324065c13b6838c 100644
--- a/LUFA/Drivers/USB/Class/Device/HID.c
+++ b/LUFA/Drivers/USB/Class/Device/HID.c
@@ -47,10 +47,11 @@ void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
 
 				uint8_t  ReportINData[HIDInterfaceInfo->ReportINBufferSize];
 				uint16_t ReportINSize;
+				uint8_t  ReportID = (USB_ControlRequest.wValue & 0xFF);
 
 				memset(ReportINData, 0, sizeof(ReportINData));
-
-				ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+				
+				ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, &ReportID, ReportINData);
 
 				Endpoint_Write_Control_Stream_LE(ReportINData, ReportINSize);
 				Endpoint_ClearOUT();
@@ -64,11 +65,12 @@ void USB_HID_ProcessControlPacket(USB_ClassInfo_HID_t* HIDInterfaceInfo)
 				
 				uint16_t ReportOUTSize = USB_ControlRequest.wLength;
 				uint8_t  ReportOUTData[ReportOUTSize];
+				uint8_t  ReportID = (USB_ControlRequest.wValue & 0xFF);
 
 				Endpoint_Read_Control_Stream_LE(ReportOUTData, ReportOUTSize);
 				Endpoint_ClearIN();
 				
-				CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
+				CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportID, ReportOUTData, ReportOUTSize);
 			}
 			
 			break;
@@ -135,15 +137,6 @@ bool USB_HID_ConfigureEndpoints(USB_ClassInfo_HID_t* HIDInterfaceInfo)
 		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;
 }
 		
@@ -162,32 +155,20 @@ void USB_HID_USBTask(USB_ClassInfo_HID_t* HIDInterfaceInfo)
 
 		uint8_t  ReportINData[HIDInterfaceInfo->ReportINBufferSize];
 		uint16_t ReportINSize;
+		uint8_t  ReportID = 0;
 
 		memset(ReportINData, 0, sizeof(ReportINData));
 
-		ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, ReportINData);
+		ReportINSize = CALLBACK_USB_HID_CreateNextHIDReport(HIDInterfaceInfo, &ReportID, ReportINData);
 
 		if (ReportINSize)
-		  Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NO_STREAM_CALLBACK);
-		
-		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, NO_STREAM_CALLBACK);
-			  
-			CALLBACK_USB_HID_ProcessReceivedHIDReport(HIDInterfaceInfo, ReportOUTData, ReportOUTSize);
-			
-			Endpoint_ClearOUT();
+			if (ReportID)
+			  Endpoint_Write_Stream_LE(&ReportID, sizeof(ReportID), NO_STREAM_CALLBACK);
+
+			Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NO_STREAM_CALLBACK);
 		}
+		
+		Endpoint_ClearIN();
 	}
 }
diff --git a/LUFA/Drivers/USB/Class/Device/HID.h b/LUFA/Drivers/USB/Class/Device/HID.h
index 9a563040c0732f74607ea39b6d72c9e9a15a0eb8..4fd6f2c22b0b02173434e20caa2379288776a45b 100644
--- a/LUFA/Drivers/USB/Class/Device/HID.h
+++ b/LUFA/Drivers/USB/Class/Device/HID.h
@@ -111,9 +111,6 @@
 
 			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  ReportINBufferSize;
 
@@ -127,8 +124,30 @@
 		void USB_HID_ProcessControlPacket(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);
+		/** HID class driver callback for the user creation of a HID input report. This callback may fire in response to either
+		 *  HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the
+		 *  user is responsible for the creation of the next HID input report to be sent to the host.
+		 *
+		 *  \param HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
+		 *  \param ReportID  If preset to a non-zero value, this is the report ID being requested by the host. If zero, this should
+		 *                   be set to the report ID of the generated HID input report. If multiple reports are not sent via the
+		 *                   given HID interface, this parameter should be ignored.
+		 *  \param ReportData  Pointer to a buffer where the generated HID report should be stored.
+		 *
+		 *  \return  Number of bytes in the generated input report, or zero if no report is to be sent
+		 */
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+
+		/** HID class driver callback for the user processing of a received HID input report. This callback may fire in response to
+		 *  either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback
+		 *  the user is responsible for the processing of the received HID output report from the host.
+		 *
+		 *  \param HIDInterfaceInfo  Pointer to a structure containing a HID Class configuration and state.
+		 *  \param ReportID  Report ID of the received output report. If multiple reports are not received via the given HID
+		 *                   interface, this parameter should be ignored.
+		 *  \param ReportData  Pointer to a buffer where the received HID report is stored.
+		 */
+		void     CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID, void* ReportData, uint16_t ReportSize);
 
 	/* Disable C linkage for C++ Compilers: */
 		#if defined(__cplusplus)
diff --git a/LUFA/Drivers/USB/Class/Device/MIDI.h b/LUFA/Drivers/USB/Class/Device/MIDI.h
index b2294d86c5e69ec1b6667f564b8712ab58515780..08a530af2e83396d4861b20193c01394610aa9d2 100644
--- a/LUFA/Drivers/USB/Class/Device/MIDI.h
+++ b/LUFA/Drivers/USB/Class/Device/MIDI.h
@@ -76,7 +76,7 @@
 		/** MIDI command for a note off (deactivation) event */
 		#define MIDI_COMMAND_NOTE_OFF       0x08
 
-		/** Standard key press velocity value used for all note events, as no pressure sensor is mounted */
+		/** Standard key press velocity value used for all note events */
 		#define MIDI_STANDARD_VELOCITY      64
 		
 		/** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel
diff --git a/Projects/Magstripe/Magstripe.c b/Projects/Magstripe/Magstripe.c
index e32397c8bb7e94b6e725a3af88e1921d8fc9c4b5..6e5e00b910070d0410941888b07655c641567e0d 100644
--- a/Projects/Magstripe/Magstripe.c
+++ b/Projects/Magstripe/Magstripe.c
@@ -157,7 +157,7 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
  *
  *  \return Number of bytes in the created report
  */
-uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData)
+uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData)
 {
 	static bool IsKeyReleaseReport;
 	static bool IsNewlineReport;
@@ -204,7 +204,8 @@ uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceI
  *  \param ReportData  Pointer to the report buffer where the received report is stored
  *  \param ReportSize  Size in bytes of the report received from the host
  */
-void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, void* ReportData, uint16_t ReportSize)
+void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                               void* ReportData, uint16_t ReportSize)
 {
 	// 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 2b8aa3770dc291802d28713d733fcb33dcf66f95..6a13af4ec5656a74000e118cc03fd02ffce92c4f 100644
--- a/Projects/Magstripe/Magstripe.h
+++ b/Projects/Magstripe/Magstripe.h
@@ -79,8 +79,8 @@
 		void EVENT_USB_ConfigurationChanged(void);
 		void EVENT_USB_UnhandledControlPacket(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);
+		uint16_t CALLBACK_USB_HID_CreateNextHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t* ReportID, void* ReportData);
+		void CALLBACK_USB_HID_ProcessReceivedHIDReport(USB_ClassInfo_HID_t* HIDInterfaceInfo, uint8_t ReportID,
+                                                       void* ReportData, uint16_t ReportSize);
 		
 #endif