--- xmlregexp.c	2006-03-20 16:36:39.022878300 -0500
+++ xmlregexp-fixed.c	2006-03-20 15:26:00.000000000 -0500
@@ -1476,7 +1476,13 @@
 	switch (atom->quant) {
 	    case XML_REGEXP_QUANT_OPT:
 		atom->quant = XML_REGEXP_QUANT_ONCE;
+		/* YG - transition must be to the state after end of atom.
+		        1. set transition from atom start to new state
+		        2. set transition from atom end to this state. 
 		xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
+		*/
+		xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
+		xmlFAGenerateEpsilonTransition(ctxt, atom->stop, ctxt->state);
 		break;
 	    case XML_REGEXP_QUANT_MULT:
 		atom->quant = XML_REGEXP_QUANT_ONCE;
@@ -1519,8 +1525,10 @@
 		atom->min = 0;
 		atom->max = 0;
 		atom->quant = XML_REGEXP_QUANT_ONCE;
+		/* YG - move this function call down
 		xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
 			                              atom->start, counter);
+		*/
 		if (to != NULL) {
 		    newstate = to;
 		} else {
@@ -1530,6 +1538,11 @@
 		ctxt->state = newstate;
 		xmlFAGenerateCountedTransition(ctxt, atom->stop,
 			                       newstate, counter);
+                
+                /* YG - first check count and if OK jump forward; 
+                   if checking fail increment count and jump back */
+		xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
+			                              atom->start, counter);
 	    }
 	    default:
 		break;
@@ -2906,6 +2919,13 @@
 #endif
 		    xmlFARegExecSave(exec);
 		}
+		/* YG - restart count for expressions like this ((abc){2})* */
+		if (trans->count >= 0) {
+#ifdef DEBUG_REGEXP_EXEC
+		    printf("Reset count %d\n", trans->count);
+#endif
+		    exec->counts[trans->count] = 0;
+		}
 		if (trans->counter >= 0) {
 #ifdef DEBUG_REGEXP_EXEC
 		    printf("Increasing count %d\n", trans->counter);
@@ -4833,6 +4853,9 @@
     return(1);
 }
 
+/* YG - some optimization for remove duplicate path in automata 
+      in expressions like this (a|b)(c|d) */
+
 /**
  * xmlFAParseBranch:
  * @ctxt:  a regexp parser context
@@ -4841,14 +4864,17 @@
  8
  */
 static int
-xmlFAParseBranch(xmlRegParserCtxtPtr ctxt) {
+xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
+    /* YG - add parameter "to" */
     xmlRegStatePtr previous;
     int ret;
 
     previous = ctxt->state;
     ret = xmlFAParsePiece(ctxt);
     if (ret != 0) {
-	if (xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom) < 0)
+	/* YG - on first branch generate new state and use it for next branches */
+	if (xmlFAGenerateTransitions(ctxt, previous, 
+	        (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
 	    return(-1);
 	previous = ctxt->state;
 	ctxt->atom = NULL;
@@ -4856,8 +4882,9 @@
     while ((ret != 0) && (ctxt->error == 0)) {
 	ret = xmlFAParsePiece(ctxt);
 	if (ret != 0) {
-	    if (xmlFAGenerateTransitions(ctxt, previous, NULL,
-					 ctxt->atom) < 0)
+	    /* YG - reuse generated state again */
+	    if (xmlFAGenerateTransitions(ctxt, previous, 
+	            (CUR=='|' || CUR==')') ? to : NULL, ctxt->atom) < 0)
 		    return(-1);
 	    previous = ctxt->state;
 	    ctxt->atom = NULL;
@@ -4880,7 +4907,7 @@
     /* if not top start should have been generated by an epsilon trans */
     start = ctxt->state;
     ctxt->end = NULL;
-    xmlFAParseBranch(ctxt);
+    xmlFAParseBranch(ctxt, NULL);  /* YG */
     if (top) {
 #ifdef DEBUG_REGEXP_GRAPH
 	printf("State %d is final\n", ctxt->state->no);
@@ -4896,7 +4923,8 @@
 	NEXT;
 	ctxt->state = start;
 	ctxt->end = NULL;
-	xmlFAParseBranch(ctxt);
+	xmlFAParseBranch(ctxt, end); /* YG - reuse state "end" */
+#if 0 /* YG */
 	if (top) {
 	    ctxt->state->type = XML_REGEXP_FINAL_STATE;
 #ifdef DEBUG_REGEXP_GRAPH
@@ -4905,6 +4933,7 @@
 	} else {
 	    xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, end);
 	}
+#endif  /* YG */
     }
     if (!top) {
 	ctxt->state = end;
