Index: uspace/lib/usbhid/include/usb/classes/hid_report_items.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hid_report_items.h	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/include/usb/classes/hid_report_items.h	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -46,4 +46,11 @@
 #define USB_HID_ITEM_IS_LONG(data)	(data == 0xFE)
 
+
+/**
+ * Extended usage macros
+ */
+#define USB_HID_IS_EXTENDED_USAGE(usage)	((usage & 0xFFFF0000) != 0)
+#define USB_HID_EXTENDED_USAGE_PAGE(usage)	((usage & 0xFFFF0000) >> 16)
+#define USB_HID_EXTENDED_USAGE(usage)		(usage & 0xFFFF)
 
 /**
Index: uspace/lib/usbhid/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidparser.h	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/include/usb/classes/hidparser.h	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -51,8 +51,4 @@
                          size_t size, uint8_t *report_id);
 
-/** */
-size_t usb_hid_report_input_length(const usb_hid_report_t *report,
-	usb_hid_report_path_t *path, int flags);
-
 /*
  * Output report parser functions
@@ -65,7 +61,7 @@
 void usb_hid_report_output_free(uint8_t *output);
 
-/** Returns size of output for given usage path */
-size_t usb_hid_report_output_size(usb_hid_report_t *report,
-                                  usb_hid_report_path_t *path, int flags);
+/** Returns size of report in items */
+size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 
+                           usb_hid_report_type_t type);
 
 /** Makes the output report buffer by translated given data */
Index: uspace/lib/usbhid/include/usb/classes/hidtypes.h
===================================================================
--- uspace/lib/usbhid/include/usb/classes/hidtypes.h	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/include/usb/classes/hidtypes.h	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -39,5 +39,5 @@
 #include <adt/list.h>
 
-#define USB_HID_MAX_USAGES	20
+#define USB_HID_MAX_USAGES	0xffff
 
 #define USB_HID_UINT32_TO_INT32(x, size)	((((x) & (1 << ((size) - 1))) != 0) ? -(~(x - 1) & ((1 << size) - 1)) : (x)) //(-(~((x) - 1)))
@@ -92,9 +92,11 @@
 	int32_t physical_minimum;
 	int32_t physical_maximum;
-	uint32_t usage_minimum;
-	uint32_t usage_maximum;
+	int32_t usage_minimum;
+	int32_t usage_maximum;
 	uint32_t unit;
 	uint32_t unit_exponent;
-	
+
+	uint32_t *usages;
+	size_t usages_count;
 
 	int32_t value;
@@ -121,7 +123,7 @@
 
 	/** */	
-	uint32_t usage_minimum;
-	/** */	
-	uint32_t usage_maximum;
+	int32_t usage_minimum;
+	/** */	
+	int32_t usage_maximum;
 	/** */	
 	int32_t logical_minimum;
Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -64,6 +64,9 @@
 {
 	/* find or append current collection path to the list */
-	link_t *path_it = report->collection_paths.next;
+	//link_t *path_it = report->collection_paths.next;
+	link_t *path_it = report->collection_paths.prev->next;
 	usb_hid_report_path_t *path = NULL;
+	
+	
 	while(path_it != &report->collection_paths) {
 		path = list_get_instance(path_it, usb_hid_report_path_t, link);
@@ -116,8 +119,14 @@
 	int i;
 
-	for(i=0; i<report_item->usages_count; i++){
-		usb_log_debug("usages (%d) - %x\n", i, report_item->usages[i]);
-	}
-
+	uint32_t *usages;
+	int usages_used=0;
+	if(report_item->usages_count > 0){
+		usages = malloc(sizeof(int32_t) * report_item->usages_count);
+		memcpy(usages, report_item->usages, sizeof(int32_t) * report_item->usages_count);
+	}
+	else {
+		usages = NULL;
+	}
+	
 	usb_hid_report_path_t *path = report_item->usage_path;	
 	for(i=0; i<report_item->count; i++){
@@ -133,16 +142,21 @@
 		field->physical_maximum = report_item->physical_maximum;
 
-		field->usage_minimum = report_item->usage_minimum;
-		field->usage_maximum = report_item->usage_maximum;
-		if(report_item->extended_usage_page != 0){
-			field->usage_page = report_item->extended_usage_page;
+		if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0){
+			/* 
+			 	Store usage array. The Correct Usage Page and Usage is depending 
+			 	on data in report and will be filled later
+			*/
+			field->usage = 0;
+			field->usage_page = 0; //report_item->usage_page;
+
+			field->usages_count = report_item->usages_count;
+			field->usages = usages;
+			usages_used = 1;
 		}
 		else {
-			field->usage_page = report_item->usage_page;
-		}
-
-		if(report_item->usages_count > 0 && ((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0))) {
-			uint32_t usage;
-			if(i < report_item->usages_count){
+
+			/* Fill the correct Usage and Usage Page */
+			int32_t usage;
+			if(i < report_item->usages_count) {
 				usage = report_item->usages[i];
 			}
@@ -151,18 +165,13 @@
 			}
 
-						
-			if((usage & 0xFFFF0000) != 0){
-				field->usage_page = (usage >> 16);					
-				field->usage = (usage & 0xFFFF);
+			if(USB_HID_IS_EXTENDED_USAGE(usage)){
+				field->usage = USB_HID_EXTENDED_USAGE(usage);
+				field->usage_page = USB_HID_EXTENDED_USAGE_PAGE(usage);
 			}
 			else {
+				// should not occur
 				field->usage = usage;
-			}
-
-			
-		}	
-
-		if((USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) != 0) && (!((report_item->usage_minimum == 0) && (report_item->usage_maximum == 0)))) {
-			field->usage = report_item->usage_minimum + i;					
+				field->usage_page = report_item->usage_page;
+			}
 		}
 		
@@ -209,4 +218,8 @@
 	}
 
+	// free only when not used!!!
+	if(usages && usages_used == 0) {
+		free(usages);
+	}
 
 	return EOK;
@@ -450,4 +463,5 @@
 			
 		case USB_HID_REPORT_TAG_COLLECTION:
+
 			// store collection atributes
 			path_item = list_get_instance(usage_path->head.prev, usb_hid_report_usage_path_t, link);
@@ -455,6 +469,10 @@
 			
 			// set last item
-			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, report_item->usage_page);
-			usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, report_item->usages[report_item->usages_count-1]);
+			usb_hid_report_set_last_item(usage_path, 
+			                             USB_HID_TAG_CLASS_GLOBAL, 
+			                             USB_HID_EXTENDED_USAGE_PAGE(report_item->usages[report_item->usages_count-1]));
+			usb_hid_report_set_last_item(usage_path, 
+			                             USB_HID_TAG_CLASS_LOCAL, 
+			                             USB_HID_EXTENDED_USAGE(report_item->usages[report_item->usages_count-1]));
 			
 			// append the new one which will be set by common
@@ -551,4 +569,6 @@
                              usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
 {
+	int32_t extended_usage;
+	
 	switch(tag) {
 		case USB_HID_REPORT_TAG_USAGE:
@@ -560,10 +580,12 @@
 					report_item->in_delimiter = INSIDE_DELIMITER_SET;
 				case OUTSIDE_DELIMITER_SET:
-					report_item->usages[report_item->usages_count] = usb_hid_report_tag_data_uint32(data,item_size);
+					extended_usage = ((report_item->usage_page) << 16);
+					extended_usage += usb_hid_report_tag_data_uint32(data,item_size);
+					report_item->usages[report_item->usages_count] = extended_usage;
 					report_item->usages_count++;
 					break;
 			}
 			break;
-		case USB_HID_REPORT_TAG_USAGE_MINIMUM:
+		case USB_HID_REPORT_TAG_USAGE_MINIMUM:			
 			if (item_size == 3) {
 				// usage extended usages
@@ -577,4 +599,9 @@
 		case USB_HID_REPORT_TAG_USAGE_MAXIMUM:
 			if (item_size == 3) {
+
+				if(report_item->extended_usage_page != ((usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16)) {
+					return EINVAL;
+				}
+				
 				// usage extended usages
 				report_item->extended_usage_page = (usb_hid_report_tag_data_uint32(data,item_size) & 0xFF00) >> 16; 
@@ -584,4 +611,18 @@
 				report_item->usage_maximum = usb_hid_report_tag_data_uint32(data,item_size);
 			}
+
+			// vlozit zaznamy do pole usages
+			int32_t i;
+			for(i=report_item->usage_minimum; i<=report_item->usage_maximum; i++) {
+				if(report_item->extended_usage_page) {
+					report_item->usages[report_item->usages_count++] = (report_item->extended_usage_page << 16) + i;
+				}
+				else {
+					
+					report_item->usages[report_item->usages_count++] = (report_item->usage_page << 16) + i;
+				}
+			}
+			report_item->extended_usage_page = 0;
+			
 			break;
 		case USB_HID_REPORT_TAG_DESIGNATOR_INDEX:
@@ -663,4 +704,5 @@
 		usb_log_debug("\t\ttUSAGEMIN: %X\n", report_item->usage_minimum);
 		usb_log_debug("\t\tUSAGEMAX: %X\n", report_item->usage_maximum);
+		usb_log_debug("\t\tUSAGES COUNT: %zu\n", report_item->usages_count);
 
 		usb_log_debug("\t\tVALUE: %X\n", report_item->value);
@@ -668,5 +710,5 @@
 		usb_log_debug("\t\tUSAGE PAGE: %X\n", report_item->usage_page);
 		
-		//usb_hid_print_usage_path(report_item->collection_path);
+		usb_hid_print_usage_path(report_item->collection_path);
 
 		usb_log_debug("\n");		
@@ -700,5 +742,5 @@
 		usb_hid_descriptor_print_list(&report_des->report_items);
 
-
+/*
 		link_t *path_it = report->collection_paths.next;
 		while(path_it != &report->collection_paths) {
@@ -706,5 +748,5 @@
 			path_it = path_it->next;
 		}
-		
+*/		
 		report_it = report_it->next;
 	}
Index: uspace/lib/usbhid/src/hidparser.c
===================================================================
--- uspace/lib/usbhid/src/hidparser.c	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/src/hidparser.c	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -69,4 +69,28 @@
 
 
+/** Returns size of report of specified report id and type in items
+ *
+ * @param parser Opaque report parser structure
+ * @param report_id 
+ * @param type
+ * @return Number of items in specified report
+ */
+size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id, 
+                           usb_hid_report_type_t type)
+{
+	usb_hid_report_description_t *report_des;
+
+	if(report == NULL) {
+		return 0;
+	}
+
+	report_des = usb_hid_report_find_description (report, report_id, type);
+	if(report_des == NULL){
+		return 0;
+	}
+	else {
+		return report_des->item_length;
+	}
+}
 
 
@@ -87,5 +111,5 @@
 	usb_hid_report_description_t *report_des;
 	usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
-
+	
 	if(report == NULL) {
 		return EINVAL;
@@ -114,5 +138,15 @@
 				// array
 				item->value = usb_hid_translate_data(item, data);
-			    item->usage = (item->value - item->physical_minimum) + item->usage_minimum;
+		
+				item->usage = USB_HID_EXTENDED_USAGE(item->usages[item->value - item->physical_minimum]);
+				item->usage_page = USB_HID_EXTENDED_USAGE_PAGE(item->usages[item->value - item->physical_minimum]);				
+
+				usb_hid_report_set_last_item (item->collection_path, 
+				                              USB_HID_TAG_CLASS_GLOBAL,
+				                              item->usage_page);
+				usb_hid_report_set_last_item (item->collection_path, 
+				                              USB_HID_TAG_CLASS_LOCAL,
+				                              item->usage);
+				
 			}
 			else {
@@ -123,5 +157,5 @@
 		list_item = list_item->next;
 	}
-	   
+	
 	return EOK;
 	
@@ -206,48 +240,4 @@
 }
 
-/**
- * Returns number of items in input report which are accessible by given usage path
- *
- * @param parser Opaque report descriptor structure
- * @param path Usage path specification
- * @param flags Usage path comparison flags
- * @return Number of items in input report
- */
-size_t usb_hid_report_input_length(const usb_hid_report_t *report,
-	usb_hid_report_path_t *path, int flags)
-{	
-	
-	size_t ret = 0;
-
-	if(report == NULL) {
-		return 0;
-	}
-
-	usb_hid_report_description_t *report_des;
-	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_INPUT);
-	if(report_des == NULL) {
-		return 0;
-	}
-
-	link_t *field_it = report_des->report_items.next;
-	usb_hid_report_field_t *field;
-	while(field_it != &report_des->report_items) {
-
-		field = list_get_instance(field_it, usb_hid_report_field_t, link);
-		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
-			
-			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
-			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
-				ret++;
-			}
-			usb_hid_report_remove_last_item (field->collection_path);
-		}
-		
-		field_it = field_it->next;
-	}
-
-	return ret;
-	}
-
 /*** OUTPUT API **/
 
@@ -304,46 +294,4 @@
 }
 
-/** Returns size of output for given usage path 
- *
- * @param parser Opaque report parser structure
- * @param path Usage path specified which items will be thought for the output
- * @param flags Flags of usage path structure comparison
- * @return Number of items matching the given usage path
- */
-size_t usb_hid_report_output_size(usb_hid_report_t *report,
-                                  usb_hid_report_path_t *path, int flags)
-{
-	size_t ret = 0;	
-	usb_hid_report_description_t *report_des;
-
-	if(report == NULL) {
-		return 0;
-	}
-
-	report_des = usb_hid_report_find_description (report, path->report_id, USB_HID_REPORT_TYPE_OUTPUT);
-	if(report_des == NULL){
-		return 0;
-	}
-	
-	link_t *field_it = report_des->report_items.next;
-	usb_hid_report_field_t *field;
-	while(field_it != &report_des->report_items) {
-
-		field = list_get_instance(field_it, usb_hid_report_field_t, link);
-		if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0){
-			usb_hid_report_path_append_item (field->collection_path, field->usage_page, field->usage);
-			if(usb_hid_report_compare_usage_path (field->collection_path, path, flags) == EOK) {
-				ret++;
-			}
-			usb_hid_report_remove_last_item (field->collection_path);
-		}
-		
-		field_it = field_it->next;
-	}
-
-	return ret;
-	
-}
-
 /** Makes the output report buffer for data given in the report structure
  *
@@ -385,59 +333,60 @@
 		report_item = list_get_instance(item, usb_hid_report_field_t, link);
 
-			if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
+		usb_log_debug("OUTPUT ITEM usage(%x), value(%x)\n", report_item->usage, report_item->value);
+		
+		if(USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags) == 0) {
 					
-				// array
-				value = usb_hid_translate_data_reverse(report_item, report_item->value);
-				offset = report_item->offset;
-				length = report_item->size;
-			}
-			else {
-				// variable item
-				value  = usb_hid_translate_data_reverse(report_item, report_item->value);
-				offset = report_item->offset;
-				length = report_item->size;
-			}
-
-			if((offset/8) == ((offset+length-1)/8)) {
-				// je to v jednom bytu
-				if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
-					break; // TODO ErrorCode
+			// array
+			value = usb_hid_translate_data_reverse(report_item, report_item->value);
+			offset = report_item->offset;
+			length = report_item->size;
+		}
+		else {
+			// variable item
+			value  = usb_hid_translate_data_reverse(report_item, report_item->value);
+			offset = report_item->offset;
+			length = report_item->size;
+		}
+
+		usb_log_debug("\ttranslated value: %x\n", value);
+
+		if((offset/8) == ((offset+length-1)/8)) {
+			// je to v jednom bytu
+			if(((size_t)(offset/8) >= size) || ((size_t)(offset+length-1)/8) >= size) {
+				break; // TODO ErrorCode
+			}
+			size_t shift = 8 - offset%8 - length;
+			value = value << shift;							
+			value = value & (((1 << length)-1) << shift);
+				
+			uint8_t mask = 0;
+			mask = 0xff - (((1 << length) - 1) << shift);
+			buffer[offset/8] = (buffer[offset/8] & mask) | value;
+		}
+		else {
+			int i = 0;
+			uint8_t mask = 0;
+			for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
+				if(i == (offset/8)) {
+					tmp_value = value;
+					tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);				
+					tmp_value = tmp_value << (offset%8);
+	
+					mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
+					buffer[i] = (buffer[i] & mask) | tmp_value;			
 				}
-
-				size_t shift = 8 - offset%8 - length;
-
-				value = value << shift;							
-				value = value & (((1 << length)-1) << shift);
+				else if (i == ((offset + length -1)/8)) {
+					
+					value = value >> (length - ((offset + length) % 8));
+					value = value & ((1 << (length - ((offset + length) % 8))) - 1);
 				
-				uint8_t mask = 0;
-				mask = 0xff - (((1 << length) - 1) << shift);
-				buffer[offset/8] = (buffer[offset/8] & mask) | value;
-			}
-			else {
-				int i = 0;
-				uint8_t mask = 0;
-				for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
-					if(i == (offset/8)) {
-						tmp_value = value;
-						tmp_value = tmp_value & ((1 << (8-(offset%8)))-1);				
-						tmp_value = tmp_value << (offset%8);
-	
-						mask = ~(((1 << (8-(offset%8)))-1) << (offset%8));
-						buffer[i] = (buffer[i] & mask) | tmp_value;			
-					}
-					else if (i == ((offset + length -1)/8)) {
-						
-						value = value >> (length - ((offset + length) % 8));
-						value = value & ((1 << (length - ((offset + length) % 8))) - 1);
-				
-						mask = (1 << (length - ((offset + length) % 8))) - 1;
-						buffer[i] = (buffer[i] & mask) | value;
-					}
-					else {
-						buffer[i] = value & (0xFF << i);
-					}
+					mask = (1 << (length - ((offset + length) % 8))) - 1;
+					buffer[i] = (buffer[i] & mask) | value;
 				}
-			}
-
+				else {
+					buffer[i] = value & (0xFF << i);
+				}
+			}
+		}
 
 		// reset value
@@ -472,34 +421,21 @@
 	}
 	
-
-	if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0)) {
-
-		// variable item
-		if(item->physical_maximum == item->physical_minimum){
-		    resolution = 1;
-		}
-		else {
-		    resolution = (item->logical_maximum - item->logical_minimum) /
-			((item->physical_maximum - item->physical_minimum) *
-			(usb_pow(10,(item->unit_exponent))));
-		}
-
-		ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
-	}
-	else {
-		// bitmapa
-		if(value == 0) {
-			ret = 0;
-		}
-		else {
-			size_t bitmap_idx = (value - item->usage_minimum);
-			ret = 1 << bitmap_idx;
-		}
-	}
-
+	// variable item
+	if(item->physical_maximum == item->physical_minimum){
+	    resolution = 1;
+	}
+	else {
+	    resolution = (item->logical_maximum - item->logical_minimum) /
+		((item->physical_maximum - item->physical_minimum) *
+		(usb_pow(10,(item->unit_exponent))));
+	}
+
+	ret = ((value - item->physical_minimum) * resolution) + item->logical_minimum;
+	usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), ret(%x)\n", value, resolution, item->physical_minimum, item->logical_minimum, ret);
+	
 	if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
 		return USB_HID_INT32_TO_UINT32(ret, item->size);
 	}
-	return (int32_t)ret;
+	return (int32_t)0 + ret;
 }
 
Index: uspace/lib/usbhid/src/hidpath.c
===================================================================
--- uspace/lib/usbhid/src/hidpath.c	(revision 9e195e2cd2e7af9bd0b0ef0bde139dac93b3f53f)
+++ uspace/lib/usbhid/src/hidpath.c	(revision df44fa2ce2cd4c6a7125a389be0292b42d1d62b3)
@@ -42,4 +42,7 @@
 
 
+#define USB_HID_SAME_USAGE(usage1, usage2)	((usage1 == usage2) || (usage1 == 0) || (usage2 == 0))
+#define USB_HID_SAME_USAGE_PAGE(page1, page2)	((page1 == page2) || (page1 == 0) || (page2 == 0))
+
 /**
  * Appends one item (couple of usage_path and usage) into the usage path
@@ -203,7 +206,7 @@
 			while(report_link != &report_path->head) {
 				report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
-				if(report_item->usage_page == path_item->usage_page){
+				if(USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page)){
 					if(only_page == 0){
-						if(report_item->usage == path_item->usage) {
+						if(USB_HID_SAME_USAGE(report_item->usage, path_item->usage)) {
 							return EOK;
 						}
@@ -242,7 +245,7 @@
 					                              link);		
 
-					if((report_item->usage_page != path_item->usage_page) || 
+					if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) || 
 					   ((only_page == 0) && 
-					    (report_item->usage != path_item->usage))) {
+					    !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) {
 							
 						   return 1;
@@ -282,9 +285,9 @@
 					                              usb_hid_report_usage_path_t, 
 					                              link);		
-
-					if((report_item->usage_page != path_item->usage_page) || 
+						  
+					if(!USB_HID_SAME_USAGE_PAGE(report_item->usage_page, path_item->usage_page) || 
 					   ((only_page == 0) && 
-					    (report_item->usage != path_item->usage))) {
-						   return 1;
+					    !USB_HID_SAME_USAGE(report_item->usage, path_item->usage))) {
+							return 1;
 					} else {
 						report_link = report_link->prev;
