Index: source/creator/creator.c
===================================================================
--- source/creator/creator.c	(revision 39541)
+++ source/creator/creator.c	(working copy)
@@ -258,6 +258,7 @@
 	printf ("Misc Options:\n");
 	BLI_argsPrintArgDoc(ba, "--debug");
 	BLI_argsPrintArgDoc(ba, "--debug-fpe");
+	BLI_argsPrintArgDoc(ba, "--instrument"); /* pkhg */
 	printf("\n");
 	BLI_argsPrintArgDoc(ba, "--factory-startup");
 	printf("\n");
@@ -377,6 +378,14 @@
 	return 0;
 }
 
+static int instr_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
+{
+	printf("INSTRUMENTING!!!\n");
+	G.f |= G_INSTR;
+	return 0;
+}
+
+
 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
 {
 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
@@ -1057,6 +1066,11 @@
 		"\n\t* Prints every operator call and their arguments"
 		"\n\t* Disables mouse grab (to interact with a debugger in some cases)"
 		"\n\t* Keeps python sys.stdin rather than setting it to None";
+	/* pkhg */
+	static char instr_doc[] = "\n\tTurn instrumentation on\n"
+		"\n\t* Writes almost every action to ./steps.txt"
+		"\n\t* Writes a corresponding snapshot to step\%06d.blend"
+		"\n\t* The current count of steps is written to stepcount.txt";
 
 	//BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
 
@@ -1091,6 +1105,8 @@
 
 	BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
 	BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
+	/*pkhg*/
+        BLI_argsAdd(ba, 1, NULL, "--instrument", instr_doc, instr_mode, ba);
 
 	BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
 
Index: source/blender/blenkernel/intern/blender.c
===================================================================
--- source/blender/blenkernel/intern/blender.c	(revision 39541)
+++ source/blender/blenkernel/intern/blender.c	(working copy)
@@ -278,7 +278,9 @@
 
 	/* special cases, override loaded flags: */
 	if(G.f != bfd->globalf) {
-		const int flags_keep= (G_DEBUG | G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF);
+	  /*orig		const int flags_keep= (G_DEBUG | G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF);
+	   */
+		const int flags_keep= (G_DEBUG | G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF | G_INSTR);
 		bfd->globalf= (bfd->globalf & ~flags_keep) | (G.f & flags_keep);
 	}
 
Index: source/blender/blenkernel/BKE_global.h
===================================================================
--- source/blender/blenkernel/BKE_global.h	(revision 39541)
+++ source/blender/blenkernel/BKE_global.h	(working copy)
@@ -105,7 +105,7 @@
 #define G_PICKSEL		(1 <<  5)
 
 /* #define G_FACESELECT	(1 <<  8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
-
+#define G_INSTR         (1 << 9) /*pkhg*/
 #define G_DEBUG			(1 << 12)
 #define G_SCRIPT_AUTOEXEC (1 << 13)
 #define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
Index: source/blender/windowmanager/intern/wm_files.c
===================================================================
--- source/blender/windowmanager/intern/wm_files.c	(revision 39541)
+++ source/blender/windowmanager/intern/wm_files.c	(working copy)
@@ -117,7 +117,10 @@
 #include "wm_files.h"
 #include "wm_window.h"
 #include "wm_event_system.h"
-
+/*pkhg*/
+#include <sys/time.h>
+/*pkhg*/
+int takingsnapshot = 0;
 static void write_history(void);
 
 /* To be able to read files without windows closing, opening, moving 
@@ -697,6 +700,53 @@
 	}
 }
 
+void snapshot(bContext *C, char *buf)
+{
+  /*pkhg ??? here?*/
+        struct timeval nowTime;
+	static int snapshot = -1;
+	char filename[256];
+	FILE *fp;
+	ReportList rp;
+
+	if( strcmp( buf, "bpy.ops.info.reports_display_update()" ) == 0 ) return;
+
+	if( snapshot < 0 )
+	{
+		fp=fopen("stepcount.txt","r");
+		if( fp == 0 ) snapshot = 0;
+		else
+		{
+			fscanf(fp,"%d",&snapshot);
+			fclose(fp);
+		}
+	}
+
+	sprintf( filename, "step%06d.blend", snapshot );
+	printf("%s: %s\n", filename, buf);
+	takingsnapshot = 1;
+	WM_write_file( C, filename, G_FILE_COMPRESS, &rp, 1 );
+	takingsnapshot = 0;
+
+	fp=fopen("steps.txt","a");
+	fprintf(fp,"%s: %s\n", filename, buf);
+	fclose(fp);
+	
+	/*error pkhg 	struct timeval nowTime; */
+	gettimeofday(&nowTime, NULL);
+	fp=fopen("steptimes.txt","a");
+	fprintf(fp,"%ld:%06ld\n", nowTime.tv_sec, nowTime.tv_usec );
+	fclose(fp);
+	
+	snapshot++;
+	fp=fopen("stepcount.txt","w");
+	fprintf(fp,"%d\n", snapshot);
+	fclose(fp);
+
+	fflush(stdout);
+}
+
+
 int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *reports, int copy)
 {
 	Library *li;
@@ -733,7 +783,8 @@
 	/* blend file thumbnail */
 	/* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */
 	if(U.flag & USER_SAVE_PREVIEWS) {
-		ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb);
+	  if( !takingsnapshot ) /*pkhg ok question ?????*/
+	    ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb);
 	}
 
 	BLI_exec_cb(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
Index: source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- source/blender/windowmanager/intern/wm_event_system.c	(revision 39541)
+++ source/blender/windowmanager/intern/wm_event_system.c	(working copy)
@@ -444,6 +444,13 @@
 	if(retval & OPERATOR_FINISHED) {
 		if(G.f & G_DEBUG)
 			wm_operator_print(C, op); /* todo - this print may double up, might want to check more flags then the FINISHED */
+
+		if(G.f & G_INSTR)
+		{
+			char *buf = WM_operator_pystring(C, op->type, op->ptr, 1);
+			snapshot(C,buf);
+			MEM_freeN(buf);
+		}
 		
 		BKE_reports_print(op->reports, RPT_DEBUG); /* print out reports to console. */
 		if (op->type->flag & OPTYPE_REGISTER) {
@@ -1272,7 +1279,8 @@
 	wmWindowManager *wm= CTX_wm_manager(C);
 	SpaceFile *sfile;
 	int action= WM_HANDLER_CONTINUE;
-	
+	char *buf; /*pkhg*/
+
 	if(event->type != EVT_FILESELECT)
 		return action;
 	if(handler->op != (wmOperator *)event->customdata)
@@ -1366,8 +1374,17 @@
 							wm->op_undo_depth--;
 						
 						if (retval & OPERATOR_FINISHED)
+						  {
 							if(G.f & G_DEBUG)
 								wm_operator_print(C, handler->op);
+							if(G.f & G_INSTR)
+							{
+								buf = WM_operator_pystring(C, handler->op->type, handler->op->ptr, 1);
+								snapshot(C,buf);
+								MEM_freeN(buf);
+							}
+						  }
+ 
 						
 						/* XXX check this carefully, CTX_wm_manager(C) == wm is a bit hackish */
 						if(CTX_wm_manager(C) == wm && wm->op_undo_depth == 0)
Index: source/blender/windowmanager/WM_api.h
===================================================================
--- source/blender/windowmanager/WM_api.h	(revision 39541)
+++ source/blender/windowmanager/WM_api.h	(working copy)
@@ -97,6 +97,9 @@
 int			WM_read_homefile	(struct bContext *C, struct ReportList *reports, short from_memory);
 int			WM_write_homefile	(struct bContext *C, struct wmOperator *op);
 void		WM_read_file		(struct bContext *C, const char *filepath, struct ReportList *reports);
+  /*pkhg*/
+void		snapshot			(struct bContext *C, char *buf);
+
 int			WM_write_file		(struct bContext *C, const char *target, int fileflags, struct ReportList *reports, int copy);
 void		WM_read_autosavefile(struct bContext *C);
 void		WM_autosave_init	(struct wmWindowManager *wm);
Index: source/blender/editors/interface/interface_handlers.c
===================================================================
--- source/blender/editors/interface/interface_handlers.c	(revision 39541)
+++ source/blender/editors/interface/interface_handlers.c	(working copy)
@@ -57,6 +57,8 @@
 #include "BKE_report.h"
 #include "BKE_texture.h"
 #include "BKE_unit.h"
+/*pkhg*/
+#include "BKE_global.h"
 
 #include "ED_screen.h"
 #include "ED_util.h"
@@ -364,6 +366,8 @@
 
 static void ui_apply_but_funcs_after(bContext *C)
 {
+  /*pkhg*/
+	char textbuf[512];
 	uiAfterFunc *afterf, after;
 	PointerRNA opptr;
 	ListBase funcs;
@@ -417,7 +421,15 @@
 			MEM_freeN(after.rename_orig);
 		
 		if(after.undostr[0])
+		  { /* pkhg*/
+			if(G.f & G_INSTR)
+			{
+				sprintf( textbuf, "interface(\"%s\")", after.undostr );
+				snapshot( C, textbuf );
+			}
 			ED_undo_push(C, after.undostr);
+		}
+		/*pkhg			ED_undo_push(C, after.undostr);*/
 	}
 }
 
Index: source/blender/editors/util/editmode_undo.c
===================================================================
--- source/blender/editors/util/editmode_undo.c	(revision 39541)
+++ source/blender/editors/util/editmode_undo.c	(working copy)
@@ -56,6 +56,8 @@
 
 #include "UI_interface.h"
 #include "UI_resources.h"
+/*pkhg*/
+#include "WM_api.h"
 
 #include "util_intern.h"
 
@@ -256,6 +258,8 @@
 		
 		if(curundo==NULL || curundo->prev==NULL) error("No more steps to undo");
 		else {
+		  /*pkhg*/
+			if(G.f & G_INSTR) snapshot( C, "undo()" );
 			if(G.f & G_DEBUG) printf("undo %s\n", curundo->name);
 			curundo= curundo->prev;
 			undo_restore(curundo, curundo->getdata(C));
@@ -266,6 +270,8 @@
 		
 		if(curundo==NULL || curundo->next==NULL) error("No more steps to redo");
 		else {
+		  /*pkhg*/
+			if(G.f & G_INSTR) snapshot( C, "redo()" );
 			undo_restore(curundo->next, curundo->getdata(C));
 			curundo= curundo->next;
 			if(G.f & G_DEBUG) printf("redo %s\n", curundo->name);
