diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
index 3c9f3049106372325e5ee397f36b4a202658ab6d..3e6aa28cb07a41b1d4a1f4805f10e8f17124a785 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -182,6 +182,20 @@ void Keyboard_HID_Task(void)
 				break;	
 			}
 
+			printf("Total Reports: %d\r\n", HIDReportInfo.TotalDeviceReports);
+
+			for (uint8_t i = 0; i < HIDReportInfo.TotalDeviceReports; i++)
+			{
+				HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[i];
+				
+				/* Print out the byte sizes of each report within the device */
+				printf_P(PSTR("  + Report ID %d - In: %d bytes, Out: %d bytes, Feature: %d bytes\r\n"),
+				                           CurrReportIDInfo->ReportID,
+				                           ((CurrReportIDInfo->BitsIn >> 3)      + (CurrReportIDInfo->BitsIn & 0x07)),
+				                           ((CurrReportIDInfo->BitsOut >> 3)     + (CurrReportIDInfo->BitsOut & 0x07)),
+				                           ((CurrReportIDInfo->BitsFeature >> 3) + (CurrReportIDInfo->BitsFeature & 0x07)));
+			}
+
 			puts_P(PSTR("Keyboard Enumerated.\r\n"));
 
 			USB_HostState = HOST_STATE_Configured;
diff --git a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
index 69ba64b13878c0b693e9e48ea595f2d08e56a225..670cab919cbf388519738d9045f6a31c14e55417 100644
--- a/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
+++ b/Demos/Host/LowLevel/MouseHostWithParser/MouseHostWithParser.c
@@ -181,6 +181,20 @@ void Mouse_HID_Task(void)
 				USB_HostState = HOST_STATE_WaitForDeviceRemoval;
 				break;
 			}
+			
+			printf("Total Reports: %d\r\n", HIDReportInfo.TotalDeviceReports);
+
+			for (uint8_t i = 0; i < HIDReportInfo.TotalDeviceReports; i++)
+			{
+				HID_ReportSizeInfo_t* CurrReportIDInfo = &HIDReportInfo.ReportIDSizes[i];
+
+				/* Print out the byte sizes of each report within the device */
+				printf_P(PSTR("  + Report ID %d - In: %d bytes, Out: %d bytes, Feature: %d bytes\r\n"),
+				                           CurrReportIDInfo->ReportID,
+				                           ((CurrReportIDInfo->BitsIn >> 3)      + (CurrReportIDInfo->BitsIn & 0x07)),
+				                           ((CurrReportIDInfo->BitsOut >> 3)     + (CurrReportIDInfo->BitsOut & 0x07)),
+				                           ((CurrReportIDInfo->BitsFeature >> 3) + (CurrReportIDInfo->BitsFeature & 0x07)));
+			}
 
 			puts_P(PSTR("Mouse Enumerated.\r\n"));
 
@@ -190,7 +204,7 @@ void Mouse_HID_Task(void)
 			/* Select and unfreeze mouse data pipe */
 			Pipe_SelectPipe(MOUSE_DATAPIPE);	
 			Pipe_Unfreeze();
-
+			
 			/* Check to see if a packet has been received */
 			if (Pipe_IsINReceived())
 			{
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.c b/LUFA/Drivers/USB/Class/Host/HIDParser.c
index 5174b59f9393cb4c5f8e74a9b337dba3fe844e5c..4293a3d98f609f74820a93c5455a6016c8cba6bb 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.c
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.c
@@ -38,19 +38,19 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 	HID_StateTable_t      StateTable[HID_STATETABLE_STACK_DEPTH];
 	HID_StateTable_t*     CurrStateTable          = &StateTable[0];
 	HID_CollectionPath_t* CurrCollectionPath      = NULL;
+	HID_ReportSizeInfo_t* CurrReportIDInfo        = &ParserData->ReportIDSizes[0];			
 	uint16_t              UsageStack[HID_USAGE_STACK_DEPTH];
 	uint8_t               UsageStackSize          = 0;
-	uint16_t              BitOffsetIn             = 0;
-	uint16_t              BitOffsetOut            = 0;
-	uint16_t              BitOffsetFeature        = 0;
 
-	ParserData->TotalReportItems     = 0;
-	ParserData->UsingMultipleReports = false;
+	ParserData->TotalReportItems   = 0;
+	ParserData->TotalDeviceReports = 1;
+	ParserData->UsingReportIDs     = false;
 	
 	for (uint8_t CurrCollection = 0; CurrCollection < HID_MAX_COLLECTIONS; CurrCollection++)
 	  ParserData->CollectionPaths[CurrCollection].Parent = NULL;
 
-	memset(&StateTable[0], 0x00, sizeof(HID_StateTable_t));
+	memset(CurrStateTable,   0x00, sizeof(HID_StateTable_t));
+	memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
 
 	while (ReportSize)
 	{
@@ -126,10 +126,33 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 				break;
 			case (TYPE_GLOBAL | TAG_GLOBAL_REPORTID):
 				CurrStateTable->ReportID                    = ReportItemData;
-				ParserData->UsingMultipleReports = true;
-				BitOffsetIn      = 0;
-				BitOffsetOut     = 0;
-				BitOffsetFeature = 0;
+
+				if (ParserData->UsingReportIDs)
+				{
+					CurrReportIDInfo = NULL;
+
+					for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++)
+					{
+						if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID)
+						{
+							CurrReportIDInfo = &ParserData->ReportIDSizes[i];
+							break;
+						}
+					}
+					
+					if (CurrReportIDInfo == NULL)
+					{
+						if (ParserData->TotalDeviceReports++ > HID_MAX_REPORT_IDS)
+						  return HID_PARSE_InsufficientReportIDItems;
+					
+						CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports - 1];
+						memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t));
+					}
+				}
+
+				ParserData->UsingReportIDs = true;				
+
+				CurrReportIDInfo->ReportID     = CurrStateTable->ReportID;
 				break;
 			case (TYPE_LOCAL | TAG_LOCAL_USAGE):
 				if (UsageStackSize == HID_USAGE_STACK_DEPTH)
@@ -223,21 +246,21 @@ uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID
 					{
 						case TAG_MAIN_INPUT:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_In;
-							NewReportItem.BitOffset = BitOffsetIn;
+							NewReportItem.BitOffset = CurrReportIDInfo->BitsIn;
 								
-							BitOffsetIn += CurrStateTable->Attributes.BitSize;
+							CurrReportIDInfo->BitsIn += CurrStateTable->Attributes.BitSize;
 							break;
 						case TAG_MAIN_OUTPUT:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_Out;
-							NewReportItem.BitOffset = BitOffsetOut;
+							NewReportItem.BitOffset = CurrReportIDInfo->BitsOut;
 								
-							BitOffsetOut += CurrStateTable->Attributes.BitSize;
+							CurrReportIDInfo->BitsOut += CurrStateTable->Attributes.BitSize;
 							break;
 						case TAG_MAIN_FEATURE:
 							NewReportItem.ItemType  = REPORT_ITEM_TYPE_Feature;						
-							NewReportItem.BitOffset = BitOffsetFeature;
+							NewReportItem.BitOffset = CurrReportIDInfo->BitsFeature;
 								
-							BitOffsetFeature += CurrStateTable->Attributes.BitSize;
+							CurrReportIDInfo->BitsFeature += CurrStateTable->Attributes.BitSize;
 							break;
 					}
 
diff --git a/LUFA/Drivers/USB/Class/Host/HIDParser.h b/LUFA/Drivers/USB/Class/Host/HIDParser.h
index 8d3fbf212d002ddd8a9c50baec7152f956569cb3..d9adae34d1e4d9fccbea00b665e2cb0b6f37593b 100644
--- a/LUFA/Drivers/USB/Class/Host/HIDParser.h
+++ b/LUFA/Drivers/USB/Class/Host/HIDParser.h
@@ -107,10 +107,21 @@
 			 *  in the report item descriptor and stored in the user HID Report Info structure. A large value allows
 			 *  for more report items to be stored, but consumes more memory. By default this is set to 20 items, 
 			 *  but this can be overridden by defining HID_MAX_REPORTITEMS to another value in the user project
-			 *  makefile, passing the define to the compiler using the -D compiler switch.
+			 *  makefile, and passing the define to the compiler using the -D compiler switch.
 			 */
 			#define HID_MAX_REPORTITEMS           20
 		#endif
+		
+		#if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__)
+			/** Constant indicating the maximum number of unique report IDs that can be processed in the report item
+			 *  descriptor for the report size information array in the user HID Report Info structure. A large value
+			 *  allows for more report ID report sizes to be stored, but consumes more memory. By default this is set
+			 *  to 5 items, but this can be overridden by defining HID_MAX_REPORT_IDS to another value in the user project
+			 *  makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE
+			 *  items sharing the same report ID consume only one size item in the array.
+			 */
+			#define HID_MAX_REPORT_IDS  5
+		#endif
 
 	/* Public Interface - May be used in end-application: */
 		/* Enums: */
@@ -132,6 +143,7 @@
 				HID_PARSE_UnexpectedEndCollection     = 4, /**< An END COLLECTION item found without matching COLLECTION item. */
 				HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */
 				HID_PARSE_UsageStackOverflow          = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */
+				HID_PARSE_InsufficientReportIDItems   = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */
 			};
 		
 		/* Type Defines: */		
@@ -191,6 +203,15 @@
 							
 				uint32_t                     Value;          /**< Current value of the report item. */
 			} HID_ReportItem_t;
+			
+			/** Type define for a report item size information structure */
+			typedef struct
+			{
+				uint8_t                      ReportID; /** Report ID of the report within the HID interface */
+				uint8_t                      BitsIn; /** Total number of IN data bits in the current report ID */
+				uint8_t                      BitsOut; /** Total number of OUT data bits in the current report ID */
+				uint8_t                      BitsFeature; /** Total number of FEATURE data bits in the current report ID */
+			} HID_ReportSizeInfo_t;
 
 			/** Type define for a complete processed HID report, including all report item data and collections. */
 			typedef struct
@@ -204,9 +225,11 @@
 				HID_CollectionPath_t         CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced
 				                                                                    *   by the report items.
 				                                                                    */
-				bool                         UsingMultipleReports; /**< Indicates if the device has at least one REPORT ID
-				                                                    *   element in its HID report descriptor.
-				                                                    */
+				uint8_t                      TotalDeviceReports; /** Number of reports within the HID interface */
+				HID_ReportSizeInfo_t         ReportIDSizes[HID_MAX_REPORT_IDS]; /** Report sizes for each report in the interface */
+				bool                         UsingReportIDs; /**< Indicates if the device has at least one REPORT ID
+				                                              *   element in its HID report descriptor.
+				                                              */
 			} HID_ReportInfo_t;
 			
 		/* Function Prototypes: */
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 76e939067f24af3de5926065a889efd1f766917c..9bbfba113adc4f949d20f3606e0467648d5a595d 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -39,6 +39,7 @@
   *  - The Benito Programmer project now has its own unique VID/PID pair allocated from the Atmel donated LUFA VID/PID pool
   *  - Add in new invalid event hook check targets to project makefiles to produce compilation errors when invalid event names
   *    are used in a project
+  *  - The HID Report Parser now gives information on the total length of each report within a HID interface
   *
   *  <b>Fixed:</b>
   *  - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the
diff --git a/LUFA/ManPages/CompileTimeTokens.txt b/LUFA/ManPages/CompileTimeTokens.txt
index ee18d27c8efe68eb54da148611108bcef6dfa73e..fb051b8c89047f8f4db7c0cadde29a42f631be79 100644
--- a/LUFA/ManPages/CompileTimeTokens.txt
+++ b/LUFA/ManPages/CompileTimeTokens.txt
@@ -51,6 +51,13 @@
  *  If a item has a multiple count (i.e. a REPORT COUNT of more than 1), each item in the report count is placed separately in the
  *  processed HID report table. If not defined, this defaults to the value indicated in the HID.h file documentation.
  *
+ *  <b>HID_MAX_REPORT_IDS</b> - ( \ref Group_HIDParser ) \n
+ *  HID reports may contain several report IDs, to logically distinguish grouped device data from one another - for example, a combination
+ *  keyboard and mouse might use report IDs to seperate the keyboard reports from the mouse reports. In order to determine the size of each
+ *  report, and thus know how many bytes must be read or written, the size of each report (IN, OUT and FEATURE) must be calculated and
+ *  stored. This token may be defined to a non-zero 8-bit value to set the maximum number of report IDs in a device which can be processed
+ *  and their sizes calculated/stored into the resultant processed report structure. If not defined, this defaults to the value indicated in
+ *  the HID.h file documentation.
  *
  *  \section Sec_SummaryUSBTokens USB Driver Related Tokens
  *  This section describes compile tokens which affect USB driver stack as a whole in the LUFA library.