Index: uspace/lib/usb/include/usb/classes/hidparser.h
===================================================================
--- uspace/lib/usb/include/usb/classes/hidparser.h	(revision f8e8738d31d2b92e00a460fe812bda69bfb6ef51)
+++ uspace/lib/usb/include/usb/classes/hidparser.h	(revision fee6381880e50fadeff5f754a7e4305789512c34)
@@ -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 f8e8738d31d2b92e00a460fe812bda69bfb6ef51)
+++ uspace/lib/usb/src/hidparser.c	(revision fee6381880e50fadeff5f754a7e4305789512c34)
@@ -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;
@@ -220,11 +222,22 @@
 					if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
 						return ENOMEM;
-					}
+					}					
 					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->designator_index = 0;
+					new_report_item->designator_minimum = 0;
+					new_report_item->designator_maximum = 0;
+					new_report_item->string_index = 0;
+					new_report_item->string_minimum = 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;
 										
@@ -232,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;
 					
@@ -1363,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;
+}
+
 /**
  * @}
