Index: extensions/SemanticMediaWiki/includes/SMW_ParserExtensions.php
===================================================================
--- extensions/SemanticMediaWiki/includes/SMW_ParserExtensions.php	(revision 0)
+++ extensions/SemanticMediaWiki/includes/SMW_ParserExtensions.php	(revision 0)
@@ -49,7 +49,11 @@
 		SMWParserExtensions::$mTempParser = $parser;
 
 		// In the regexp matches below, leading ':' escapes the markup, as known for Categories.
-		// Parse links to extract semantic properties.
+		// Parse links to extract semantic properties.
+		global $smwgRecursivePropertyValues;
+		if ( $smwgRecursivePropertyValues ) {
+			self::parsePropertiesRecursive( $parser, $text );
+		} else
 		if ( $smwgLinksInValues ) { // More complex regexp -- lib PCRE may cause segfaults if text is long :-(
 			$semanticLinkPattern = '/\[\[                 # Beginning of the link
 			                        (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
@@ -60,7 +64,7 @@
 			                        )*)                   # all this zero or more times
 			                        (?:\|([^]]*))?        # Display text (like "text" in [[link|text]]), optional
 			                        \]\]                  # End of link
-			                        /xu';
+			                        /xu';
 			$text = preg_replace_callback( $semanticLinkPattern, array( 'SMWParserExtensions', 'parsePropertiesCallback' ), $text );
 		} else { // Simpler regexps -- no segfaults found for those, but no links in values.
 			$semanticLinkPattern = '/\[\[                 # Beginning of the link
@@ -160,13 +164,13 @@
 
 		// Extract annotations and create tooltip.
 		$properties = preg_split( '/:[=:]/u', $property );
-
-		foreach ( $properties as $singleprop ) {
-			$dv = SMWParseData::addProperty( $singleprop, $value, $valueCaption, SMWParserExtensions::$mTempParser, $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations );
+
+		foreach ( $properties as $singleprop ) {
+			$dv = SMWParseData::addProperty( $singleprop, $value, $valueCaption, SMWParserExtensions::$mTempParser, $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations );
 		}
 
 		$result = $dv->getShortWikitext( true );
-
+
 		if ( ( $smwgInlineErrors && $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations ) && ( !$dv->isValid() ) ) {
 			$result .= $dv->getErrorText();
 		}
@@ -175,5 +179,161 @@
 
 		return $result;
 	}
-
+
+
+	static private function parseProperties( $text, &$result = array(), &$start = 0, $inprop = false ) {
+		while( preg_match( '/\[\[([^:[][^]]*?):[=:]|(\[\[[^][]*?\]\])|(\]\])/xu', $text, $m, PREG_OFFSET_CAPTURE, $start ) ) {
+			$offset = $m[0][1];
+			if( isset($m[3]) && $inprop ) {
+				// end of property
+				$result[] = substr($text, $start, $offset - $start);
+				$start = $offset + 2;
+				return true;
+			}
+			if( isset($m[2]) ) {
+				// common link
+				$result[] = substr($text, $start, $offset - $start);
+				// special case, common link in 1-sized array
+				$result[] = array( $m[0][0] );
+				$offset += strlen($m[0][0]);
+				$start = $offset;
+				continue;
+			}
+
+			// property declaration
+			if( count( SMWPropertyValue::makeUserProperty( $m[1][0] )->getErrors() ) > 0 ) {
+				$offset += 2;
+				$result[] = substr($text, $start, $offset - $start);
+				$start = $offset;
+				continue;
+			}
+
+			$result[] = substr($text, $start, $offset - $start);
+			$start = $offset;
+			
+			$start2 = $start + strlen($m[0][0]);
+			$props = array();
+			$props[] = $m[1][0];
+			while( preg_match( '/([^:[][^]]*?):[=:]/xu', $text, $m, PREG_OFFSET_CAPTURE, $start2 ) ) {
+				$offset = $m[0][1];
+				if( $offset != $start2 ) break;
+				if( count( SMWPropertyValue::makeUserProperty( $m[1][0] )->getErrors() ) > 0 ) break;
+
+				$props[] = $m[1][0];
+				$start2 = $offset + strlen($m[0][0]);
+			}
+			$propprefix = substr($text, $start, $start2 - $start);
+			$pval = array();
+			if( self::parseProperties( $text, $pval, $start2, true ) ) {
+				$i = count($props) - 1;
+				$pval = array( 'name' => $props[$i], 'val' => $pval );
+				while( $i > 0 ) {
+					--$i;
+					$pval = array( 'name' => $props[$i], 'val' => array( $pval ) );
+				}
+				$result[] = $pval;
+			} else {
+				$result[] = $propprefix;
+				foreach($pval as $item) {
+					$result[] = $item;
+				}
+			}
+			$start = $start2;
+		}
+		$result[] = substr($text, $start);
+		
+		return false;
+	}
+	static private function renderProperties( &$parser, $prop ) {
+		$property = $prop['name'];
+		$pval = $prop['val'];
+		
+		$value = '';
+		$caption = false;
+		
+		foreach($pval as $item) {
+			if(is_array($item)) {
+				if(count($item) == 1) {
+					// link
+					$t = $item[0];
+				} else {
+					// property
+					$t = self::renderProperties($parser, $item);
+				}
+				if($caption === false) {
+					$value .= $t;
+				} else {
+					$caption .= $t;
+				}
+			} else {
+				if($caption === false) {
+					if(($idx = strpos($item, '|')) !== false) {
+						$value .= substr($item, 0, $idx);
+						$caption = substr($item, $idx + 1);
+					} else {
+						$value .= $item;
+					}
+				} else {
+					$caption .= $item;
+				}
+			}
+		}
+		
+		if ( $value == '' ) { // silently ignore empty values
+			return '';
+		}
+		if ( $property == 'SMW' ) {
+			switch ( $value ) {
+				case 'on':
+					SMWParserExtensions::$mTempStoreAnnotations = true;
+					break;
+				case 'off':
+					SMWParserExtensions::$mTempStoreAnnotations = false;
+					break;
+			}
+			return '';
+		}
+
+		global $smwgInlineErrors, $smwgStoreAnnotations;
+		
+		// FIXME: not fully tested yet
+		// The following checks for markers generated by MediaWiki to handle special content,
+		// e.g. math. In general, SMW is not prepared to handle such content properly.
+		// Note: \x07 was used in MediaWiki 1.11.0, \x7f is used now
+		if ( ( strpos( $value, "\x7f" ) === false ) && ( strpos( $value, "\x07" ) === false ) ) {
+			$dv = SMWParseData::addProperty( $property, $value, $caption, SMWParserExtensions::$mTempParser, $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations );			
+			$result = $dv->getShortWikitext( true );
+			if ( ( $smwgInlineErrors && $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations ) && ( !$dv->isValid() ) ) {
+				$result .= $dv->getErrorText();
+			}
+		} else {
+			$unstrippedValue = $parser->mStripState->unstripBoth($value);
+			$dv = SMWParseData::addProperty( $property, $unstrippedValue, $caption, SMWParserExtensions::$mTempParser, $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations );
+			// for text only, no check for now			
+			$result = $caption ? $caption : $value;
+			if ( ( $smwgInlineErrors && $smwgStoreAnnotations && SMWParserExtensions::$mTempStoreAnnotations ) && ( !$dv->isValid() ) ) {
+				$result .= $dv->getErrorText();
+			}
+		}
+		return $result;
+	}
+	static public function parsePropertiesRecursive( &$parser, &$text ) {
+		wfProfileIn( 'parsePropertiesRecursive (SMW)' );
+
+		self::parseProperties( $text, $doc );
+		$text = '';
+		foreach($doc as $item) {
+			if(!is_array($item)) {
+				// plain text
+				$text .= $item;
+			} elseif(count($item) == 1) {
+				// link
+				$text .= $item[0];
+			} else {
+				$text .= self::renderProperties( $parser, $item);				
+			}
+		}
+
+		wfProfileOut( 'parsePropertiesRecursive (SMW)' );
+	}
 }