Index: uspace/drv/usbhid/kbd/conv.c
===================================================================
--- uspace/drv/usbhid/kbd/conv.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/kbd/conv.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -99,5 +99,6 @@
 	[0x30] = KC_RBRACKET,
 	[0x31] = KC_BACKSLASH,
-	//[0x32] = KC_,	// TODO: HASH??? maybe some as 0x31 - backslash
+	//[0x32] = KC_,	// TODO: HASH??? maybe same as 0x31 - backslash
+	[0x32] = KC_BACKSLASH,
 	[0x33] = KC_SEMICOLON,
 	[0x34] = KC_QUOTE,  // same as APOSTROPHE? (')
Index: uspace/drv/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/kbd/kbddev.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -177,10 +177,10 @@
 /*----------------------------------------------------------------------------*/
 
-static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
-    uint8_t report_id, void *arg);
-
-static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
-	.keyboard = usb_kbd_process_keycodes
-};
+//static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
+//    uint8_t report_id, void *arg);
+
+//static const usb_hid_report_in_callbacks_t usb_kbd_parser_callbacks = {
+//	.keyboard = usb_kbd_process_keycodes
+//};
 
 /*----------------------------------------------------------------------------*/
@@ -299,32 +299,39 @@
 		return;
 	}
-	
-	unsigned i = 0;
-	
+		
 	/* Reset the LED data. */
 	memset(kbd_dev->led_data, 0, kbd_dev->led_output_size * sizeof(int32_t));
-	
-	if ((kbd_dev->mods & KM_NUM_LOCK) && (i < kbd_dev->led_output_size)) {
-		kbd_dev->led_data[i++] = USB_HID_LED_NUM_LOCK;
-	}
-	
-	if ((kbd_dev->mods & KM_CAPS_LOCK) && (i < kbd_dev->led_output_size)) {
-		kbd_dev->led_data[i++] = USB_HID_LED_CAPS_LOCK;
-	}
-	
-	if ((kbd_dev->mods & KM_SCROLL_LOCK) 
-	    && (i < kbd_dev->led_output_size)) {
-		kbd_dev->led_data[i++] = USB_HID_LED_SCROLL_LOCK;
-	}
-
-	// TODO: COMPOSE and KANA
-	
-	usb_log_debug("Creating output report.\n");
-	
-	int rc = usb_hid_report_output_translate(hid_dev->parser, 
-	    kbd_dev->led_path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-	    kbd_dev->output_buffer, 
-	    kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
+	usb_log_debug("Creating output report:\n");
+
+	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, kbd_dev->led_path, 
+	    USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY | USB_HID_PATH_COMPARE_END,
+	    USB_HID_REPORT_TYPE_OUTPUT);
+	
+	while (field != NULL) {
+
+		if ((field->usage == USB_HID_LED_NUM_LOCK) 
+		    && (kbd_dev->mods & KM_NUM_LOCK)){
+			field->value = 1;
+		}
+
+		if ((field->usage == USB_HID_LED_CAPS_LOCK) 
+		    && (kbd_dev->mods & KM_CAPS_LOCK)){
+			field->value = 1;
+		}
+
+		if ((field->usage == USB_HID_LED_SCROLL_LOCK) 
+		    && (kbd_dev->mods & KM_SCROLL_LOCK)){
+			field->value = 1;
+		}
+		
+		field = usb_hid_report_get_sibling(hid_dev->report, field,
+		    kbd_dev->led_path, USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 
+		    | USB_HID_PATH_COMPARE_END, USB_HID_REPORT_TYPE_OUTPUT);
+	}
+	
+	// TODO: what about the Report ID?
+	int rc = usb_hid_report_output_translate(hid_dev->report, 0,
+	    kbd_dev->output_buffer, kbd_dev->output_size);
 	
 	if (rc != EOK) {
@@ -485,5 +492,5 @@
  */
 static void usb_kbd_check_key_changes(usb_hid_dev_t *hid_dev, 
-    usb_kbd_t *kbd_dev, const uint8_t *key_codes, size_t count)
+    usb_kbd_t *kbd_dev/*, const uint8_t *key_codes, size_t count*/)
 {
 	unsigned int key;
@@ -499,30 +506,27 @@
 	 */
 	i = 0;
-	while (i < count && key_codes[i] != ERROR_ROLLOVER) {
+	while (i < kbd_dev->key_count && kbd_dev->keys[i] != ERROR_ROLLOVER) {
 		++i;
 	}
-	if (i != count) {
+	if (i != kbd_dev->key_count) {
 		usb_log_debug("Phantom state occured.\n");
 		// phantom state, do nothing
 		return;
 	}
-	
-	/* TODO: quite dummy right now, think of better implementation */
-	assert(count == kbd_dev->key_count);
 	
 	/*
 	 * 1) Key releases
 	 */
-	for (j = 0; j < count; ++j) {
+	for (j = 0; j < kbd_dev->key_count; ++j) {
 		// try to find the old key in the new key list
 		i = 0;
 		while (i < kbd_dev->key_count
-		    && key_codes[i] != kbd_dev->keys[j]) {
+		    && kbd_dev->keys[i] != kbd_dev->keys_old[j]) {
 			++i;
 		}
 		
-		if (i == count) {
+		if (i == kbd_dev->key_count) {
 			// not found, i.e. the key was released
-			key = usbhid_parse_scancode(kbd_dev->keys[j]);
+			key = usbhid_parse_scancode(kbd_dev->keys_old[j]);
 			if (!usb_kbd_is_lock(key)) {
 				usb_kbd_repeat_stop(kbd_dev, key);
@@ -541,15 +545,15 @@
 		// try to find the new key in the old key list
 		j = 0;
-		while (j < count && kbd_dev->keys[j] != key_codes[i]) { 
+		while (j < kbd_dev->key_count 
+		    && kbd_dev->keys_old[j] != kbd_dev->keys[i]) { 
 			++j;
 		}
 		
-		if (j == count) {
+		if (j == kbd_dev->key_count) {
 			// not found, i.e. new key pressed
-			key = usbhid_parse_scancode(key_codes[i]);
+			key = usbhid_parse_scancode(kbd_dev->keys[i]);
 			usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
-			    key_codes[i]);
-			usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, 
-			    key);
+			    kbd_dev->keys[i]);
+			usb_kbd_push_ev(hid_dev, kbd_dev, KEY_PRESS, key);
 			if (!usb_kbd_is_lock(key)) {
 				usb_kbd_repeat_start(kbd_dev, key);
@@ -560,8 +564,24 @@
 	}
 	
-	memcpy(kbd_dev->keys, key_codes, count);
-
-	usb_log_debug("New stored keycodes: %s\n", 
-	    usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
+//	usb_log_debug("Old keys: ");
+//	for (i = 0; i < kbd_dev->key_count; ++i) {
+//		usb_log_debug("%d ", kbd_dev->keys_old[i]);
+//	}
+//	usb_log_debug("\n");
+	
+	
+//	usb_log_debug("New keys: ");
+//	for (i = 0; i < kbd_dev->key_count; ++i) {
+//		usb_log_debug("%d ", kbd_dev->keys[i]);
+//	}
+//	usb_log_debug("\n");
+	
+	memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
+	
+	usb_log_debug2("New stored keys: ");
+	for (i = 0; i < kbd_dev->key_count; ++i) {
+		usb_log_debug2("%d ", kbd_dev->keys_old[i]);
+	}
+	usb_log_debug2("\n");
 }
 
@@ -585,34 +605,34 @@
  * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes()
  */
-static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
-    uint8_t report_id, void *arg)
-{
-	if (arg == NULL) {
-		usb_log_warning("Missing argument in callback "
-		    "usbhid_process_keycodes().\n");
-		return;
-	}
-	
-	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
-	
-	if (hid_dev->data == NULL) {
-		usb_log_warning("Missing KBD device structure in callback.\n");
-		return;
-	}
-	
-	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
-
-	usb_log_debug("Got keys from parser (report id: %u): %s\n", 
-	    report_id, usb_debug_str_buffer(key_codes, count, 0));
-	
-	if (count != kbd_dev->key_count) {
-		usb_log_warning("Number of received keycodes (%zu) differs from"
-		    " expected (%zu).\n", count, kbd_dev->key_count);
-		return;
-	}
-	
-	///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
-	usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
-}
+//static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
+//    uint8_t report_id, void *arg)
+//{
+//	if (arg == NULL) {
+//		usb_log_warning("Missing argument in callback "
+//		    "usbhid_process_keycodes().\n");
+//		return;
+//	}
+	
+//	usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
+	
+//	if (hid_dev->data == NULL) {
+//		usb_log_warning("Missing KBD device structure in callback.\n");
+//		return;
+//	}
+	
+//	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
+
+//	usb_log_debug("Got keys from parser (report id: %u): %s\n", 
+//	    report_id, usb_debug_str_buffer(key_codes, count, 0));
+	
+//	if (count != kbd_dev->key_count) {
+//		usb_log_warning("Number of received keycodes (%zu) differs from"
+//		    " expected (%zu).\n", count, kbd_dev->key_count);
+//		return;
+//	}
+	
+//	///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
+//	usb_kbd_check_key_changes(hid_dev, kbd_dev, key_codes, count);
+//}
 
 /*----------------------------------------------------------------------------*/
@@ -638,5 +658,9 @@
                                  uint8_t *buffer, size_t actual_size)
 {
-	assert(hid_dev->parser != NULL);
+	assert(hid_dev->report != NULL);
+	assert(hid_dev != NULL);
+	assert(hid_dev->data != NULL);
+	
+	usb_kbd_t *kbd_dev = (usb_kbd_t *)hid_dev->data;
 
 	usb_log_debug("Calling usb_hid_parse_report() with "
@@ -648,16 +672,59 @@
 	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
 	//usb_hid_report_path_set_report_id(path, 0);
-	
-	int rc = usb_hid_parse_report(hid_dev->parser, buffer,
-	    actual_size, path, 
+
+	uint8_t report_id;
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, actual_size, 
+	    &report_id);
+	
+	if (rc != EOK) {
+		usb_log_warning("Error in usb_hid_parse_report():"
+		    "%s\n", str_error(rc));
+	}
+	
+	usb_hid_report_path_set_report_id (path, report_id);
+	
+	// fill in the currently pressed keys
+	
+	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, path, 
 	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-	    &usb_kbd_parser_callbacks, hid_dev);
-
+	    USB_HID_REPORT_TYPE_INPUT);
+	unsigned i = 0;
+	
+	while (field != NULL) {
+		usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", 
+		    field, field->value, field->usage);
+		
+		assert(i < kbd_dev->key_count);
+//		if (i == kbd_dev->key_count) {
+//			break;
+//		}
+		
+		// save the key usage
+		/* TODO: maybe it's not good to save value, nor usage
+		 *       as the value may be e.g. 1 for LEDs and usage may be
+		 *       value of the LED. On the other hand, in case of normal
+		 *       keys, the usage is more important and we must check
+		 *       that. One possible solution: distinguish between those
+		 *       two parts of the Report somehow.
+		 */
+		if( field->value != 0 ) {
+			kbd_dev->keys[i] = field->usage;
+		}
+		else {
+			kbd_dev->keys[i] = 0;
+		}
+		usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]);
+		
+		++i;
+		field = usb_hid_report_get_sibling(hid_dev->report, field, path, 
+		    USB_HID_PATH_COMPARE_END 
+		    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
+		    USB_HID_REPORT_TYPE_INPUT);
+	}
+	
 	usb_hid_report_path_free(path);
 	
-	if (rc != EOK) {
-		usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
-		    "%s\n", str_error(rc));
-	}
+	usb_kbd_check_key_changes(hid_dev, kbd_dev);
 }
 
@@ -747,5 +814,5 @@
 	
 	kbd_dev->key_count = usb_hid_report_input_length(
-	    hid_dev->parser, path, 
+	    hid_dev->report, path, 
 	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
 	usb_hid_report_path_free(path);
@@ -753,5 +820,5 @@
 	usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
 	
-	kbd_dev->keys = (uint8_t *)calloc(kbd_dev->key_count, sizeof(uint8_t));
+	kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
 	
 	if (kbd_dev->keys == NULL) {
@@ -761,15 +828,24 @@
 	}
 	
+	kbd_dev->keys_old = 
+		(int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
+	
+	if (kbd_dev->keys_old == NULL) {
+		usb_log_fatal("No memory!\n");
+		free(kbd_dev->keys);
+		free(kbd_dev);
+		return ENOMEM;
+	}
+	
 	/*
 	 * Output report
 	 */
 	kbd_dev->output_size = 0;
-	kbd_dev->output_buffer = usb_hid_report_output(hid_dev->parser, 
-	    &kbd_dev->output_size);
-	if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {
+	kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report, 
+	    &kbd_dev->output_size, 0);
+	if (kbd_dev->output_buffer == NULL) {
 		usb_log_warning("Error creating output report buffer.\n");
 		free(kbd_dev->keys);
-		free(kbd_dev);
-		return ENOMEM;
+		return ENOMEM;  /* TODO: other error code */
 	}
 	
@@ -780,5 +856,5 @@
 	    kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
 	
-	kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->parser, 
+	kbd_dev->led_output_size = usb_hid_report_output_size(hid_dev->report, 
 	    kbd_dev->led_path, 
 	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
@@ -937,5 +1013,5 @@
 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
 {
-	int rc = usb_hid_parse_report_descriptor(hid_dev->parser, 
+	int rc = usb_hid_parse_report_descriptor(hid_dev->report, 
 	    USB_KBD_BOOT_REPORT_DESCRIPTOR, 
 	    USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
Index: uspace/drv/usbhid/kbd/kbddev.h
===================================================================
--- uspace/drv/usbhid/kbd/kbddev.h	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/kbd/kbddev.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -65,6 +65,8 @@
  */
 typedef struct usb_kbd_t {
+	/** Previously pressed keys (not translated to key codes). */
+	int32_t *keys_old;
 	/** Currently pressed keys (not translated to key codes). */
-	uint8_t *keys;
+	int32_t *keys;
 	/** Count of stored keys (i.e. number of keys in the report). */
 	size_t key_count;
Index: uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c
===================================================================
--- uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/lgtch-ultrax/lgtch-ultrax.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -81,15 +81,25 @@
 	usb_hid_report_path_t *path = usb_hid_report_path();
 	usb_hid_report_path_append_item(path, 0xc, 0);
-	usb_hid_report_path_set_report_id(path, 1);
+
+	uint8_t report_id;
 	
-	int rc = usb_hid_parse_report(hid_dev->parser, buffer,
-	    buffer_size, path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-	    &usb_lgtch_parser_callbacks, hid_dev);
+	int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 
+	    &report_id);
+	usb_hid_report_path_set_report_id(path, report_id);
+
+	usb_hid_report_field_t *field = usb_hid_report_get_sibling(
+	    hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END , 
+	    USB_HID_REPORT_TYPE_INPUT);
+	
+	while (field != NULL) {
+		usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", field->value, 
+		    field->usage);
+	}
+	
 
 	usb_hid_report_path_free(path);
 	
 	if (rc != EOK) {
-		usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
+		usb_log_warning(NAME "Error in usb_hid_boot_keyboard_input_report():"
 		    "%s\n", str_error(rc));
 	}
Index: uspace/drv/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/usbhid/mouse/mousedev.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/mouse/mousedev.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -296,5 +296,5 @@
 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
 {
-	int rc = usb_hid_parse_report_descriptor(hid_dev->parser, 
+	int rc = usb_hid_parse_report_descriptor(hid_dev->report, 
 	    USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 
 	    USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
Index: uspace/drv/usbhid/subdrivers.c
===================================================================
--- uspace/drv/usbhid/subdrivers.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/subdrivers.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -55,6 +55,6 @@
 		USB_HID_PATH_COMPARE_END 
 		| USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
-		0,
-		0,
+		-1,
+		-1,
 		{
 			.init = usb_kbd_init,
@@ -79,5 +79,5 @@
 		}
 	},
-	{NULL, -1, 0, 0, 0, {NULL, NULL, NULL, NULL}}
+	{NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL}}
 };
 
Index: uspace/drv/usbhid/subdrivers.h
===================================================================
--- uspace/drv/usbhid/subdrivers.h	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/subdrivers.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -56,6 +56,6 @@
 	int report_id;
 	int compare;
-	uint16_t vendor_id;
-	uint16_t product_id;
+	int vendor_id;
+	int product_id;
 	usb_hid_subdriver_t subdriver;
 } usb_hid_subdriver_mapping_t;
Index: uspace/drv/usbhid/usbhid.c
===================================================================
--- uspace/drv/usbhid/usbhid.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/usbhid.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -158,5 +158,11 @@
     const usb_hid_subdriver_mapping_t *mapping)
 {
-	return false;
+	assert(hid_dev != NULL);
+	assert(hid_dev->usb_dev != NULL);
+	
+	return (hid_dev->usb_dev->descriptors.device.vendor_id 
+	    == mapping->vendor_id
+	    && hid_dev->usb_dev->descriptors.device.product_id 
+	    == mapping->product_id);
 }
 
@@ -192,8 +198,8 @@
 	}
 	
-	assert(hid_dev->parser != NULL);
+	assert(hid_dev->report != NULL);
 	
 	usb_log_debug("Compare flags: %d\n", mapping->compare);
-	size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path, 
+	size_t size = usb_hid_report_input_length(hid_dev->report, usage_path, 
 	    mapping->compare);
 	usb_log_debug("Size of the input report: %zuB\n", size);
@@ -251,13 +257,13 @@
 	while (count < USB_HID_MAX_SUBDRIVERS &&
 	    (mapping->usage_path != NULL
-	    || mapping->vendor_id != 0 || mapping->product_id != 0)) {
+	    || mapping->vendor_id >= 0 || mapping->product_id >= 0)) {
 		// check the vendor & product ID
-		if (mapping->vendor_id != 0 && mapping->product_id == 0) {
-			usb_log_warning("Missing Product ID for Vendor ID %u\n",
+		if (mapping->vendor_id >= 0 && mapping->product_id < 0) {
+			usb_log_warning("Missing Product ID for Vendor ID %d\n",
 			    mapping->vendor_id);
 			return EINVAL;
 		}
-		if (mapping->product_id != 0 && mapping->vendor_id == 0) {
-			usb_log_warning("Missing Vendor ID for Product ID %u\n",
+		if (mapping->product_id >= 0 && mapping->vendor_id < 0) {
+			usb_log_warning("Missing Vendor ID for Product ID %d\n",
 			    mapping->product_id);
 			return EINVAL;
@@ -267,6 +273,6 @@
 		matched = false;
 		
-		if (mapping->vendor_id != 0) {
-			assert(mapping->product_id != 0);
+		if (mapping->vendor_id >= 0) {
+			assert(mapping->product_id >= 0);
 			usb_log_debug("Comparing device against vendor ID %u"
 			    " and product ID %u.\n", mapping->vendor_id,
@@ -341,7 +347,7 @@
 	}
 	
-	hid_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
-	    usb_hid_report_parser_t)));
-	if (hid_dev->parser == NULL) {
+	hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
+	    usb_hid_report_t)));
+	if (hid_dev->report == NULL) {
 		usb_log_fatal("No memory!\n");
 		free(hid_dev);
@@ -382,16 +388,8 @@
 		return rc;
 	}
-	
-	/* Initialize the report parser. */
-	rc = usb_hid_parser_init(hid_dev->parser);
-	if (rc != EOK) {
-		usb_log_error("Failed to initialize report parser.\n");
-		//usb_hid_free(&hid_dev);
-		return rc;
-	}
-	
+		
 	/* Get the report descriptor and parse it. */
 	rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 
-	    hid_dev->parser);
+	    hid_dev->report);
 	
 	bool fallback = false;
@@ -591,6 +589,6 @@
 
 	// destroy the parser
-	if ((*hid_dev)->parser != NULL) {
-		usb_hid_free_report_parser((*hid_dev)->parser);
+	if ((*hid_dev)->report != NULL) {
+		usb_hid_free_report((*hid_dev)->report);
 	}
 
Index: uspace/drv/usbhid/usbhid.h
===================================================================
--- uspace/drv/usbhid/usbhid.h	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbhid/usbhid.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -91,5 +91,5 @@
 	
 	/** HID Report parser. */
-	usb_hid_report_parser_t *parser;
+	usb_hid_report_t *report;
 	
 	/** Arbitrary data (e.g. a special structure for handling keyboard). */
Index: uspace/drv/usbkbd/kbddev.c
===================================================================
--- uspace/drv/usbkbd/kbddev.c	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbkbd/kbddev.c	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -128,7 +128,10 @@
         0x15, 0x00,  //   Logical Minimum (0),
         0x25, 0x01,  //   Logical Maximum (1),
+	//0x85, 0x00,  //   Report ID,
+	//0xA4,	     //   Push
         0x81, 0x02,  //   Input (Data, Variable, Absolute),   ; Modifier byte
-	0x95, 0x01,  //   Report Count (1),
-        0x75, 0x08,  //   Report Size (8),
+	//0xB4,	     //   Pop
+        0x75, 0x08,  //   Report Size (1),
+        0x95, 0x01,  //   Report Count (8),       
         0x81, 0x01,  //   Input (Constant),                   ; Reserved byte
         0x95, 0x05,  //   Report Count (5),
@@ -268,5 +271,5 @@
 		return;
 	}
-	
+
 	unsigned i = 0;
 	
@@ -290,10 +293,10 @@
 	
 	usb_log_debug("Creating output report.\n");
-	
-	int rc = usb_hid_report_output_translate(kbd_dev->parser, 
-	    kbd_dev->led_path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-	    kbd_dev->output_buffer, 
-	    kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
+
+	usb_hid_report_output_set_data(kbd_dev->parser, kbd_dev->led_path, 
+	                               USB_HID_PATH_COMPARE_END , kbd_dev->led_data, 
+	                               kbd_dev->led_output_size);
+	int rc = usb_hid_report_output_translate(kbd_dev->parser, 0,
+	    kbd_dev->output_buffer, kbd_dev->output_size);
 	
 	if (rc != EOK) {
@@ -563,6 +566,6 @@
 	assert(kbd_dev != NULL);
 
-	usb_log_debug("Got keys from parser (report id: %u): %s\n", 
-	    report_id, usb_debug_str_buffer(key_codes, count, 0));
+	usb_log_debug("Got keys from parser (report id: %d): %s\n", report_id, 
+	    usb_debug_str_buffer(key_codes, count, 0));
 	
 	if (count != kbd_dev->key_count) {
@@ -614,10 +617,8 @@
 	usb_hid_report_path_t *path = usb_hid_report_path();
 	usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
-	usb_hid_report_path_set_report_id(path, 0);
-	
-	int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
-	    actual_size, path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
-	    callbacks, kbd_dev);
+
+	uint8_t report_id;
+	int rc = usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, &report_id);
+	usb_hid_descriptor_print (kbd_dev->parser);
 
 	usb_hid_report_path_free (path);
@@ -663,6 +664,6 @@
 	memset(kbd_dev, 0, sizeof(usb_kbd_t));
 	
-	kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
-	    usb_hid_report_parser_t)));
+	kbd_dev->parser = (usb_hid_report_t *)(malloc(sizeof(
+	    usb_hid_report_t)));
 	if (kbd_dev->parser == NULL) {
 		usb_log_fatal("No memory!\n");
@@ -732,9 +733,9 @@
 	
 	/* Initialize the report parser. */
-	rc = usb_hid_parser_init(kbd_dev->parser);
-	if (rc != EOK) {
-		usb_log_error("Failed to initialize report parser.\n");
-		return rc;
-	}
+	//rc = usb_hid_parser_init(kbd_dev->parser);
+	//if (rc != EOK) {
+	//	usb_log_error("Failed to initialize report parser.\n");
+	//	return rc;
+	//}
 	
 	/* Get the report descriptor and parse it. */
@@ -771,6 +772,5 @@
 	
 	kbd_dev->key_count = usb_hid_report_input_length(
-	    kbd_dev->parser, path, 
-	    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
+	    kbd_dev->parser, path, USB_HID_PATH_COMPARE_END);
 	usb_hid_report_path_free (path);
 	
@@ -789,6 +789,6 @@
 	kbd_dev->output_size = 0;
 	kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser, 
-	    &kbd_dev->output_size);
-	if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {
+	    &kbd_dev->output_size, 0x00);
+	if (kbd_dev->output_buffer == NULL) {
 		usb_log_warning("Error creating output report buffer.\n");
 		free(kbd_dev->keys);
@@ -801,4 +801,5 @@
 	usb_hid_report_path_append_item(
 	    kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
+	usb_hid_report_path_set_report_id(kbd_dev->led_path, 0x00);
 	
 	kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser, 
@@ -849,5 +850,5 @@
 	 * Set Idle rate
 	 */
-	usb_kbd_set_led(kbd_dev);
+	usb_kbd_set_led(kbd_dev);	
 	
 	usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe, 
@@ -934,5 +935,5 @@
 	// destroy the parser
 	if ((*kbd_dev)->parser != NULL) {
-		usb_hid_free_report_parser((*kbd_dev)->parser);
+		usb_hid_free_report((*kbd_dev)->parser);
 	}
 	
Index: uspace/drv/usbkbd/kbddev.h
===================================================================
--- uspace/drv/usbkbd/kbddev.h	(revision 564a2b33fa6a9365cde0a9228b5722048647e566)
+++ uspace/drv/usbkbd/kbddev.h	(revision 308a5d52410eedc0ee1ce72952d26a931def9c82)
@@ -106,5 +106,5 @@
 
 	/** HID Report parser. */
-	usb_hid_report_parser_t *parser;
+	usb_hid_report_t *parser;
 	
 	/** State of the structure (for checking before use). 
