Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision a9974eff3f81a6e4dea2168b45787b67b74ac0bb)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision 64dbc83fa8ed981c2a200fd6643bc95dbe0bfc47)
@@ -92,4 +92,5 @@
 	/** */	
 	link_t link;
+
 } usb_hid_report_path_t;
 
@@ -158,5 +159,7 @@
 	
 	int use_report_id;
-	
+
+	/** */
+ 	link_t stack;
 } usb_hid_report_parser_t;	
 
Index: uspace/lib/usb/src/hidparser.c
===================================================================
--- uspace/lib/usb/src/hidparser.c	(revision a9974eff3f81a6e4dea2168b45787b67b74ac0bb)
+++ uspace/lib/usb/src/hidparser.c	(revision 64dbc83fa8ed981c2a200fd6643bc95dbe0bfc47)
@@ -64,5 +64,5 @@
 int usb_hid_report_reset_local_items();
 void usb_hid_free_report_list(link_t *head);
-
+usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
 /*
  * Data translation private functions
@@ -105,4 +105,6 @@
     list_initialize(&(parser->output));
     list_initialize(&(parser->feature));
+
+	list_initialize(&(parser->stack));
 
 	parser->use_report_id = 0;
@@ -222,9 +224,9 @@
 					}					
 					memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
+					link_initialize(&(new_report_item->link));
 					
 					/* reset local items */
 					new_report_item->usage_minimum = 0;
 					new_report_item->usage_maximum = 0;
-					new_report_item->usage = 0;
 					new_report_item->designator_index = 0;
 					new_report_item->designator_minimum = 0;
@@ -232,7 +234,10 @@
 					new_report_item->string_index = 0;
 					new_report_item->string_minimum = 0;
-					new_report_item->string_maximum = 0;										
+					new_report_item->string_maximum = 0;
+
+					/* reset usage from current usage path */
+					usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link);
+					path->usage = 0;
 					
-					link_initialize(&(new_report_item->link));
 					report_item = new_report_item;
 										
@@ -240,9 +245,17 @@
 				case USB_HID_REPORT_TAG_PUSH:
 					// push current state to stack
-					// not yet implemented
+					new_report_item = usb_hid_report_item_clone(report_item);
+					list_prepend (&parser->stack, &new_report_item->link);
+					
 					break;
 				case USB_HID_REPORT_TAG_POP:
 					// restore current state from stack
-					// not yet implemented						   
+					if(list_empty (&parser->stack)) {
+						return EINVAL;
+					}
+					
+					report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link);
+					list_remove (parser->stack.next);
+					
 					break;
 					
@@ -1371,4 +1384,18 @@
 }
 
+
+usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
+{
+	usb_hid_report_item_t *new_report_item;
+	
+	if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
+		return NULL;
+	}					
+	memcpy(new_report_item,item, sizeof(usb_hid_report_item_t));
+	link_initialize(&(new_report_item->link));
+
+	return new_report_item;
+}
+
 /**
  * @}
