Index: wp-testcase/test_includes_formatting.php
===================================================================
--- wp-testcase/test_includes_formatting.php	(revision 315)
+++ wp-testcase/test_includes_formatting.php	(working copy)
@@ -386,26 +386,43 @@
 		$this->assertEquals('A dog (&#8220;Hubertus&#8221;) was sent out.', wptexturize('A dog ("Hubertus") was sent out.'));
 	}
 	
+	//WP Ticket #4539
+	function test_basic_quotes() {
+		$this->assertEquals('test&#8217;s', wptexturize('test\'s'));
+		$this->assertEquals('test&#8217;s', wptexturize('test\'s'));
+
+		$this->assertEquals('&#8216;quoted&#8217;', wptexturize('\'quoted\''));
+		$this->assertEquals('&#8220;quoted&#8221;', wptexturize('"quoted"'));
+
+		$this->assertEquals('(&#8216;quoted&#8217;)', wptexturize('(\'quoted\')'));
+		$this->assertEquals('{&#8220;quoted&#8221;}', wptexturize('{"quoted"}'));
+
+		$this->assertEquals('&#8216;qu(ot)ed&#8217;', wptexturize('\'qu(ot)ed\''));
+		$this->assertEquals('&#8220;qu{ot}ed&#8221;', wptexturize('"qu{ot}ed"'));
+
+		$this->assertEquals('&#8216;test&#8217;s quoted&#8217;', wptexturize('\'test\'s quoted\''));
+		$this->assertEquals('&#8220;test&#8217;s quoted&#8221;', wptexturize('"test\'s quoted"'));
+	}
+	
+	//WP Ticket #4539
 	function test_quotes() {
-		$this->knownWPBug(4539);
 		$this->assertEquals('&#8220;Quoted String&#8221;', wptexturize('"Quoted String"'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"'));
-		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link and a period </a>&#8221;.', wptexturize('Here is "<a href="http://example.com">a test with a link and a period</a>".'));
+		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link and a period</a>&#8221;.', wptexturize('Here is "<a href="http://example.com">a test with a link and a period</a>".'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221; and a space.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>" and a space.'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a> and some text quoted&#8221;', wptexturize('Here is "<a href="http://example.com">a test with a link</a> and some text quoted"'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;, and a comma.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>", and a comma.'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;; and a semi-colon.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"; and a semi-colon.'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;- and a dash.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"- and a dash.'));
-		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;... and ellipses.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"... and ellipses.'));
+		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;&#8230; and ellipses.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"... and ellipses.'));
 		$this->assertEquals('Here is &#8220;a test <a href="http://example.com">with a link</a>&#8221;.', wptexturize('Here is "a test <a href="http://example.com">with a link</a>".'));
 		$this->assertEquals('Here is &#8220;<a href="http://example.com">a test with a link</a>&#8221;and a work stuck to the end.', wptexturize('Here is "<a href="http://example.com">a test with a link</a>"and a work stuck to the end.'));
 		$this->assertEquals('A test with a finishing number, &#8220;like 23&#8221;.', wptexturize('A test with a finishing number, "like 23".'));
 		$this->assertEquals('A test with a number, &#8220;like 62&#8221;, is nice to have.', wptexturize('A test with a number, "like 62", is nice to have.'));
 	}
 	
-	//WP Ticket #1258
+	//WP Ticket #4539
 	function test_quotes_before_s() {
-		$this->knownWPBug(4539);
 		$this->assertEquals('test&#8217;s', wptexturize("test's"));
 		$this->assertEquals('&#8216;test&#8217;s', wptexturize("'test's"));
 		$this->assertEquals('&#8216;test&#8217;s&#8217;', wptexturize("'test's'"));
@@ -415,16 +432,40 @@
 
 	//WP Ticket #4539
 	function test_quotes_before_numbers() {
-		$this->knownWPBug(4539);
 		$this->assertEquals('Class of &#8217;99', wptexturize("Class of '99"));
+		$this->assertEquals('Class of &#8217;99&#8217;s', wptexturize("Class of '99's"));
 		$this->assertEquals('&#8216;Class of &#8217;99&#8217;', wptexturize("'Class of '99'"));
+		$this->assertEquals('&#8216;Class of &#8217;99&#8217;s&#8217;', wptexturize("'Class of '99's'"));
+		$this->assertEquals('&#8216;Class of &#8217;99&#8217;s&#8217;', wptexturize("'Class of '99&#8217;s'"));
+		$this->assertEquals('&#8220;Class of 99&#8221;', wptexturize("\"Class of 99\""));
+		$this->assertEquals('&#8220;Class of &#8217;99&#8221;', wptexturize("\"Class of '99\""));
 	}
 	
+	function test_quotes_after_numbers() {
+		$this->assertEquals('Class of &#8217;99', wptexturize("Class of '99"));
+	}
+	
+	//WP Ticket #15241
 	function test_other_html() {
-		$this->knownWPBug(15241);
-		$this->assertEquals('&#8216;<strong>Quoted Text</strong>&#8217;,', wptexturize("'<strong>Quoted Text</strong>',"));
+		$this->assertEquals('&#8216;<strong>', wptexturize("'<strong>"));
+		$this->assertEquals('&#8216;<strong>Quoted Text</strong>&#8217;,', wptexturize('\'<strong>Quoted Text</strong>\','));
 		$this->assertEquals('&#8220;<strong>Quoted Text</strong>&#8221;,', wptexturize('"<strong>Quoted Text</strong>",'));
 	}
+	
+	function test_x() {
+		$this->assertEquals('14&#215;24', wptexturize("14x24"));
+	}
+	
+	function test_minutes_seconds() {
+		$this->assertEquals('9&#8242;', wptexturize('9\''));
+		$this->assertEquals('9&#8243;', wptexturize("9\""));
+
+		$this->assertEquals('a 9&#8242; b', wptexturize('a 9\' b'));
+		$this->assertEquals('a 9&#8243; b', wptexturize("a 9\" b"));
+		
+		$this->assertEquals('&#8220;a 9&#8242; b&#8221;', wptexturize('"a 9\' b"'));
+		$this->assertEquals('&#8216;a 9&#8243; b&#8217;', wptexturize("'a 9\" b'"));
+	}
 }
 
 class TestCleanUrl extends WPTestCase {
Index: wordpress/wp-includes/formatting.php
===================================================================
--- wordpress/wp-includes/formatting.php	(revision 16231)
+++ wordpress/wp-includes/formatting.php	(working copy)
@@ -56,9 +56,25 @@
 		$static_characters = array_merge(array('---', ' -- ', '--', ' - ', 'xn&#8211;', '...', '``', '\'\'', ' (tm)'), $cockney);
 		$static_replacements = array_merge(array('&#8212;', ' &#8212; ', '&#8211;', ' &#8211; ', 'xn--', '&#8230;', $opening_quote, $closing_quote, ' &#8482;'), $cockneyreplace);
 
-		$dynamic_characters = array('/\'(\d\d(?:&#8217;|\')?s)/', '/\'(\d)/', '/(\s|\A|[([{<]|")\'/', '/(\d)"/', '/(\d)\'/', '/(\S)\'([^\'\s])/', '/(\s|\A|[([{<])"(?!\s)/', '/"(\s|\S|\Z)/', '/\'([\s.]|\Z)/', '/\b(\d+)x(\d+)\b/');
-		$dynamic_replacements = array('&#8217;$1','&#8217;$1', '$1&#8216;', '$1&#8243;', '$1&#8242;', '$1&#8217;$2', '$1' . $opening_quote . '$2', $closing_quote . '$1', '&#8217;$1', '$1&#215;$2');
-
+		$dynamic_map = array(
+			'/\'(\d)/' => '&#8217;$1', // '99
+			
+			'/\'([^\']*)\'([^\']*)\'/' => '&#8216;$1&#8217;$2&#8217;', // 'test's'
+			
+			'/\'([^\']*)\'/' => '&#8216;$1&#8217;', // 'asd'
+			'/"([^"]*)"/' => $opening_quote . '$1' . $closing_quote, // "qwe"
+			
+			'/(\w)\'(\w)/' => '$1&#8217;$2', // test's
+			
+			'/(\d)"/' => '$1&#8243;', // 9" -> 9″
+			'/(\d)\'/' => '$1&#8242;', // 9' -> 9′
+			
+			'/\b(\d+)x(\d+)\b/' => '$1&#215;$2' // 10. 97x34 => 97×34
+		);
+		
+		$dynamic_characters = array_keys($dynamic_map);
+		$dynamic_replacements = array_values($dynamic_map);
+		
 		$static_setup = true;
 	}
 
@@ -69,6 +85,9 @@
 
 	$no_texturize_tags_stack = array();
 	$no_texturize_shortcodes_stack = array();
+	
+	$single_quote_state = '&#8216;';
+	$doube_quote_state = $opening_quote;
 
 	for ( $i = 0; $i < $stop; $i++ ) {
 		$curl = $textarr[$i];
@@ -80,6 +99,15 @@
 			$curl = str_replace($static_characters, $static_replacements, $curl);
 			// regular expressions
 			$curl = preg_replace($dynamic_characters, $dynamic_replacements, $curl);
+			// quotes that span multiple tags & shortcodes
+			while (($pos = strpos($curl, '\'')) !== FALSE) {
+				$curl = preg_replace('/\'/', $single_quote_state, $curl);
+				$single_quote_state = (($single_quote_state == '&#8216;') ? '&#8217;' : '&#8216;');
+			}
+			while (($pos = strpos($curl, '"')) !== FALSE) {
+				$curl = preg_replace('/"/', $doube_quote_state, $curl);
+				$doube_quote_state = (($doube_quote_state == $opening_quote) ? $closing_quote : $opening_quote);
+			}
 		} elseif (!empty($curl)) {
 			/*
 			 * Only call _wptexturize_pushpop_element if first char is correct
