Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.27.2.41.2.77
diff -u -r1.647.2.27.2.41.2.77 zend_compile.c
--- Zend/zend_compile.c	25 Jul 2008 04:54:08 -0000	1.647.2.27.2.41.2.77
+++ Zend/zend_compile.c	25 Jul 2008 10:26:25 -0000
@@ -1022,19 +1022,6 @@
 }
 
 
-void zend_do_init_string(znode *result TSRMLS_DC)
-{
-	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-	opline->opcode = ZEND_INIT_STRING;
-	opline->result.op_type = IS_TMP_VAR;
-	opline->result.u.var = get_temporary_variable(CG(active_op_array));
-	*result = opline->result;
-	SET_UNUSED(opline->op1);
-	SET_UNUSED(opline->op2);
-}
-
-
 void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC)
 {
 	zend_op *opline;
@@ -1054,47 +1041,36 @@
 		efree(Z_STRVAL(op2->u.constant));
 		return;
 	}
-	opline->op1 = *op1;
+
+	if (op1) {
+		opline->result = *result;
+		opline->op1 = *op1;
+	} else {
+		opline->result.op_type = IS_TMP_VAR;
+		opline->result.u.var = get_temporary_variable(CG(active_op_array));
+		*result = opline->result;
+		SET_UNUSED(opline->op1);
+	}
 	opline->op2 = *op2;
-	opline->op2.op_type = IS_CONST;
-	opline->result = opline->op1;
-	*result = opline->result;
 }
 
 
 void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC)
 {
-	zend_op *opline;
+	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
-	if (op1->op_type == IS_CONST) {
-		opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-		opline->opcode = ZEND_INIT_STRING;
+	opline->opcode = ZEND_ADD_VAR;
+
+	if (op1) {
+		opline->result = *result;
+		opline->op1 = *op1;
+	} else {
 		opline->result.op_type = IS_TMP_VAR;
 		opline->result.u.var = get_temporary_variable(CG(active_op_array));
 		*result = opline->result;
 		SET_UNUSED(opline->op1);
-		SET_UNUSED(opline->op2);
-
-		if (Z_STRLEN(op1->u.constant)>0) {
-			opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-			opline->opcode = ZEND_ADD_STRING;
-			opline->result = *result;
-			opline->op1 = *result;
-			opline->op2 = *op1;
-			opline->result = opline->op1;
-		} else {
-			zval_dtor(&op1->u.constant);
-		}
-	} else {
-		*result = *op1;
 	}
-
-	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-	opline->opcode = ZEND_ADD_VAR;
-	opline->result = *result;
-	opline->op1 = *result;
 	opline->op2 = *op2;
-	*result = opline->result;
 }
 
 void zend_do_free(znode *op1 TSRMLS_DC)
@@ -3949,6 +3925,7 @@
 	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
 	switch (cmd->op_type) {
+		case IS_CONST:
 		case IS_TMP_VAR:
 			opline->opcode = ZEND_SEND_VAL;
 			break;
@@ -4925,7 +4902,6 @@
 			retval = T_ECHO;
 			break;
 		case T_END_HEREDOC:
-		case T_END_NOWDOC:
 			efree(Z_STRVAL(zendlval->u.constant));
 			break;
 	}
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.8.2.12.2.28
diff -u -r1.316.2.8.2.12.2.28 zend_compile.h
--- Zend/zend_compile.h	25 Jul 2008 04:54:08 -0000	1.316.2.8.2.12.2.28
+++ Zend/zend_compile.h	25 Jul 2008 10:26:25 -0000
@@ -412,7 +412,6 @@
 
 void zend_do_free(znode *op1 TSRMLS_DC);
 
-void zend_do_init_string(znode *result TSRMLS_DC);
 void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC);
 void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);
 
Index: Zend/zend_highlight.c
===================================================================
RCS file: /repository/ZendEngine2/zend_highlight.c,v
retrieving revision 1.49.2.3.2.2.2.4
diff -u -r1.49.2.3.2.2.2.4 zend_highlight.c
--- Zend/zend_highlight.c	29 Jun 2008 08:21:34 -0000	1.49.2.3.2.2.2.4
+++ Zend/zend_highlight.c	9 Jul 2008 11:12:59 -0000
@@ -93,7 +93,6 @@
 	int token_type;
 	char *last_color = syntax_highlighter_ini->highlight_html;
 	char *next_color;
-	int in_string=0;
 
 	zend_printf("<code>");
 	zend_printf("<span style=\"color: %s\">\n", last_color);
@@ -115,22 +114,18 @@
 			case T_CLOSE_TAG:
 				next_color = syntax_highlighter_ini->highlight_default;
 				break;
+			case '"':
+			case T_ENCAPSED_AND_WHITESPACE:
 			case T_CONSTANT_ENCAPSED_STRING:
 				next_color = syntax_highlighter_ini->highlight_string;
 				break;
-			case '"':
-				next_color = syntax_highlighter_ini->highlight_string;
-				in_string = !in_string;
-				break;				
 			case T_WHITESPACE:
 				zend_html_puts(LANG_SCNG(yy_text), LANG_SCNG(yy_leng) TSRMLS_CC);  /* no color needed */
 				token.type = 0;
 				continue;
 				break;
 			default:
-				if (in_string) {
-					next_color = syntax_highlighter_ini->highlight_string;
-				} else if (token.type == 0) {
+				if (token.type == 0) {
 					next_color = syntax_highlighter_ini->highlight_keyword;
 				} else {
 					next_color = syntax_highlighter_ini->highlight_default;
@@ -149,7 +144,6 @@
 		}
 		switch (token_type) {
 			case T_END_HEREDOC:
-			case T_END_NOWDOC:
 				zend_html_puts(token.value.str.val, token.value.str.len TSRMLS_CC);
 				break;
 			default:
@@ -159,8 +153,6 @@
 
 		if (token.type == IS_STRING) {
 			switch (token_type) {
-				case EOF:
-					goto done;
 				case T_OPEN_TAG:
 				case T_OPEN_TAG_WITH_ECHO:
 				case T_CLOSE_TAG:
@@ -172,7 +164,7 @@
 					efree(token.value.str.val);
 					break;
 			}
-		} else if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
+		} else if (token_type == T_END_HEREDOC) {
 			efree(token.value.str.val);
 		}
 		token.type = 0;
@@ -190,7 +182,7 @@
 		}
 		zend_html_puts(LANG_SCNG(yy_text), (LANG_SCNG(yy_limit) - LANG_SCNG(yy_text)) TSRMLS_CC);
 	}
-done:
+
 	if (last_color != syntax_highlighter_ini->highlight_html) {
 		zend_printf("</span>\n");
 	}
@@ -217,12 +209,8 @@
 			case T_DOC_COMMENT:
 				token.type = 0;
 				continue;
-
-			case EOF:
-				return;
 			
 			case T_END_HEREDOC:
-			case T_END_NOWDOC:
 				zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
 				efree(token.value.str.val);
 				/* read the following character, either newline or ; */
Index: Zend/zend_language_parser.y
===================================================================
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
retrieving revision 1.160.2.4.2.8.2.23
diff -u -r1.160.2.4.2.8.2.23 zend_language_parser.y
--- Zend/zend_language_parser.y	24 Jul 2008 11:47:49 -0000	1.160.2.4.2.8.2.23
+++ Zend/zend_language_parser.y	25 Jul 2008 13:15:00 -0000
@@ -23,7 +23,7 @@
 /*
  * LALR shift/reduce conflicts and how they are resolved:
  *
- * - 2 shift/reduce conflicts due to the dangeling elseif/else ambiguity.  Solved by shift.
+ * - 2 shift/reduce conflicts due to the dangling elseif/else ambiguity. Solved by shift.
  *
  */
 
@@ -147,8 +147,6 @@
 %token T_NAMESPACE
 %token T_NS_C
 %token T_DIR
-%token T_START_NOWDOC
-%token T_END_NOWDOC
 
 %% /* Rules */
 
@@ -641,7 +639,7 @@
 	|	'@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
 	|	scalar				{ $$ = $1; }
 	|	T_ARRAY '(' array_pair_list ')' { $$ = $3; }
-	|	'`' encaps_list '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
+	|	'`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
 	|	T_PRINT expr  { zend_do_print(&$$, &$2 TSRMLS_CC); }
 	|	function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
 			parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
@@ -736,6 +734,12 @@
 	|	'(' expr ')'	{ $$ = $2; }
 ;
 
+backticks_expr:
+		/* empty */	{ ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
+	|	T_ENCAPSED_AND_WHITESPACE	{ $$ = $1; }
+	|	encaps_list	{ $$ = $1; }
+;
+
 
 ctor_arguments:
 		/* empty */	{ Z_LVAL($$.u.constant)=0; }
@@ -754,7 +758,8 @@
 	|	T_METHOD_C					{ $$ = $1; }
 	|	T_FUNC_C					{ $$ = $1; }
 	|	T_NS_C						{ $$ = $1; }
-	|	T_START_NOWDOC T_ENCAPSED_AND_WHITESPACE T_END_NOWDOC	{ $$ = $2; }
+	|	T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
+	|	T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
 ;
 
 
@@ -944,8 +949,8 @@
 encaps_list:
 		encaps_list encaps_var { zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC);  zend_do_add_variable(&$$, &$1, &$2 TSRMLS_CC); }
 	|	encaps_list T_ENCAPSED_AND_WHITESPACE	{ zend_do_add_string(&$$, &$1, &$2 TSRMLS_CC); }
-	|	/* empty */			{ zend_do_init_string(&$$ TSRMLS_CC); }
-
+	|	encaps_var { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, NULL, &$1 TSRMLS_CC); }
+	|	T_ENCAPSED_AND_WHITESPACE encaps_var	{ zend_do_add_string(&$$, NULL, &$1 TSRMLS_CC); zend_do_end_variable_parse(&$2, BP_VAR_R, 0 TSRMLS_CC); zend_do_add_variable(&$$, &$$, &$2 TSRMLS_CC); }
 ;
 
 
Index: Zend/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.131.2.11.2.13.2.24
diff -u -r1.131.2.11.2.13.2.24 zend_language_scanner.l
--- Zend/zend_language_scanner.l	24 Jul 2008 23:53:42 -0000	1.131.2.11.2.13.2.24
+++ Zend/zend_language_scanner.l	25 Jul 2008 10:52:13 -0000
@@ -919,7 +919,7 @@
 BACKQUOTE_CHARS     ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
 HEREDOC_CHARS       ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({HEREDOC_NEWLINE}+({HEREDOC_NON_LABEL}|{HEREDOC_LABEL_NO_NEWLINE})))
 
-NOWDOC_CHARS		({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
+NOWDOC_CHARS        ([^\n\r]|{NEWLINE}+([^a-zA-Z_\x7f-\xff\n\r]|({LABEL}([^a-zA-Z0-9_\x7f-\xff;\n\r]|(";"[^\n\r])))))
 
 /* compute yyleng before each rule */
 <!*> := yyleng = YYCURSOR - SCNG(yy_text);
@@ -1896,7 +1896,7 @@
 }
 
 
-<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|["]{LABEL}["]){NEWLINE} {
+<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
 	char *s;
 	int bprefix = (yytext[0] != '<') ? 1 : 0;
 
@@ -1908,12 +1908,35 @@
 		CG(heredoc_len)--;
 	}
 
-	if (*s == '"') {
+	if (*s == '\'') {
 		s++;
 		CG(heredoc_len) -= 2;
+
+		BEGIN(ST_NOWDOC);
+	} else {
+		if (*s == '"') {
+			s++;
+			CG(heredoc_len) -= 2;
+		}
+
+		BEGIN(ST_HEREDOC);
 	}
+
 	CG(heredoc) = estrndup(s, CG(heredoc_len));
-	BEGIN(ST_START_HEREDOC);
+
+	/* Check for ending label on the next line */
+	if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
+		char *end = YYCURSOR + CG(heredoc_len);
+
+		if (*end == ';') {
+			end++;
+		}
+
+		if (*end == '\n' || *end == '\r') {
+			BEGIN(ST_END_HEREDOC);
+		}
+	}
+
 	return T_START_HEREDOC;
 }
 
@@ -1924,34 +1947,6 @@
 }
 
 
-<ST_START_HEREDOC>{ANY_CHAR} {
-	yyless(0);
-	BEGIN(ST_HEREDOC);
-	goto restart;
-}
-
-<ST_START_HEREDOC>{LABEL}";"?[\n\r] {
-	int label_len = yyleng - 1;
-
-	if (yytext[label_len-1]==';') {
-		label_len--;
-	}
-
-	yyless(label_len);
-
-	if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
-		zendlval->value.str.val = CG(heredoc);
-		zendlval->value.str.len = label_len;
-		CG(heredoc)=NULL;
-		CG(heredoc_len)=0;
-		BEGIN(ST_IN_SCRIPTING);
-		return T_END_HEREDOC;
-	} else {
-		BEGIN(ST_HEREDOC);
-		yymore();
-	}
-}
-
 /* Match everything up to and including a possible ending label, so if the label
  * doesn't match, it's kept with the rest of the string
  *
@@ -1979,12 +1974,9 @@
 			len--; /* Windows newline */
 		}
 
-		/* Go back before last label char, to match in ST_END_HEREDOC state */
-		yyless(yyleng - 2);
-
-		/* Subtract the remaining label length. yyleng must include newline
-		 * before label, for zend_highlight/strip, tokenizer, etc. */
-		yyleng -= CG(heredoc_len) - 1;
+		/* Go back before label, to match in ST_END_HEREDOC state. yytext will include
+		 * newline before label, for zend_highlight/strip, tokenizer, etc. */
+		yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
 
 		CG(increment_lineno) = 1; /* For newline before label */
 		BEGIN(ST_END_HEREDOC);
@@ -1999,8 +1991,11 @@
 }
 
 <ST_END_HEREDOC>{ANY_CHAR} {
-	SCNG(yy_text) = (unsigned char *)(Z_STRVAL_P(zendlval) = CG(heredoc));
-	SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
+	YYCURSOR += CG(heredoc_len) - 1;
+	yyleng = CG(heredoc_len);
+
+	Z_STRVAL_P(zendlval) = CG(heredoc);
+	Z_STRLEN_P(zendlval) = CG(heredoc_len);
 	CG(heredoc) = NULL;
 	CG(heredoc_len) = 0;
 	BEGIN(ST_IN_SCRIPTING);
@@ -2065,52 +2060,7 @@
 }
 
 
-/* BEGIN nowdoc */
-
-<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
-	int bprefix = (yytext[0] != '<') ? 1 : 0;
-	char *s;
-	CG(zend_lineno)++;
-	/* 3 is <<<, 2 is quotes, 1 is newline */
-	CG(heredoc_len) = yyleng-bprefix-3-2-1-(yytext[yyleng-2]=='\r'?1:0);
-	s = yytext+bprefix+3;
-	while ((*s == ' ') || (*s == '\t')) {
-		s++;
-		CG(heredoc_len)--;
-	}
-	s++; /* first quote */
-	CG(heredoc) = estrndup(s, CG(heredoc_len));
-	BEGIN(ST_START_NOWDOC);
-	return T_START_NOWDOC;
-}
-
-<ST_START_NOWDOC>{ANY_CHAR} {
-	yyless(0);
-	BEGIN(ST_NOWDOC);
-	goto restart;
-}
-
-<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
-	int label_len = yyleng - 1;
-
-	if (yytext[label_len-1]==';') {
-		label_len--;
-	}
-
-	if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
-		yyless(label_len-1);
-		yyleng = 0;
-		BEGIN(ST_END_NOWDOC);
-		ZVAL_EMPTY_STRING(zendlval);
-		return T_ENCAPSED_AND_WHITESPACE;
-	} else {
-		BEGIN(ST_NOWDOC);
-		yyless(label_len);
-		yymore();
-	}
-}
-
-<ST_NOWDOC>{NOWDOC_CHARS}*{NEWLINE}+{LABEL}";"?[\n\r] {
+<ST_NOWDOC>({NOWDOC_CHARS}+{NEWLINE}+|{NEWLINE}+){LABEL}";"?[\n\r] {
 	char *end = yytext + yyleng - 1;
 
 	if (end[-1] == ';') {
@@ -2131,19 +2081,16 @@
 			len--; /* Windows newline */
 		}
 
-		/* Go back before last label char, to match in ST_END_NOWDOC state */
-		yyless(yyleng - 2);
-
-		/* Subtract the remaining label length. yyleng must include newline
-		 * before label, for zend_highlight/strip, tokenizer, etc. */
-		yyleng -= CG(heredoc_len) - 1;
+		/* Go back before label, to match in ST_END_HEREDOC state. yytext will include
+		 * newline before label, for zend_highlight/strip, tokenizer, etc. */
+		yyless(yyleng - CG(heredoc_len) - 1); /* 1 for newline after label */
 
 		CG(increment_lineno) = 1; /* For newline before label */
-		BEGIN(ST_END_NOWDOC);
+		BEGIN(ST_END_HEREDOC);
 
-		HANDLE_NEWLINES(yytext, len);
 		zend_copy_value(zendlval, yytext, len);
 		zendlval->type = IS_STRING;
+		HANDLE_NEWLINES(yytext, len);
 		return T_ENCAPSED_AND_WHITESPACE;
 	} else {
 		/* Go back to end of label, so the next match works correctly in case of
@@ -2153,16 +2100,6 @@
 	}
 }
 
-<ST_END_NOWDOC>{ANY_CHAR} {
-	SCNG(yy_text) = (unsigned char*)(Z_STRVAL_P(zendlval) = CG(heredoc));
-	SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len);
-	CG(heredoc) = NULL;
-	CG(heredoc_len) = 0;
-	BEGIN(ST_IN_SCRIPTING);
-	return T_END_NOWDOC;
-}
-
-/* END nowdoc */
 
 <ST_DOUBLE_QUOTES>["] {
 	BEGIN(ST_IN_SCRIPTING);
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.62
diff -u -r1.59.2.29.2.48.2.62 zend_vm_def.h
--- Zend/zend_vm_def.h	24 Jul 2008 11:47:49 -0000	1.59.2.29.2.48.2.62
+++ Zend/zend_vm_def.h	25 Jul 2008 13:38:41 -0000
@@ -1776,38 +1776,64 @@
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP, CONST)
+ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
 {
 	zend_op *opline = EX(opline);
-	zend_free_op free_op1;
+	zval *str = &EX_T(opline->result.u.var).tmp_var;
+
+	if (OP1_TYPE == IS_UNUSED) {
+		/* Initialize for erealloc in add_char_to_string */
+		Z_STRVAL_P(str) = NULL;
+		Z_STRLEN_P(str) = 0;
+		Z_TYPE_P(str) = IS_STRING;
+
+		INIT_PZVAL(str);
+	}
+
+	add_char_to_string(str, str, &opline->op2.u.constant);
 
-	add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
-		GET_OP1_ZVAL_PTR(BP_VAR_NA),
-		&opline->op2.u.constant);
 	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP, CONST)
+ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST)
 {
 	zend_op *opline = EX(opline);
-	zend_free_op free_op1;
+	zval *str = &EX_T(opline->result.u.var).tmp_var;
+
+	if (OP1_TYPE == IS_UNUSED) {
+		/* Initialize for erealloc in add_string_to_string */
+		Z_STRVAL_P(str) = NULL;
+		Z_STRLEN_P(str) = 0;
+		Z_TYPE_P(str) = IS_STRING;
+
+		INIT_PZVAL(str);
+	}
+
+	add_string_to_string(str, str, &opline->op2.u.constant);
 
-	add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
-		GET_OP1_ZVAL_PTR(BP_VAR_NA),
-		&opline->op2.u.constant);
 	/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP, TMP|VAR|CV)
+ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV)
 {
 	zend_op *opline = EX(opline);
-	zend_free_op free_op1, free_op2;
+	zend_free_op free_op2;
+	zval *str = &EX_T(opline->result.u.var).tmp_var;
 	zval *var = GET_OP2_ZVAL_PTR(BP_VAR_R);
 	zval var_copy;
 	int use_copy = 0;
 
+	if (OP1_TYPE == IS_UNUSED) {
+		/* Initialize for erealloc in add_string_to_string */
+		Z_STRVAL_P(str) = NULL;
+		Z_STRLEN_P(str) = 0;
+		Z_TYPE_P(str) = IS_STRING;
+
+		INIT_PZVAL(str);
+	}
+
 	if (Z_TYPE_P(var) != IS_STRING) {
 		zend_make_printable_zval(var, &var_copy, &use_copy);
 
@@ -1815,9 +1841,8 @@
 			var = &var_copy;
 		}
 	}
-	add_string_to_string(	&EX_T(opline->result.u.var).tmp_var,
-							GET_OP1_ZVAL_PTR(BP_VAR_NA),
-							var);
+	add_string_to_string(str, str, var);
+
 	if (use_copy) {
 		zval_dtor(var);
 	}
Index: Zend/tests/bug35655.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/bug35655.phpt,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 bug35655.phpt
--- Zend/tests/bug35655.phpt	17 Dec 2005 14:54:41 -0000	1.1.2.3
+++ Zend/tests/bug35655.phpt	2 May 2008 13:50:00 -0000
@@ -20,6 +20,6 @@
 ?>
 --EXPECT--
 <code><span style="color: #000000">
-<br /><span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;EOT<br /></span><span style="color: #0000BB">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
+<br /><span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;EOT<br /></span><span style="color: #DD0000">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
 </span>
 </code>
Index: Zend/tests/heredoc_011.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/heredoc_011.phpt,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 heredoc_011.phpt
--- Zend/tests/heredoc_011.phpt	12 Feb 2008 09:27:45 -0000	1.1.2.1
+++ Zend/tests/heredoc_011.phpt	3 May 2008 04:14:00 -0000
@@ -1,5 +1,5 @@
 --TEST--
-Heredocs can NOT be used as static scalars.
+STATIC heredocs CAN be used as static scalars.
 --FILE--
 <?php
 
@@ -7,14 +7,14 @@
 
 class e {
     
-    const E = <<<THISMUSTERROR
-If you see this, something's wrong.
-THISMUSTERROR;
+    const E = <<<THISMUSTNOTERROR
+If you DON'T see this, something's wrong.
+THISMUSTNOTERROR;
 
 };
 
 print e::E . "\n";
 
 ?>
---EXPECTF--
-Parse error: syntax error, unexpected T_START_HEREDOC in %sheredoc_011.php on line 8
+--EXPECT--
+If you DON'T see this, something's wrong.
Index: Zend/tests/nowdoc_013.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/nowdoc_013.phpt,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 nowdoc_013.phpt
--- Zend/tests/nowdoc_013.phpt	12 Feb 2008 09:27:45 -0000	1.1.2.1
+++ Zend/tests/nowdoc_013.phpt	2 May 2008 13:25:20 -0000
@@ -21,6 +21,6 @@
 ?>
 --EXPECT--
 <code><span style="color: #000000">
-<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
+<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #DD0000">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
 </span>
 </code>
Index: Zend/tests/nowdoc_014.phpt
===================================================================
RCS file: /repository/ZendEngine2/tests/nowdoc_014.phpt,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 nowdoc_014.phpt
--- Zend/tests/nowdoc_014.phpt	12 Feb 2008 09:27:45 -0000	1.1.2.1
+++ Zend/tests/nowdoc_014.phpt	2 May 2008 13:32:00 -0000
@@ -1,5 +1,5 @@
 --TEST--
-Highliting empty nowdoc
+Highlighting empty nowdoc
 --INI--
 highlight.string  = #DD0000
 highlight.comment = #FF8000
@@ -20,6 +20,6 @@
 ?>
 --EXPECT--
 <code><span style="color: #000000">
-<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB"></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
+<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br />EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
 </span>
 </code>
Index: NEWS
===================================================================
RCS file: /repository/php-src/NEWS,v
retrieving revision 1.2027.2.547.2.965.2.222
diff -u -r1.2027.2.547.2.965.2.222 NEWS
--- NEWS	25 Jul 2008 08:27:37 -0000	1.2027.2.547.2.965.2.222
+++ NEWS	25 Jul 2008 10:26:01 -0000
@@ -24,6 +24,10 @@
   . Added "jump label" operator (limited "goto"). (Dmitry, Sara)
   . Added NOWDOC syntax. (Gwynne Raskind, Stas, Dmitry)
   . Added HEREDOC syntax with double quotes. (Lars Strojny, Felipe)
+  . Added support for using static HEREDOCs to initialize static variables and
+    class members or constants. (Matt)
+  . Improved syntax highlighting and consistency for variables in double-quoted
+    strings and literal text in HEREDOCs and backticks. (Matt)
   . Added "?:" operator. (Marcus)
   . Added support for namespaces. (Dmitry, Stas, Gregory)
   . Added support for Late Static Binding. (Dmitry, Etienne Kneuss)
@@ -69,6 +73,7 @@
     second usage. (Dmitry)
   . Optimized ZEND_FETCH_CLASS + ZEND_ADD_INTERFACE into single
     ZEND_ADD_INTERFACE opcode (Dmitry)
+  . Optimized interpolated strings to use one less opcode. (Matt)
 
 - Improved php.ini handling: (Jani)
   . Added ".htaccess" style user-defined php.ini files support for CGI/FastCGI
Index: ext/tokenizer/tokenizer.c
===================================================================
RCS file: /repository/php-src/ext/tokenizer/tokenizer.c,v
retrieving revision 1.31.2.5.2.7.2.8
diff -u -r1.31.2.5.2.7.2.8 tokenizer.c
--- ext/tokenizer/tokenizer.c	25 Jul 2008 03:42:01 -0000	1.31.2.5.2.7.2.8
+++ ext/tokenizer/tokenizer.c	25 Jul 2008 10:26:01 -0000
@@ -132,7 +132,7 @@
 			MAKE_STD_ZVAL(keyword);
 			array_init(keyword);
 			add_next_index_long(keyword, token_type);
-			if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
+			if (token_type == T_END_HEREDOC) {
 				if (CG(increment_lineno)) {
 					token_line = ++CG(zend_lineno);
 					CG(increment_lineno) = 0;
Index: ext/tokenizer/tokenizer_data.c
===================================================================
RCS file: /repository/php-src/ext/tokenizer/tokenizer_data.c,v
retrieving revision 1.1.2.2.2.7
diff -u -r1.1.2.2.2.7 tokenizer_data.c
--- ext/tokenizer/tokenizer_data.c	30 Mar 2008 22:01:44 -0000	1.1.2.2.2.7
+++ ext/tokenizer/tokenizer_data.c	9 Jul 2008 13:04:00 -0000
@@ -151,8 +151,6 @@
 	REGISTER_LONG_CONSTANT("T_NAMESPACE", T_NAMESPACE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_NS_C", T_NS_C, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_DIR", T_DIR, CONST_CS | CONST_PERSISTENT);
-	REGISTER_LONG_CONSTANT("T_START_NOWDOC", T_START_NOWDOC, CONST_CS | CONST_PERSISTENT);
-	REGISTER_LONG_CONSTANT("T_END_NOWDOC", T_END_NOWDOC, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("T_DOUBLE_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT);
 }
 
@@ -282,8 +280,6 @@
 		case T_NAMESPACE: return "T_NAMESPACE";
 		case T_NS_C: return "T_NS_C";
 		case T_DIR: return "T_DIR";
-		case T_START_NOWDOC: return "T_START_NOWDOC";
-		case T_END_NOWDOC: return "T_END_NOWDOC";
 
 	}
 	return "UNKNOWN";
Index: tests/strings/bug26703.phpt
===================================================================
RCS file: /repository/php-src/tests/strings/bug26703.phpt,v
retrieving revision 1.3
diff -u -r1.3 bug26703.phpt
--- tests/strings/bug26703.phpt	23 May 2005 11:38:24 -0000	1.3
+++ tests/strings/bug26703.phpt	2 May 2008 14:00:10 -0000
@@ -13,6 +13,6 @@
 ?>
 --EXPECT--
 <code><span style="color: #000000">
-<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">echo&nbsp;</span><span style="color: #DD0000">"foo[]&nbsp;$a&nbsp;\n"</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">?&gt;</span>
+<span style="color: #0000BB">&lt;?php&nbsp;</span><span style="color: #007700">echo&nbsp;</span><span style="color: #DD0000">"foo[]&nbsp;</span><span style="color: #0000BB">$a</span><span style="color: #DD0000">&nbsp;\n"</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">?&gt;</span>
 </span>
 </code>
