diff --git a/src/modules/Parser/html.c b/src/modules/Parser/html.c
index cbbed196fc48e9461849f5116d456a625c60f3e9..c3de86ac650bfe26c7ad1fa748e5a8ed5eb7f55f 100644
--- a/src/modules/Parser/html.c
+++ b/src/modules/Parser/html.c
@@ -17,8 +17,10 @@
 
 #include "parser.h"
 
-/*
+extern struct program *parser_html_program;
+
 #define DEBUG
+/*
 #define SCAN_DEBUG
 */
 
@@ -31,7 +33,7 @@
 #define DEBUG_MARK_SPOT(TEXT,FEED,C) do; while(0)
 #endif
 
-#if 0
+#if 1
 #define free(X) fprintf(stderr,"free line %d: %p\n",__LINE__,X); free(X)
 #endif
 
@@ -285,12 +287,11 @@ found_start:
       free(THIS->ws_or_endarg);
       THIS->ws_or_endarg=NULL;
    }
-   THIS->ws_or_endarg=(p_wchar2*)xalloc(sizeof(p_wchar2)*THIS->n_ws);
-
+   THIS->n_ws_or_endarg=THIS->n_ws+2;
+   THIS->ws_or_endarg=(p_wchar2*)xalloc(sizeof(p_wchar2)*THIS->n_ws_or_endarg);
    MEMCPY(THIS->ws_or_endarg+2,THIS->ws,THIS->n_ws*sizeof(p_wchar2));
    THIS->ws_or_endarg[0]=THIS->arg_eq;
    THIS->ws_or_endarg[1]=THIS->tag_end;
-   THIS->n_ws_or_endarg=THIS->n_ws+2;
 
    if (THIS->ws_or_endarg_or_quote) 
    {
@@ -298,8 +299,10 @@ found_start:
       THIS->ws_or_endarg_or_quote=NULL;
    }
 
+   THIS->n_ws_or_endarg_or_quote=
+      THIS->n_ws_or_endarg+THIS->nargq;
    THIS->ws_or_endarg_or_quote=
-      (p_wchar2*)xalloc(sizeof(p_wchar2)*(THIS->n_ws_or_endarg+THIS->nargq));
+      (p_wchar2*)xalloc(sizeof(p_wchar2)*(THIS->n_ws_or_endarg_or_quote));
 
    MEMCPY(THIS->ws_or_endarg_or_quote, THIS->ws_or_endarg,
 	  THIS->n_ws_or_endarg*sizeof(p_wchar2));
@@ -307,8 +310,6 @@ found_start:
    MEMCPY(THIS->ws_or_endarg_or_quote+THIS->n_ws_or_endarg,
 	  THIS->argq_start, THIS->nargq*sizeof(p_wchar2));
 
-   THIS->n_ws_or_endarg_or_quote=
-      THIS->n_ws_or_endarg+THIS->nargq;
 }
 
 static void init_html_struct(struct object *o)
@@ -389,6 +390,8 @@ static void exit_html_struct(struct object *o)
    if (THIS->ws_or_endarg_or_quote) free(THIS->ws_or_endarg_or_quote);
 
    if (THIS->extra_args) free_array(THIS->extra_args);
+
+   DEBUG((stderr,"exit_html_struct %p done\n",THIS));
 }
 
 /****** setup callbacks *****************************/
@@ -469,6 +472,13 @@ static void html_add_tag(INT32 args)
 {
    check_all_args("add_tag",args,
 		  BIT_STRING,BIT_MIXED,0);
+   if (THIS->maptag->refs>1)
+   {
+      push_mapping(THIS->maptag);
+      THIS->maptag=copy_mapping(THIS->maptag);
+      pop_stack();
+      fprintf(stderr,"COPY\n");
+   }
    mapping_insert(THIS->maptag,sp-2,sp-1);
    
    pop_n_elems(args);
@@ -478,6 +488,12 @@ static void html_add_container(INT32 args)
 {
    check_all_args("add_container",args,
 		  BIT_STRING,BIT_MIXED,0);
+   if (THIS->mapcont->refs>1)
+   {
+      push_mapping(THIS->mapcont);
+      THIS->mapcont=copy_mapping(THIS->mapcont);
+      pop_stack();
+   }
    mapping_insert(THIS->mapcont,sp-2,sp-1);
    pop_n_elems(args);
 }
@@ -486,6 +502,12 @@ static void html_add_entity(INT32 args)
 {
    check_all_args("parse_tag_args",args,
 		  BIT_STRING,BIT_MIXED,0);
+   if (THIS->mapentity->refs>1)
+   {
+      push_mapping(THIS->mapentity);
+      THIS->mapentity=copy_mapping(THIS->mapentity);
+      pop_stack();
+   }
    mapping_insert(THIS->mapentity,sp-2,sp-1);
    pop_n_elems(args);
 }
@@ -2165,6 +2187,78 @@ void html_create(INT32 args)
    pop_n_elems(args);
 }
 
+/*
+**! method object clone(mixed ...)
+**!	Clones the <ref>Parser.HTML</ref> object.
+**!	A new object of the same class is created,
+**!	filled with the parse setup from the 
+**!	old object.
+**!
+**!	This is the simpliest way of flushing a 
+**!	parse feed/output.
+**!
+**!	The arguments to clone is sent to the 
+**!	new object, simplifying work for custom classes that
+**!	inherits <ref>Parser.HTML</ref>.
+**! returns the new object.
+**!
+**! note:
+**!	create is called _before_ the setup is copied.
+*/
+
+static void html_clone(INT32 args)
+{
+   struct object *o;
+   struct parser_html_storage *p;
+   int i;
+   p_wchar2 *newws;
+
+   DEBUG((stderr,"parse_html_clone object %p\n",THISOBJ));
+
+   /* clone the current object, same class (!) */
+   push_object(o=clone_object(parser_html_program,args));
+
+   p=(struct parser_html_storage*)get_storage(o,parser_html_program);
+
+   if (p->maptag) free_mapping(p->maptag);
+   add_ref(p->maptag=THIS->maptag);
+   if (p->mapcont) free_mapping(p->mapcont);
+   add_ref(p->mapcont=THIS->mapcont);
+   if (p->mapentity) free_mapping(p->mapentity);
+   add_ref(p->mapentity=THIS->mapentity);
+
+   if (p->extra_args) free_array(p->extra_args);
+   if (THIS->extra_args)
+      add_ref(p->extra_args=THIS->extra_args);
+   else
+      p->extra_args=NULL;
+
+   p->lazy_end_arg_quote=THIS->lazy_end_arg_quote;
+   p->lazy_entity_end=THIS->lazy_entity_end;
+   
+   p->tag_start=THIS->tag_start;
+   p->tag_end=THIS->tag_end;
+   p->entity_start=THIS->entity_start;
+   p->entity_end=THIS->entity_end;
+   p->arg_eq=THIS->arg_eq;
+
+   p->nargq=THIS->nargq;
+   for (i=0; i<p->nargq; i++)
+   {
+      p->argq_start[i]=THIS->argq_start[i];
+      p->argq_stop[i]=THIS->argq_stop[i];
+   }
+   p->n_ws=THIS->n_ws;
+   newws=(p_wchar2*)xalloc(sizeof(p_wchar2)*p->n_ws);
+   MEMCPY(newws,THIS->ws,sizeof(p_wchar2)*p->n_ws);
+   if (p->ws) free(p->ws); 
+   p->ws=newws;
+
+   fprintf(stderr,"done clone\n");
+
+   /* all copied, object on stack */
+}
+
 /****** module init *********************************/
 
 #define tCbret tOr3(tInt0,tStr,tArr(tStr))
@@ -2184,30 +2278,22 @@ void init_parser_html(void)
 #define CBRET "string|array(string)" /* 0|string|({string}) */
 
    ADD_FUNCTION("create",html_create,tFunc(,tVoid),0);
+   ADD_FUNCTION("clone",html_clone,tFuncV(,tMixed,tVoid),0);
 
    /* feed control */
 
-   add_function("feed",html_feed,
-		"function(:object)|"
-		"function(string,void|int:object)",0);
-   add_function("finish",html_finish,
-		"function(:object)",0);
-   add_function("read",html_read,
-		"function(void|int:string)",0);
+   ADD_FUNCTION("feed",html_feed,tOr(tFunc(,tObj),tFunc(tStr tOr(tVoid,tInt),tObj)),0);
+   ADD_FUNCTION("finish",html_finish,tFunc(,tObj),0);
+   ADD_FUNCTION("read",html_read,tFunc(tOr(tVoid,tInt),tStr),0);
 
-   add_function("write_out",html_write_out,
-		"function(string:object)",0);
-   add_function("feed_insert",html_feed_insert,
-		"function(string,void|int:object)",0);
+   ADD_FUNCTION("write_out",html_write_out,tFunc(tStr,tObj),0);
+   ADD_FUNCTION("feed_insert",html_feed_insert,tFunc(tStr tOr(tVoid,tInt),tObj),0);
 
    /* query */
 
-   add_function("current",html_current,
-		"function(:string)",0);
-   add_function("tag_name",html_tag_name,
-		"function(:string)",0);
-   add_function("tag_args",html_tag_args,
-		"function(:mapping)",0);
+   ADD_FUNCTION("current",html_current,tFunc(,tStr),0);
+   ADD_FUNCTION("tag_name",html_tag_name,tFunc(,tStr),0);
+   ADD_FUNCTION("tag_args",html_tag_args,tFunc(,tMapping),0);
 
    /* callback setup */
 
@@ -2220,17 +2306,16 @@ void init_parser_html(void)
 
    /* special callbacks */
 
-   add_function("_set_tag_callback",html__set_tag_callback,
-		"function(function(object,string,mixed ...:"CBRET"):void)",0);
-   add_function("_set_data_callback",html__set_data_callback,
-		"function(function(object,string,mixed ...:"CBRET"):void)",0);
-   add_function("_set_entity_callback",html__set_entity_callback,
-		"function(function(object,string,mixed ...:"CBRET"):void)",0);
+   ADD_FUNCTION("_set_tag_callback",html__set_tag_callback,
+		tFunc(tFuncV(tObj tStr,tMix,tCbret),tVoid),0);
+   ADD_FUNCTION("_set_data_callback",html__set_data_callback,
+		tFunc(tFuncV(tObj tStr,tMix,tCbret),tVoid),0);
+   ADD_FUNCTION("_set_entity_callback",html__set_entity_callback,
+		tFunc(tFuncV(tObj tStr,tMix,tCbret),tVoid),0);
 
    /* debug, whatever */
    
-   add_function("_inspect",html__inspect,
-		"function(:mapping)",0);
+   ADD_FUNCTION("_inspect",html__inspect,tFunc(,tMapping),0);
 
    /* just useful */
 
@@ -2240,6 +2325,9 @@ void init_parser_html(void)
 		tFunc(tStr,tStr),0);
 }
 
+void exit_parser_html()
+{
+}
 
 /*
 
@@ -2250,8 +2338,6 @@ class Parse_HTML
 
    string read(void|int chars); // read out-feed
 
-   void reset();  // reset stream
-
    object clone(); // new object, fresh stream
 
    // argument quote ( < ... foo="bar" foo='bar' ...> )