Revision: 201025
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 23 Jun 2010 19:29:20 +0300
changeset 63 d706e2bc01db
parent 51 858432135449
child 66 f3b4a10db92c
Revision: 201025 Kit: 2010125
bldsystemtools/sysdeftools/filtering.xsl
bldsystemtools/sysdeftools/joinsysdef-module.xsl
bldsystemtools/sysdeftools/joinsysdef.xsl
bldsystemtools/sysdeftools/mergesysdef-module.xsl
bldsystemtools/sysdeftools/mergesysdef.xsl
bldsystemtools/sysdeftools/sysdefdowngrade.xsl
bldsystemtools/sysdeftools/validate/checklinks.pl
bldsystemtools/sysdeftools/validate/test-model.xsl
package_definition.xml
toolsandutils/e32tools/elf2e32/include/h_ver.h
toolsandutils/e32tools/elf2e32/source/parametermanager.cpp
toolsandutils/e32tools/group/release.txt
--- a/bldsystemtools/sysdeftools/filtering.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/filtering.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -12,14 +12,25 @@
 	Contributors:
 	Description:
 	Filter a sysdef in the 2.0 or 3.0 syntax
+	The functionality of these filters is not supported outside of this tool. 
+	The filtering concepts here may not be carried forward in future system definition processing tools
 -->
 <xsl:output method="xml" indent="yes"/>
 
 <xsl:param name="filter-type">only</xsl:param> <!-- only, has or with -->
 
-<xsl:param name="filter"/> <!-- comma-separated list -->
+<!--
+"only" = every component/unit can only have zero or more of these specified filters. ie, it can only have filters from this list, no other filters are allowed. This covers the common use case of "I want anything with gt and or techview, but no other filters" that was the first step in all old symbian.com builds. 
+
+"has" =  every component/unit must have all of these filters. ie it can have any other filters, but all specified filters must all be present. This covers the case where filter="test" identifies tests and there is no special filter to identify things that are not tests. So a filter for "!test" will strip out anything with filter="test" (plus any other filters) for a production build, and a filter of "test" will strip out everything that does not have filter="test" (plus any other filters) for a test build. Opposite filters will generate sets that are exactly opposite to each other.
 
-<xsl:param name="addbuild" select="0"/> <!-- add a system build section that accepts everything -->
+"with" =  components/units that have the opposite filter are removed. This covers the old symbian.com case of java, !java and "don't care" components. In other words we have a global feature that every item can be built only when the feature is set, only when the feature is not set, or it does not care and will always be built. So for a !java build only items containing filter="java" are stripped out. For a java build, only items with filter="!java" are stripped out. Anything which does not explicitly mention java are always unaffected. Opposite filters will generate sets which overlap.
+-->
+
+
+<xsl:param name="filter"/> <!-- comma-separated list of filters-->
+
+<xsl:param name="addbuild" select="0"/> <!-- add a system build section that accepts everything. Needed for genxml processing -->
 
 
 <xsl:template match="node()|@*"><xsl:copy-of select="."/></xsl:template>
--- a/bldsystemtools/sysdeftools/joinsysdef-module.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/joinsysdef-module.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -20,11 +20,19 @@
 <!-- create a stand-alone sysdef from a linked set of fragments -->
 
 <xsl:template match="/*" mode="join">
-	<xsl:message terminate="yes">ERROR: Cannot process this document</xsl:message>
+	<xsl:param name="filename"/>
+	<xsl:message terminate="yes">ERROR: Cannot process this document<xsl:if test="$filename !=''"> (<xsl:value-of select="$filename"/>)</xsl:if>
+		<xsl:choose>
+			<xsl:when test="self::SystemDefinition/@schema">. Unrecognised syntax schema="<xsl:value-of select="@schema"/>"</xsl:when>
+			<xsl:when test="self::SystemDefinition">. Missing schema</xsl:when>
+			<xsl:otherwise>. Invalid file type: <xsl:value-of select="name()"/></xsl:otherwise>
+		</xsl:choose>
+	</xsl:message>
 </xsl:template>
 
+<!-- anything in schemas 3.0.x won't add new functional attributes that need processing here, just blindly copy them-->
 
-<xsl:template match="/SystemDefinition[@schema='3.0.0' and count(*)=1]" mode="join">
+<xsl:template match="/SystemDefinition[starts-with(@schema,'3.0.') and count(*)=1]" mode="join">
 	<xsl:param name="origin" select="/.."/>
 	<xsl:param name="root"/>
 	<xsl:param name="filename"/>
@@ -46,9 +54,9 @@
 					<xsl:choose>
 						<xsl:when test="$n='id'"/> <!-- never copy this, always set -->
 						<xsl:when test="$origin/@*[name()=$n]"> <!-- don't copy if already set -->
-							<xsl:message>Cannot set "<xsl:value-of select="$n"/>", already set</xsl:message>
+							<xsl:message>Note: Cannot set "<xsl:value-of select="$n"/>", already set. Ignoring linked value</xsl:message>
 						</xsl:when>
-						<xsl:when test="$n='before'">
+						<xsl:when test="$n='before' or $n='replace'">
 							<!-- ensure ns is correct (if any future attribtues will ever use an ID, process it here too)-->
 							<xsl:apply-templates select="." mode="join">
 								<xsl:with-param name="namespaces" select="$namespaces"/>
@@ -90,7 +98,7 @@
 				</xsl:call-template>
 			</xsl:variable>
 			<xsl:variable name="ns" select="@id-namespace | namespace::* | exslt:node-set($nss)/*"/>
-			<xsl:copy><xsl:copy-of select="@*"/>
+			<xsl:copy><xsl:copy-of select="@*[name()!='schema']"/><xsl:call-template name="set-schema"/>
 				<xsl:apply-templates select="self::*[not(@id-namespace)]" mode="add-id-ns"/>
 				<xsl:for-each select="exslt:node-set($nss)/*"> <!-- add namespace definitions -->
 					<xsl:attribute name="xmlns:{name()}">
@@ -108,7 +116,7 @@
 		</xsl:when>
 		<xsl:otherwise> <!-- can't handle node-set() so put the namespaces in the document instead of the root element-->
 			<xsl:variable name="ns" select="@id-namespace | namespace::*"/>
-			<xsl:copy><xsl:copy-of select="@*"/>
+			<xsl:copy><xsl:copy-of select="@*[name()!='schema']"/><xsl:call-template name="set-schema"/>
 				<!-- no need to call is-content-filtered, it never will be from this element -->
 				<xsl:apply-templates select="*|comment()" mode="join">
 					<xsl:with-param name="namespaces" select="$ns"/>
@@ -136,8 +144,8 @@
 <xsl:template name="needed-namespaces">
 	<xsl:param name="foundns"/>
 	<xsl:param name="usedpre"/>
-	
-	<xsl:if test="foundns!=''">
+
+	<xsl:if test="$foundns!=''">
 		<xsl:variable name="line" select="substring-before($foundns,'&#xa;')"/> <!-- always has trailing newline -->
 		<xsl:variable name="name" select="substring-after($line,' ')"/> <!-- namespace prefix -->
 		<xsl:variable name="remainder" select="substring-after($foundns,'&#xa;')"/>
@@ -193,6 +201,74 @@
 </xsl:template>
 
 
+<!-- schema handling -->
+
+<xsl:template name="set-schema">
+<xsl:attribute name="schema">
+	<xsl:apply-templates mode="my-schema" select="/SystemDefinition"/>
+</xsl:attribute>
+</xsl:template>
+
+<xsl:template name="compare-versions"><xsl:param name="v1"/><xsl:param name="v2"/>
+			<xsl:choose>
+				<xsl:when test="$v1=$v2"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before($v1,'.') &gt; substring-before($v2,'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before($v1,'.') &lt; substring-before($v2,'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:when test="substring-before(substring-after($v1,'.'),'.') &gt; substring-before(substring-after($v2,'.'),'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before(substring-after($v1,'.'),'.') &lt; substring-before(substring-after($v2,'.'),'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:when test="substring-after(substring-after($v1,'.'),'.') &gt; substring-after(substring-after($v2,'.'),'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-after(substring-after($v1,'.'),'.') &lt; substring-after(substring-after($v2,'.'),'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:otherwise><xsl:value-of select="$v1"/></xsl:otherwise>
+			</xsl:choose>
+</xsl:template>
+
+<xsl:template name="compare-version-list"><xsl:param name="list"/>
+	<xsl:variable name="cur" select="substring-before($list,' ')"/>
+	<xsl:variable name="remaining" select="substring-after($list,' ')"/>
+	<xsl:choose>
+		<xsl:when test="$remaining=''"><xsl:value-of select="$cur"/></xsl:when>
+		<xsl:otherwise>
+			<xsl:variable name="nextbig">
+				<xsl:call-template name="compare-version-list">
+					<xsl:with-param name="list" select="$remaining"/>
+				</xsl:call-template>
+			</xsl:variable>
+			<xsl:call-template name="compare-versions">
+				<xsl:with-param name="v1" select="$cur"/>
+				<xsl:with-param name="v2" select="$nextbig"/>
+			</xsl:call-template>
+		</xsl:otherwise>
+	</xsl:choose>
+</xsl:template>
+
+<xsl:template match="/SystemDefinition" mode="my-schema"><xsl:param name="biggest" select="@schema"/>
+	<xsl:variable name="linked" select="//*[(self::component or self::collection or self::package or self::layer) and @href]"/>
+	<xsl:choose>
+		<xsl:when test="not($linked)"> <!-- no need to go further -->
+			<xsl:call-template name="compare-versions">
+				<xsl:with-param name="v1" select="@schema"/>
+				<xsl:with-param name="v2" select="$biggest"/>
+			</xsl:call-template>
+		</xsl:when>
+		<xsl:otherwise>
+				<xsl:call-template name="compare-version-list">
+					<xsl:with-param name="list">
+						<xsl:for-each select="$linked">
+						<xsl:call-template name="compare-versions">
+							<xsl:with-param name="v1">
+								<xsl:apply-templates mode="my-schema" select="document(@href,.)/*"/>
+							</xsl:with-param>
+							<xsl:with-param name="v2" select="$biggest"/>
+						</xsl:call-template>
+						<xsl:text> </xsl:text>
+					</xsl:for-each>
+				</xsl:with-param>
+				</xsl:call-template>
+		</xsl:otherwise>
+	</xsl:choose>
+</xsl:template>
+
+
 <xsl:template match="unit" mode="join">	<xsl:param name="root"/><xsl:param name="filename"/><xsl:param name="data"/>
 	 <xsl:variable name="display">
 	 	<xsl:apply-templates select="$data" mode="filter">
@@ -211,7 +287,7 @@
 </xsl:template>
 
 <!-- override mode="meta" to translate metadata sections. By default, include -->
-<xsl:template match="meta" priority="2"><xsl:param name="data"/>
+<xsl:template match="meta" priority="2" mode="join"><xsl:param name="data"/>
 	 <xsl:variable name="display">
 	 	<xsl:apply-templates select="$data" mode="filter">
 			<xsl:with-param name="item" select="current()"/>
@@ -226,6 +302,8 @@
 	</xsl:if>
 </xsl:template>
 
+<xsl:template match="meta[@rel='link-mapping']" priority="3" mode="join"/> <!--these are only used in the joining process, so remove from output -->
+
 
 <xsl:template match="*" mode="join">
 	<xsl:param name="root"/><xsl:param name="filename"/><xsl:param name="namespaces"/><xsl:param name="data"/>
@@ -236,7 +314,6 @@
 			still has meta: keep / delete
 			still has comments: keep / delete 
 	 -->
-	 
 	 <xsl:variable name="display">
 	 	<xsl:apply-templates select="$data" mode="filter">
 			<xsl:with-param name="item" select="current()"/>
@@ -244,14 +321,12 @@
 	 </xsl:variable>
 	 
 	 <xsl:if test="$display != 'hide' "> <!-- if hide, remove completely from the output-->
-	 
 		 <xsl:variable name="href">
 		 	<xsl:apply-templates select="." mode="link">
 				<xsl:with-param name="data" select="$data"/>
 			</xsl:apply-templates>
 		 </xsl:variable>
-		 	 
-		 
+	 		 
 		<xsl:element name="{name()}"> <!-- use this instead of <copy> so xalan doesn't add extra wrong namespaces -->
 			<xsl:apply-templates select="@*" mode="join">
 				<xsl:with-param name="namespaces" select="$namespaces"/>
@@ -265,6 +340,7 @@
 			</xsl:apply-templates>			
 			<xsl:choose>
 				<xsl:when test="$href !='' ">
+					<xsl:variable name="prefixmap" select="ancestor::SystemDefinition/*/meta[@rel='link-mapping']/map-prefix[starts-with($href,@link)]"/>
 					<xsl:variable name="origin" select="."/>
 					<xsl:apply-templates select="document($href,.)/*" mode="join">
 						<xsl:with-param name="origin" select="$origin"/>
@@ -273,11 +349,21 @@
 						<xsl:with-param name="filename">
 							<xsl:call-template name="joinpath">
 								<xsl:with-param name="file" select="$filename"/>
-								<xsl:with-param name="rel" select="$href"/>
+								<xsl:with-param name="rel">
+									<xsl:choose>
+										<xsl:when test="$prefixmap">
+											<xsl:value-of select="$prefixmap/@to"/>
+											<xsl:value-of select="substring-after($href,$prefixmap/@link)"/>
+										</xsl:when>
+										<xsl:otherwise>
+											<xsl:value-of select="$href"/>
+										</xsl:otherwise>
+									</xsl:choose>								
+								 </xsl:with-param>
 							</xsl:call-template>					
 						</xsl:with-param>
 						<xsl:with-param name="root">
-								<xsl:value-of select="$root"/>/<xsl:call-template name="lastbefore">
+							<xsl:value-of select="$root"/>/<xsl:call-template name="lastbefore">
 								<xsl:with-param name="string" select="$href"/>
 							</xsl:call-template>
 						</xsl:with-param>
@@ -315,6 +401,7 @@
 	<xsl:copy-of select="."/>
 </xsl:template>
 
+
 <xsl:template match="@mrp|@bldFile|@base" mode="join">	<xsl:param name="root"/><xsl:param name="filename"/>
 	<xsl:attribute name="{name()}">
 		<xsl:call-template name="joinpath">
@@ -360,7 +447,7 @@
 </xsl:template>
 
 
-<xsl:template match="@id|@before" mode="join">
+<xsl:template match="@id|@before|@replace" mode="join">
 	<xsl:param name="namespaces"/>
 	<!-- this will change the namespace prefixes for all IDs to match the root document -->
 	<xsl:variable name="ns">
@@ -374,7 +461,7 @@
 	<xsl:variable name="prefix" select="name($namespaces[.=$ns])"/>
 	<xsl:attribute name="{name()}">
 	<xsl:choose>
-		<xsl:when test="$prefix = 'id-namespace' or  (not($namespaces[name()='id-prefix']) and $ns=$defaultns)"/> <!-- it's the default namespace, no prefix -->
+		<xsl:when test="$prefix = 'id-namespace' or  (not($namespaces[name()='id-namespace']) and $ns=$defaultns)"/> <!-- it's the default namespace, no prefix -->
 		<xsl:when test="$prefix='' and contains(.,':')">
 			<!-- complex: copy id and copy namespace (namespace should be copied already)-->
 			<xsl:value-of select="."/>
@@ -413,15 +500,22 @@
 </xsl:template>
 
  <xsl:template name="joinpath"><xsl:param name="file"/><xsl:param name="rel"/>
-        <xsl:call-template name="reducepath">
-        <xsl:with-param name="file">
-	        <xsl:call-template name="lastbefore">
-	                <xsl:with-param name="string" select="$file"/>
-	        </xsl:call-template>
-	        <xsl:text>/</xsl:text>
-	        <xsl:value-of select="$rel"/>
-	       </xsl:with-param>
-	      </xsl:call-template>
+	<xsl:choose>
+		<xsl:when test="(contains($rel,'://') and not(contains(substring-before($rel,'://'),'/'))) or starts-with($rel,'/')"> <!-- absolute URI or absolute path-->
+			<xsl:value-of select="$rel"/>
+		</xsl:when>
+		<xsl:otherwise> <!-- relative link -->
+			<xsl:call-template name="reducepath">
+				<xsl:with-param name="file">
+					<xsl:call-template name="lastbefore">
+						<xsl:with-param name="string" select="$file"/>
+					</xsl:call-template>
+					<xsl:text>/</xsl:text>
+					<xsl:value-of select="$rel"/>
+				</xsl:with-param>
+			</xsl:call-template>
+		</xsl:otherwise>
+	</xsl:choose>
  </xsl:template>
 
 <xsl:template name="reducepath"><xsl:param name="file"/>
@@ -464,6 +558,7 @@
         		<xsl:with-param name="file" select="substring($file,3)"/>
 			</xsl:call-template>
 		</xsl:when>
+
 		<xsl:when test="contains($file,'/./')">
 			<xsl:call-template name="reducepath">
         		<xsl:with-param name="file">
@@ -473,6 +568,9 @@
 				</xsl:with-param>
 			</xsl:call-template>
 		</xsl:when>
+		<xsl:when test="substring($file,string-length($file) - 1) = '/.'">
+           <xsl:value-of select="substring($file,1,string-length($file) - 2)"/>
+		</xsl:when>
 		<xsl:otherwise><xsl:value-of select="$file"/></xsl:otherwise>
 	</xsl:choose>
  </xsl:template>
@@ -508,4 +606,5 @@
 	</xsl:element>
 </xsl:template>
 
+
 </xsl:stylesheet>
--- a/bldsystemtools/sysdeftools/joinsysdef.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/joinsysdef.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -14,6 +14,7 @@
 	Create a stand-alone sysdef from a linked set of fragments
 -->
  	<xsl:output method="xml" indent="yes"/>
+<!-- create a stand-alone sysdef from a linked set of fragments -->
 
 <xsl:param name="path">/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml</xsl:param>
 
@@ -29,6 +30,7 @@
 </xsl:template>
 
 
+<xsl:template match="meta[@rel='Api']" priority="2" mode="meta"/> <!-- ignore these, not needed in system build -->
 
 
 <xsl:include href="joinsysdef-module.xsl"/>
--- a/bldsystemtools/sysdeftools/mergesysdef-module.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/mergesysdef-module.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -18,9 +18,9 @@
 <xsl:template match="/SystemDefinition[starts-with(@schema,'2.') or starts-with(@schema,'1.')]" priority="2" mode="merge-models">
 	<xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="@schema"/> not supported</xsl:message>
 </xsl:template>
-<xsl:template match="/SystemDefinition[not(systemModel)]" priority="2" mode="merge-models">
+<!--<xsl:template match="/SystemDefinition[not(systemModel)]" priority="2" mode="merge-models">
 	<xsl:message terminate="yes">ERROR: Can only merge stand-alone system models</xsl:message>
-</xsl:template>
+</xsl:template>-->
 
 <!-- stuff for dealing with namespaces -->
 
@@ -42,7 +42,7 @@
 </xsl:template>
 
 
-<xsl:template match="@id|@before" mode="translate-namespaces"><xsl:param name="nsdoc"/>
+<xsl:template match="@id|@before|@replace" mode="translate-namespaces"><xsl:param name="nsdoc"/>
 	<xsl:attribute name="{name()}">
 		<xsl:variable name="id">
 			<xsl:choose>
@@ -59,8 +59,8 @@
 				<xsl:when test="contains(.,':')">
 					<xsl:value-of select="ancestor-or-self::*/namespace::*[name()=substring-before(current()/.,':')]"/>
 				</xsl:when>
-				<xsl:when test="/SystemDefinition/@id-namespace">
-					<xsl:value-of select="/SystemDefinition/@id-namespace"/>
+				<xsl:when test="ancestor::SystemDefinition/@id-namespace">
+					<xsl:value-of select="ancestor::SystemDefinition/@id-namespace"/>
 				</xsl:when>
 				<xsl:otherwise>
 					<xsl:value-of select="$defaultnamespace"/>
@@ -77,7 +77,7 @@
 			<xsl:when test="$nsdoc/namespace::*[.=$ns]">
 				<xsl:value-of select="concat(name($nsdoc/namespace::*[.=$ns]),':',$id)"/>
 			</xsl:when>
-			<xsl:when test="/SystemDefinition/@id-namespace=$ns">
+			<xsl:when test="ancestor::SystemDefinition/@id-namespace=$ns">
 				<xsl:variable name="myns">
 					<xsl:apply-templates mode="ns-prefix" select="$nsdoc">
 						<xsl:with-param name="ns" select="$ns"/>
@@ -93,7 +93,7 @@
 	</xsl:attribute>
 </xsl:template>
 
-<xsl:template match="/SystemDefinition" mode="ns-prefix">
+<xsl:template match="SystemDefinition" mode="ns-prefix">
 	<xsl:param name="ns"/> <!-- the namespace URI -->
 	<xsl:param name="pre"/> <!-- the preferred prefix to use if possbile -->
 	<xsl:param name="dontuse"/> <!-- space prefixed, separated and terminated list of namespace prefixes to not use -->
@@ -121,7 +121,7 @@
 
 <!--  need to make sure this handles <meta> correctly -->
 
-<xsl:template match="/SystemDefinition" mode="merge-models">
+<xsl:template match="SystemDefinition" mode="merge-models">
 	<xsl:param name="other"/>	<!-- the downstream SystemDefinition this is merged with -->
 	<xsl:param name="up" select="systemModel"/>	<!-- the element containing the origin @name used for any component from "this" model. -->
 	<xsl:param name="down" select="$other/systemModel"/> <!-- the element containing origin @name used for any component from $other model. -->
@@ -130,12 +130,18 @@
  	<xsl:if test="$other[starts-with(@schema,'2.') or starts-with(@schema,'1.')]">
 		<xsl:message terminate="yes">ERROR: Syntax <xsl:value-of select="$other/@schema"/> not supported</xsl:message>
 	</xsl:if>
-	<xsl:if test="not($other/systemModel)">
-		<xsl:message terminate="yes">ERROR: Can only merge stand-alone system models</xsl:message>
+	<xsl:if test="name(*) != name($other/*)">
+		<xsl:message terminate="yes">ERROR: Can only merge system models of the same rank</xsl:message>
 	</xsl:if>
 	 
 	<xsl:copy>
-		<xsl:copy-of  select="@*"/> <!--  use attributes from origin model -->
+		<xsl:attribute name="schema">
+			<xsl:call-template name="compare-versions">
+				<xsl:with-param name="v1" select="@schema"/>
+				<xsl:with-param name="v2" select="$other/@schema"/>
+			</xsl:call-template>
+		</xsl:attribute>
+		<xsl:copy-of  select="@*[name()!='schema']"/> <!--  use attributes from origin model -->
 		<xsl:variable name="namespaces">
 			<xsl:copy> <!-- needs <copy> so the processor doesn't lose the namespaces -->
 				<!--copy namespaces as needed -->
@@ -183,6 +189,7 @@
 			<xsl:with-param name="other" select="exslt:node-set($otherdoc)/*"/>
 			<xsl:with-param name="up" select="$up"/>
 			<xsl:with-param name="down" select="$down"/>
+			<xsl:with-param name="replaces" select="exslt:node-set($otherdoc)//*[self::component or self::collection or self::package or self::layer]/@replace"/>
 		</xsl:apply-templates>
 	
 	</xsl:copy>
@@ -192,6 +199,7 @@
 	<xsl:param name="other"/>	<!-- the parent of the downstream systemModel this is merged with -->
 	<xsl:param name="up"/>
 	<xsl:param name="down"/>
+	<xsl:param name="replaces"/>
 	<xsl:copy><xsl:copy-of  select="@*"/>
 		<!--  copy metas and comments in between meta. Do not try to merge metadata between models -->
 			<xsl:copy-of select="meta | $other/systemModel/meta | comment()[following-sibling::meta]"/>	
@@ -199,6 +207,7 @@
 			<xsl:with-param name="other" select="$other/systemModel"/>
 			<xsl:with-param name="up" select="$up"/>
 			<xsl:with-param name="down" select="$down"/>
+			<xsl:with-param name="replaces" select="$replaces"/>
 		</xsl:apply-templates>
 	</xsl:copy>
 </xsl:template>
@@ -226,7 +235,7 @@
 			<xsl:copy-of select="$other/@levels"/>
 		</xsl:when>
 		<xsl:when test="contains(concat(' ',normalize-space($other/@levels),' '),' - ')">
-			<!-- if other uses + syntax, then pre/append -->
+			<!-- if other uses - syntax, then pre/append -->
 			<xsl:variable name="lev">
 				<xsl:value-of select="substring-before(concat(' ',normalize-space($other/@levels),' '),' - ')"/>
 				<xsl:value-of select="concat(' ',.,' ')"/>
@@ -316,15 +325,69 @@
 	</xsl:choose>
 </xsl:template>
 
+<xsl:template match="node()" mode="merge-data">
+	<xsl:copy-of select="." />
+</xsl:template>
+
+<xsl:template match="meta" mode="merge-data">
+	<xsl:param name="metas" />
+	<!-- compare this meta against all metas in the  merged doc
+		if they are identical, then ignore this one.
+		identical is computed by translating to a string, normalising some known parts. This might be slow in some cases-->
+	<xsl:variable name="val"><xsl:apply-templates select="." mode="as-xml-text" /></xsl:variable>
+	<xsl:variable name="match">
+		<xsl:for-each select="$metas">
+			<xsl:variable name="cur"><xsl:apply-templates select="." mode="as-xml-text" /></xsl:variable>
+			<xsl:if test="$cur=$val">*</xsl:if>
+		</xsl:for-each>
+	</xsl:variable>
+	<xsl:if test="$match='' ">
+		<xsl:copy-of select="." />
+	</xsl:if>
+</xsl:template>
+
+<xsl:template match="text()[normalize-space(.)='']" mode="as-xml-text"/>
+<xsl:template match="node()" mode="as-xml-text"><xsl:value-of select="."/></xsl:template>
+<xsl:template match="comment()" mode="as-xml-text">&lt;--<xsl:value-of select="."/>--&gt;</xsl:template>
+<xsl:template match="@*" mode="as-xml-text">
+	<xsl:value-of select="concat(' ',name())"/>="<xsl:value-of select="."/>"</xsl:template>
+<xsl:template match="*" mode="as-xml-text">
+	<xsl:value-of select="concat('&lt;',name())"/>
+	<xsl:apply-templates select="@*" mode="as-xml-text"/>
+	<xsl:if test="self::meta and not(@rel)"> rel="Generic"</xsl:if>
+	<xsl:if test="self::meta and not(@type)"> type="auto"</xsl:if>
+	<xsl:text>&gt;</xsl:text>
+	<xsl:apply-templates select="node()" mode="as-xml-text"/>
+	<xsl:value-of select="concat('&lt;/',name(),'&gt;')"/>
+</xsl:template>
+
+
 <xsl:template match="layer | package | collection | component" mode="merge-models">
 	<xsl:param name="other"/>	<!-- the downstream item of the parent's rank that contains a potential items this is merged with -->
 	<xsl:param name="up"/>
 	<xsl:param name="down"/>
+	<xsl:param name="replaces"/>
 	<xsl:variable name="this" select="."/>	<!-- current item -->
-	
+
 	<!-- match = this item in the downstream model -->	
 	<xsl:variable name="match" select="$other/*[@id=current()/@id]"/>
-	
+
+	<xsl:choose>
+		<xsl:when test="$replaces[.=$this/@id] or (self::component and $match)">  <!-- replace the item instead of merge -->
+			<xsl:message>Note: <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>" <xsl:choose>
+				<xsl:when test="self::component and $match">overridden in downstream sysdef</xsl:when>
+				<xsl:otherwise><xsl:for-each select="$replaces[.=$this/@id]/..">replaced by <xsl:value-of select="name()"/> "<xsl:value-of select="@id"/>"</xsl:for-each></xsl:otherwise>
+			</xsl:choose>
+			</xsl:message>
+			<!-- if the removed item is in the downstream doc, just copy that and ignore the upstream contents -->
+			<xsl:apply-templates mode="merge-copy-of" select="$match">
+				<xsl:with-param name="origin" select="$down"/>
+				<xsl:with-param name="root" select="$this/ancestor::systemModel"/>			
+			</xsl:apply-templates>		
+		</xsl:when>
+		<xsl:otherwise>
+			<!-- remove this if it's in the list of stuff to be replaced-->
+
 	<!-- prev = the previous item before the current one (no metas, only named items)-->
 	<xsl:variable name="prev" select="preceding-sibling::*[@id][1]"/> 
 
@@ -372,9 +435,16 @@
 			</xsl:if>
 		</xsl:if>
 		
-		<xsl:for-each select="$match/@*">  <!-- copy downstream attributes, only if not set on upstream -->
+		<xsl:for-each select="$match/@*[name()!='replace']">  <!-- copy downstream attributes, only if not set on upstream -->
 			<xsl:if test="not($this/@*[name()=name(current())])"><xsl:copy-of select="."/></xsl:if>
 		</xsl:for-each>
+
+		<xsl:if test="$match/@replace"> <!-- check replace separately -->
+			<xsl:if test="not($this/ancestor::SystemDefinition//*[(self::component or self::collection or self::package or self::layer) and $match/@replace=@id])">
+				<!-- only remove replace if it's been used -->
+				<xsl:copy-of select="$match/@replace"/>
+			</xsl:if>
+		</xsl:if>
 		
 		<xsl:choose>
 			<xsl:when test="self::component">
@@ -388,12 +458,16 @@
 			<xsl:otherwise>
 
 				<!--  copy metas and comments in between meta. Do not try to merge metadata between models -->
-				<xsl:copy-of select="meta | $match/meta | comment()[following-sibling::meta]"/>
+				<xsl:apply-templates select="meta | $match/meta | comment()[following-sibling::meta]" mode="merge-data">
+					<xsl:with-param name="metas" select="$match/meta"/>
+				</xsl:apply-templates>
+				<xsl:copy-of select=" $match/meta | $match/comment()[following-sibling::meta]"/>
 				
 				<xsl:apply-templates mode="merge-models">
 					<xsl:with-param name="other" select="$match"/>
 					<xsl:with-param name="up" select="$up"/>
 					<xsl:with-param name="down" select="$down"/>
+					<xsl:with-param name="replaces" select="$replaces"/>
 				</xsl:apply-templates>
 				<!--  don't copy if explicitly or implicitly placed already-->
 				<xsl:for-each select="$match/*[not(@before) and not(following-sibling::*[@id=$this/*/@id])]">
@@ -407,8 +481,11 @@
 			</xsl:otherwise>
 		</xsl:choose>
 	</xsl:copy>
+
+		</xsl:otherwise>
+	</xsl:choose>
 	
-	<xsl:if test="self::layer and not(following-sibling::layer)">
+	<xsl:if test="self::layer and not(following-sibling::layer)">	
 		<!-- for the last layer, tack on any remaining layers -->
 		<xsl:apply-templates mode="merge-copy-of" select="$other/layer[not(@before) and not(following-sibling::*[@id=$this/../layer/@id]) and not(@id=$this/../layer/@id)]">
 			<xsl:with-param name="origin" select="$down"/>
@@ -448,12 +525,10 @@
 				</xsl:when>
 				<xsl:otherwise>
 					<xsl:copy>
-						<xsl:choose>
-							<xsl:when test="$remove-before">
-								<xsl:copy-of select="@*[name()!='before']"/>
-							</xsl:when>
-							<xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
-						</xsl:choose>
+						<xsl:call-template name="merge-copy-of-atts">
+							<xsl:with-param name="remove-before" select="$remove-before"/>
+							<xsl:with-param name="root" select="$root"/>
+						</xsl:call-template>
 						<xsl:copy-of select="exslt:node-set($content)"/>
 					</xsl:copy>
 				</xsl:otherwise>
@@ -467,11 +542,27 @@
 	<xsl:copy-of select="."/>
 </xsl:template>
 
+
+<xsl:template name="merge-copy-of-atts">
+	<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
+	<xsl:param name="root"/> 	<!--the systemModel element in the upstream doc  -->
+	<xsl:choose>
+		<xsl:when test="$remove-before">
+			<xsl:copy-of select="@*[name()!='before' and name()!='replace']"/>
+		</xsl:when>
+		<xsl:otherwise><xsl:copy-of select="@*[name()!='replace']"/></xsl:otherwise>
+	</xsl:choose>
+	<xsl:if test="@replace and not($root/descendant::*[(self::component or self::collection or self::package or self::layer) and @id=current()/@replace])">
+		<!-- only include replace if it's not been used -->
+		<xsl:copy-of select="@replace"/>
+	</xsl:if>
+</xsl:template>
+
 <xsl:template match="component" mode="merge-copy-of">
 	<xsl:param name="remove-before" select="0"/> <!-- set to true if any before attribute is to be removed -->
 	<xsl:param name="origin"/>	<!--the element containing the @name to use the origin-model attribute  -->
 	<xsl:param name="root"/> 	<!--the systemModel element in the upstream doc  -->
-	
+
 	<xsl:choose>
 		<!-- this might slow things down, consider making optional -->
 		<xsl:when test="$root/descendant::collection[@id!=current()/../@id]/component[@id=current()/@id]">
@@ -481,12 +572,10 @@
 		</xsl:when>
 		<xsl:otherwise>
 			<xsl:copy>
-				<xsl:choose>
-					<xsl:when test="$remove-before">
-						<xsl:copy-of select="@*[name()!='before']"/>
-					</xsl:when>
-					<xsl:otherwise><xsl:copy-of select="@*"/></xsl:otherwise>
-				</xsl:choose>
+				<xsl:call-template name="merge-copy-of-atts">
+					<xsl:with-param name="remove-before" select="$remove-before"/>
+					<xsl:with-param name="root" select="$root"/>
+				</xsl:call-template>
 				<xsl:if test="not(@origin-model) and $origin/@name">
 					<xsl:attribute name="origin-model">
 						<xsl:value-of select="$origin/@name"/>
--- a/bldsystemtools/sysdeftools/mergesysdef.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/mergesysdef.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -22,10 +22,16 @@
 <xsl:variable name="downstream" select="document($Downstream,.)/SystemDefinition"/>
 <xsl:param name="upname">
 	<xsl:choose>
-		<xsl:when test="$downstream[starts-with(@schema,'2.') or starts-with(@schema,'1.')  or not(systemModel)]">
+		<xsl:when test="$downstream[starts-with(@schema,'2.') or starts-with(@schema,'1.')]">
 			<xsl:message terminate="yes">Syntax <xsl:value-of select="@schema"/> not supported</xsl:message>
 		</xsl:when>
-		<xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name">
+		<xsl:when test="name($downstream/*)!=name(/SystemDefinition/*)">
+			<xsl:message terminate="yes">Can only merge fragments of the same rank</xsl:message>
+		</xsl:when>
+<!--		<xsl:when test="$downstream[not(systemModel)]">
+			<xsl:message terminate="yes">Needs to be a standalone system definition</xsl:message>
+		</xsl:when>-->
+		<xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name or not(/SystemDefinition/systemModel/@name)">
 			<xsl:apply-templates mode="origin-term" select="/*">
 				<xsl:with-param name="root">Upstream</xsl:with-param>
 			</xsl:apply-templates>
@@ -36,11 +42,14 @@
 
 <xsl:param name="downname">
 	<xsl:choose>
-		<xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name">
+		<xsl:when test="/SystemDefinition/systemModel/@name=$downstream/systemModel/@name or not($downstream/systemModel/@name)">
 			<xsl:apply-templates mode="origin-term" select="$downstream">	
 				<xsl:with-param name="root">Downstream</xsl:with-param>
 			</xsl:apply-templates>
 			</xsl:when>
+		<xsl:when test="name($downstream/*)!=name(/SystemDefinition/*)">
+			<xsl:message terminate="yes">Can only merge fragments of the same rank</xsl:message>
+		</xsl:when>
 		<xsl:otherwise><xsl:value-of select="$downstream/systemModel/@name"/></xsl:otherwise>
 	</xsl:choose>
 </xsl:param>
@@ -68,7 +77,21 @@
 </xsl:template>
 
 
-<!--  this merge only two files according to the 3.0.0 rules. Old syntax not supported. Must be converetd before calling -->
+<!-- choose the greater of the two versions -->
+<xsl:template name="compare-versions"><xsl:param name="v1"/><xsl:param name="v2"/>
+			<xsl:choose>
+				<xsl:when test="$v1=$v2"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before($v1,'.') &gt; substring-before($v2,'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before($v1,'.') &lt; substring-before($v2,'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:when test="substring-before(substring-after($v1,'.'),'.') &gt; substring-before(substring-after($v2,'.'),'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-before(substring-after($v1,'.'),'.') &lt; substring-before(substring-after($v2,'.'),'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:when test="substring-after(substring-after($v1,'.'),'.') &gt; substring-after(substring-after($v2,'.'),'.')"><xsl:value-of select="$v1"/></xsl:when>
+				<xsl:when test="substring-after(substring-after($v1,'.'),'.') &lt; substring-after(substring-after($v2,'.'),'.')"><xsl:value-of select="$v2"/></xsl:when>
+				<xsl:otherwise><xsl:value-of select="$v1"/></xsl:otherwise>
+			</xsl:choose>
+</xsl:template>
+
+<!--  this merge only two files according to the 3.0.x rules. Old syntax not supported. Must be converetd before calling -->
 
 
 
--- a/bldsystemtools/sysdeftools/sysdefdowngrade.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/sysdefdowngrade.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -106,6 +106,7 @@
 		<xsl:choose>
 			<xsl:when test="@href">
 				<xsl:variable name="this" select="."/>
+				<xsl:variable name="prefixmap" select="ancestor::SystemDefinition/*/meta[@rel='link-mapping']/map-prefix[starts-with(current()/@href,@link)]"/>
 				<xsl:for-each select="document(@href,.)/SystemDefinition/*">
 					<xsl:variable name="my-id"><xsl:apply-templates mode="normalize-id" select="@id"/></xsl:variable>
 					<xsl:variable name="other-id"><xsl:apply-templates mode="normalize-id" select="$this/@id"/></xsl:variable>
@@ -124,9 +125,31 @@
 					</xsl:for-each>
 					<xsl:apply-templates select="*|comment()">
 	  					<xsl:with-param name="path">
-	  						<xsl:call-template name="normpath">
-	  							<xsl:with-param name="path" select="concat($path,'/',$this/@href)"/>
-	  						</xsl:call-template>
+							<xsl:choose>
+								<xsl:when test="$prefixmap">
+	  								<xsl:call-template name="normpath">
+	  									<xsl:with-param name="path">
+										<xsl:apply-templates select="$prefixmap/@to"/>
+										<xsl:value-of select="substring-after($this/@href,$prefixmap/@link)"/>
+									 </xsl:with-param>
+	  								</xsl:call-template>
+								</xsl:when>
+								<xsl:when test="starts-with($this/@href,'/')">  <!-- absolute path -->
+	  								<xsl:call-template name="normpath">
+	  									<xsl:with-param name="path" select="$this/@href"/>
+	  								</xsl:call-template>
+								</xsl:when>
+								<xsl:when test="contains($this/@href,'://')">  <!-- generic URI -->
+	  								<xsl:call-template name="normpath">
+	  									<xsl:with-param name="path" select="substring-after($this/@href,'://')"/>
+	  								</xsl:call-template>
+								</xsl:when>
+								<xsl:otherwise>
+	  								<xsl:call-template name="normpath">
+	  									<xsl:with-param name="path" select="concat($path,'/',$this/@href)"/>
+	  								</xsl:call-template>
+								</xsl:otherwise>
+							</xsl:choose>
 	  					</xsl:with-param> 
 	  				</xsl:apply-templates>
 				</xsl:for-each>
@@ -211,7 +234,11 @@
 		<xsl:choose>
 			<xsl:when test="../@root">
 				<xsl:variable name="pre" select="substring-before(substring-after($root,concat(' ',../@root,'=')),' ')"/>
-				<xsl:if test="$pre!=''"><xsl:value-of select="concat($pre,'/')"/></xsl:if>
+				<xsl:value-of select="$pre"/>
+				<xsl:if test="$pre!='' and $pre!='/'">/</xsl:if>
+			</xsl:when>
+			<xsl:when test="$srcroot='/'"> <!-- treat all paths as absolute -->
+				<xsl:value-of select="$srcroot"/>
 			</xsl:when>
 			<xsl:when test="$srcroot!=''">
 				<xsl:value-of select="concat($srcroot,'/')"/>
@@ -241,6 +268,15 @@
 	<xsl:copy-of select="info/@contract"/>
 </xsl:template>
 
+
+<xsl:template match="meta[@rel='link-mapping']/map-prefix/@to">
+	<xsl:choose>
+		<xsl:when test="starts-with(.,'/')"><xsl:value-of select="substring(.,2)"/></xsl:when> <!-- absolute paths in 3.0 are relative in 2.0 -->
+		<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
+	</xsl:choose>
+</xsl:template>
+
+
 <xsl:template match="@id" mode="normalize-id">
 	<xsl:choose>
 		<xsl:when test="contains(@id,':')"><xsl:value-of select="substring-after(@id,':')"/></xsl:when>
--- a/bldsystemtools/sysdeftools/validate/checklinks.pl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/validate/checklinks.pl	Wed Jun 23 19:29:20 2010 +0300
@@ -1,4 +1,4 @@
-# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 # All rights reserved.
 # This component and the accompanying materials are made available
 # under the terms of "Eclipse Public License v1.0"
@@ -12,97 +12,524 @@
 #
 # Description:
 # Script to validate the unit links in a system definition or package definition XML file
+#!/usr/bin/perl
 
 use strict;
 
-if (! scalar @ARGV) {&help()}
+
+use FindBin;		# for FindBin::Bin
+use lib $FindBin::Bin;
+use lib "$FindBin::Bin/lib";
+
+use Cwd;
+use Cwd 'abs_path';
+use Getopt::Long;
+use File::Basename;
+use File::Spec;
+use XML::DOM;
+
+my $output;
+my $path;
+my %defineParams;
+my %defines;
+my $defaultns = 'http://www.symbian.org/system-definition';	# needed if no DTD
+my $realloc;
+
+# need to add options for controlling which metas are filtered out and which are included inline
+GetOptions
+	(
+	'path=s' => $path,
+	 'effective-sysdef=s' => \$realloc
+	);
+
+# -path specifies the full system-model path to the file which is being processed. 
+#	This must be an absolute path if you're processing a root sysdef.
+#	If processing a pkgdef file, you can use "./package_definition.xml" to leave all links relative. Though I can't really see the use case for this.
+
+
+# if config is not set, no confguration will be done.
+# If it is set, all configuration metadata will be processed and stripped from the output, even if the confguration data is empty
+
+ if($path eq '') {$path = '/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml'}
+
+($#ARGV == -1 ) && &help();
+my $sysdef = &abspath(shift);	# resolve the location of the root sysdef
+
+$realloc = $realloc || $sysdef;
+
+my %unitmap;
+my @p1=reverse(split(/[\\\/]/,$path));
+my @p2=reverse(split(/[\\\/]/,$realloc));
+
+shift(@p1);shift(@p2); # don't care abt file name
+while(lc($p1[0]) eq lc($p2[0])) {shift(@p1);shift(@p2)}
+
+$unitmap{join('/',reverse(@p1))} = join("/",reverse(@p2));
+
+my @p1=reverse(split(/[\\\/]/,$sysdef));
+my @p2=reverse(split(/[\\\/]/,$realloc));
+
+shift(@p1);shift(@p2); # don't care abt file name
+while(lc($p1[0]) eq lc($p2[0])) {shift(@p1);shift(@p2)}
+
+$unitmap{join('/',reverse(@p1))} = join("/",reverse(@p2));
+
+
+# rootmap is a mapping from the filesystem to the paths in the doc
+my %rootmap = &rootMap($path,$sysdef);	
+my %nsmap;
+my %urimap;
+
+my $parser = new XML::DOM::Parser;
+my   $sysdefdoc = $parser->parsefile ($sysdef);
+
+
+my $maxschema = $sysdefdoc->getDocumentElement()->getAttribute('schema');	# don't check value, just store it.
+
+my $docroot =  $sysdefdoc->getDocumentElement;
+
+my $ns = $docroot->getAttribute('id-namespace');
+if(!$ns && $nsmap{''})
+	{
+	$docroot->setAttribute('id-namespace',$nsmap{''});
+	}
+
+$docroot->setAttribute('schema',$maxschema);	# output has the largest syntax version of all includes
+
+
+while(my($pre,$uri) = each(%nsmap))
+	{
+	$pre ne '' || next ;
+	$docroot->setAttribute("xmlns:$pre",$uri);
+	}
+
+&walk($sysdef,$docroot);	# process the XML
+
+ 
+sub abspath
+	{ 	# normalize the path into an absolute one
+	my  ($name,$path) = fileparse($_[0]);
+	$path=~tr,\\,/,;
+	if( -e $path)
+		{
+		return abs_path($path)."/$name";
+		}
+	my @dir = split('/',$_[0]);
+	my @new;
+	foreach my $d (@dir)
+		{
+		if($d eq '.') {next}
+		if($d eq '..')
+			{
+			pop(@new);
+			next;
+			}
+		push(@new,$d)
+		}
+	return join('/',@new);
+	}
+
+sub rootMap {
+	my @pathdirs = split(/\//,$_[0]);
+	my @rootdirs = split(/\//,$_[1]);
+
+	while(lc($rootdirs[$#rootdirs])  eq lc($pathdirs[$#pathdirs])  )
+		{
+		pop(@rootdirs);
+		pop(@pathdirs);
+		}
+	return (join('/',@rootdirs)  => join('/',@pathdirs) );
+	}
+
+sub rootMapMeta {
+	# find all the explict path mapping from the link-mapping metadata
+	my $node = shift;
+	foreach my $child (@{$node->getChildNodes})
+			{
+			if ($child->getNodeType==1 && $child->getTagName eq 'map-prefix')
+				{
+				my $from = $child->getAttribute('link');
+				my $to = $child->getAttribute('to');		# optional, but blank if not set
+				$rootmap{$from} = $to;
+				}
+			}
+	# once this is processed we have no more need for it. Remove from output
+	$node->getParentNode->removeChild($node);
+	}
 
 
-my $debug = 0;
-my $skipfilter;	# skip anything with a named filter
-my $xslt = "../../../buildtools/bldsystemtools/buildsystemtools/joinsysdef.xsl";
-my $xalan = "../../../buildtools/devlib/devlibhelp/tools/doc_tree/lib/apache/xalan.jar";
-my $sysdef = shift;
-while($sysdef=~/^-/) { #arguments
-	 if($sysdef eq '-nofilter') {$skipfilter = shift}
-	 elsif($sysdef eq '-v') {$debug = 1}
-	 else { &help("Invalid command line option $sysdef")} 
-	 $sysdef = shift; 
-}
-my $dir = $sysdef;
-$dir =~ s,[^\\/]+$,,;
-my $root="../../../..";
- my $full;
- 
-if($sysdef=~/system_definition\.xml/) {	# if running on a sysdef, ensure it's joined before continuing
-	($full = `java -jar $dir$xalan -in $sysdef -xsl $dir$xslt`) || die "bad XML syntax";
-}else {	# assume any other file has no hrefs to include (valid by convention)
-	$root='';
-	open S, $sysdef;
-	$full=join('',<S>);
-	close S;
-}
-$full=~s/<!--.*?-->//sg; # remove all comments;
-my $count=1;
+sub walk
+	{ 	# walk through the doc, resolving all links
+	my $file = shift;
+	my $node = shift;
+	my $type = $node->getNodeType;
+	if($type!=1) {return}
+	my $tag = $node->getTagName;
+	if($tag=~/^(layer|package|collection|component)$/ )
+		{
+		my $link= $node->getAttribute('href');
+		if($link)
+			{
+			my $file = &resolvePath($file,$link); 
+			if(-e $file)
+				{
+				&combineLink($node,$file);
+				}
+			else
+				{
+				print  "Note: $file not found\n";
+				$node->removeAttribute('href');
+				}
+			return;
+			}
+		}
+	elsif($tag=~/^(SystemDefinition|systemModel)$/ )
+		{
+		}
+	elsif($tag eq 'unit')
+		{
+		my %at = &atts($node);
+		my $pro;
+		foreach my $o (keys(%at)) 
+			{
+			if($o eq 'proFile' || $o=~/:proFile$/)
+				{
+				$pro = $at{$o};
+				last;
+				}
+			}
+		my $filter=$node->getParentNode()->getAttribute('filter');
+		if($filter ne '' && $at{'filter'}) {$filter.=','.$at{'filter'}}
+		elsif($at{'filter'}) {$filter=$at{'filter'}}
+		if($filter ne '') {$filter="\t($filter)"}
+		foreach my $atr ('bldFile','mrp','base')
+			{
+			my $ext;
+			my $link= $at{$atr};
+			if($atr eq 'bldFile') {
+				$ext = ($pro ne '') ? "/$pro" : '/bld.inf'
+			}
+			if($link ne '')
+				{
+				my $ok = 0;
+				my $trylink;
+				if($link && !($link=~/^\//))
+					{
+					$link= &abspath(File::Basename::dirname($file)."/$link");
+					$ok = (-e "$link$ext");
+					if(!$ok)	
+						{
+						foreach my $a (keys %rootmap)
+							{
+							$link=~s,^$a,$rootmap{$a},ie;
+							# remove leading ./  which is used to indicate that paths should remain relative
+							$link=~s,^\./([^/]),$1,; 
+							}
 
-my $filter = '';
-foreach (split(/</,$full)) {	# loop through all elements
-	my $found = 0;
-	if(/^component/) {		# save the current filter so we know if we need to skip the named filter
-		$filter='';
-		if(/filter="([^"]+)"/) {$filter=$1}
+						}
+					}
+				if(!$ok)
+					{
+					foreach my $a (keys %unitmap) {
+						if($a eq substr($link,0,length($a))) {
+							$trylink = $unitmap{$a}.substr($link,length($a));
+							if(-e "$trylink$ext") {
+								$ok=1;
+								$link = $trylink;
+								last;
+							}
+						}
+					}
+					}
+				if(!$ok)
+					{
+					print "Error: $atr not found in ",($trylink ne '') ? $trylink : $link,"$filter\n";
+					}				
+				}
+			}
+		}
+	elsif($tag eq 'meta')
+		{
+		my $rel= $node->getAttribute('rel') || 'Generic';
+		my $link= $node->getAttribute('href');
+		$link=~s,^file://(/([a-z]:/))?,$2,; # convert file URI to absolute path
+		if ($link ne '' ) 
+			{ 
+			if($link=~/^[\/]+:/)
+				{
+				print  "Note: Remote URL $link not validated\n";
+				next; # do not alter children
+				}
+			if(! ($link=~/^\//))
+				{
+				$link= &abspath(File::Basename::dirname($file)."/$link");
+				}
+			if(! -e $link) 
+				{
+				if(! -e &realPath($link)) {
+					print  "Warning: Local metadata file not found: $link\n";
+				}
+				next; # do not alter children
+				}
+			}
+		if($node->getAttribute('rel') eq 'link-mapping')
+			{# need to process this now
+			&rootMapMeta($node);
+			}
+		return;
+		}
+	else {return}
+	my $checkversion=0;
+	foreach my $item (@{$node->getChildNodes})
+		{
+		#print $item->getNodeType,"\n";
+		&walk($file,$item);
+		}
+
+
+
 	}
-	elsif(s/^unit//) {
-		my $f=",$filter,";		# commas are the separators - safe to have extra ones for testing
-		if(/filter="([^"]+)"/) {$f.=",$1,"}
-		if($skipfilter ne '' && $f=~/,$filter,/) {next}	# don't test anything with s60 filter
-		if(/\smrp="(.*?)"/) {
-			my $file = &fileLocation($1);
-			if($debug) {print "MRP ",-s $file," $file\n"}		# debug code		
-			if(!(-s $file)){
-				print  STDERR "$count: Cannot find MRP file $file\n";	
-				$found=1;
+
+
+sub realPath
+	{
+	my $link = shift;
+	foreach my $a (keys %unitmap)
+		{
+		if($a eq substr($link,0,length($a))) 
+			{
+			my $trylink = $unitmap{$a}.substr($link,length($a));
+			if(-e $trylink) {return $trylink}
 			}
 		}
-		if(/\sbldFile="(.*?)"/) {
-			my $file = &fileLocation("$1/bld.inf");
-			if($debug) {print "Bld ",-s $file ," $file\n"}		# debug code		
-			if(!(-s $file) ){
-				print  STDERR "$count: Cannot find bld.inf file $file\n";
-				$found=1;
+	}
+
+sub combineLink
+	{
+	# combine data from linked sysdef fragment w/ equivalent element in parent document
+	my $node = shift;
+	my $file = shift;
+	my $getfromfile = &localfile($file);
+	$getfromfile eq '' && return;  # already raised warning, no need to repeat
+	my  $doc = $parser->parsefile ($getfromfile);
+	my $item =&firstElement($doc->getDocumentElement);
+	$item || die "badly formatted $file";	
+	&fixIDs($item);
+	my %up = &atts($node);
+	my %down = &atts($item);
+	$up{'id'} eq $down{'id'}  || die "$up{id} differs from $down{id}";
+	$node->removeAttribute('href');
+	foreach my $v (keys %up) {delete $down{$v}}
+	foreach my $v (keys %down)
+		{
+		$node->setAttribute($v,$down{$v})
+		}
+	foreach my $child (@{$item->getChildNodes})
+		{
+		&copyInto($node,$child);
+		}
+	&walk($file,$node);
+	}
+
+
+sub copyInto
+	{
+	# make a deep copy the node (2nd arg) into the element (1st arg)
+	my $parent=shift;
+	my $item = shift;
+	my $doc = $parent->getOwnerDocument;
+	my $type = $item->getNodeType;
+	my $new;
+	if($type==1) 
+		{
+		&fixIDs($item);
+		$new = $doc->createElement($item->getTagName);
+		my %down = &atts($item);
+		foreach my $ordered ('id','name','bldFile','mrp','level','levels','introduced','deprecated','filter')
+			{
+			if($down{$ordered})
+				{
+				$new->setAttribute($ordered,$down{$ordered});
+				delete $down{$ordered}
+				}
+			}
+		while(my($a,$b) = each(%down))
+			{
+			$new->setAttribute($a,$b);
+			}
+		foreach my $child (@{$item->getChildNodes})
+			{
+			&copyInto($new,$child);
 			}
 		}
-		if(/\sbase="(.*?)"/) {
-			my $file = &fileLocation($1);
-			if($debug) {print "Base $file\n"}		# debug code		
-			if(!(-d $file) ){
-				print  STDERR "$count: Cannot find base dir $file\n";
-				$found=1;
-			}
+	elsif($type==3) 
+		{
+		$new = $doc->createTextNode ($item->getData);
+		}
+	elsif($type==8) 
+		{
+		$new = $doc->createComment  ($item->getData);
+		}
+	if($new)
+		{
+		$parent->appendChild($new);
 		}
-	}	
-	$count+=$found;	
+	}
+
+sub getNs
+	{
+	# find the namespace URI that applies to the specified prefix.
+	my $node = shift;
+	my $pre = shift;
+	my $uri = $node->getAttribute("xmlns:$pre");
+	if($uri) {return $uri}
+	my $parent = $node->getParentNode;
+	if($parent && $parent->getNodeType==1)
+		{
+		return getNs($parent,$pre);
+		}
+	}
+
+
+sub fixIDs
+	{
+	# translate the ID to use the root doc's namespaces 
+	my $node = shift;
+	foreach my $id ('id','before')
+		{
+		&fixID($node,$id);
+		}
 }
 
-exit $count;
+sub fixID
+	{
+	# translate the ID to use the root doc's namespaces 
+	my $node = shift;
+	my $attr = shift || 'id';
+	my $id = $node->getAttribute($attr);
+	if($id eq '') {return}
+	my $ns;
+	if($id=~s/^(.*)://)
+		{ # it's got a ns, find out what it is
+		my $pre = $1;
+		$ns=&getNs($node,$pre);
+		}
+	else
+		{
+		$ns = $node->getOwnerDocument->getDocumentElement->getAttribute("id-namespace") ||
+			$defaultns;
+		}
+	$ns = $urimap{$ns};
+	$id = ($ns eq '') ? $id : "$ns:$id";
+	return $node->setAttribute($attr,$id);
+}
 
-sub fileLocation {
-	my $file = "$dir$root$_[0]";
-	$file=~tr/\//\\/;
-	while($file=~s/\\[^\\.]+\\\.\.\\/\\/){}
-	return $file;
+sub firstElement {
+	# return the first element in this node
+	my $node = shift;
+	foreach my $item (@{$node->getChildNodes}) {
+		if($item->getNodeType==1) {return $item}
+	}
+}
+
+
+sub atts {
+	# return a hash of all attribtues defined for this element
+	my $node = shift;
+	my %at = $node->getAttributes;
+	my %list;
+	foreach my $a (keys %{$node->getAttributes}) 
+		{
+		if($a ne '')
+			{
+			$list{$a} = $node->getAttribute ($a);
+			}
+		}
+	return %list;
 }
-sub help {
-	print "$0: ",($_[0] eq '' ? "syntax"  : $_[0]); 
-	print "\nSyntax: [-v] [-nofilter filter] system_definition.xml 
-Validate the unit links in a system definition or package definition XML
-file. This only prints errors in the files. If it exits silently, the links
-are all valid.
-	Call with -nos60 filter to skip checking presence of fitler=\"s60\" units
-	Requires system definition files to be in the standard location
-	in deviceplatformrelease,
-	and the presence of joinsysdef.xsl and xalan.jar in their expected
-	locations.
-	Package definition files can be anywhere.";
-exit 1;
-}
+
+
+sub ns 
+	{
+	# return a hash of ns prefix and uri -- the xmlns: part is stripped off
+	my $node = shift;
+	my %list;
+	foreach my $a (keys %{$node->getAttributes}) 
+		{
+		my $pre = $a;
+		if($pre=~s/^xmlns://)
+			{
+			$list{$pre} = $node->getAttribute ($a);
+			}
+		}
+	return %list;
+	}
+
+
+sub resolvePath
+	{
+	# return full path to 2nd arg relative to first (path or absolute URI)
+	my $base = shift;
+	my $path = shift;
+	if($path=~m,^/,) {return $path } # path is absolute, but has no drive. Let OS deal with it.
+	if($path=~s,^file:///([a-zA-Z]:/),$1,) {return $path } # file URI with drive letter
+	if($path=~m,^file://,) {return $path } # file URI with no drive letter (unit-style). Just pass on as is with leading / and let OS deal with it
+	if($path=~m,^[a-z0-9][a-z0-9]+:,i) {return $path } # absolute URI -- no idea how to handle, so just return
+	return &abspath(File::Basename::dirname($base)."/$path");
+	}
+
+
+sub resolveURI
+	{
+	# return full path to 2nd arg relative to first (path or absolute URI)
+	my $base = shift;
+	my $path = shift;
+	if($path=~m,[a-z0-9][a-z0-9]+:,i) {return $path } # absolute URI -- just return
+	if($path=~m,^/,) {return $path } # path is absolute, but has no drive. Let OS deal with it.
+	return &abspath(File::Basename::dirname($base)."/$path");
+	}
+
+sub localfile
+	{
+	my $file = shift;
+	if($file=~s,file:///([a-zA-Z]:/),$1,) {return $file } # file URI with drive letter
+	if($file=~m,file://,) {return $file } # file URI with no drive letter (unit-style). Just pass on as is with leading / and let OS deal with it
+	if($file=~m,^([a-z0-9][a-z0-9]+):,i)
+		{
+		print  "ERROR: $1 scheme not supported\n";
+		return;  # return empty string if not supported.
+		} 
+	return $file
+	}
+
+
+
+	
+
+sub help
+	{
+	my $name= $0; $name=~s,^.*[\\/],,;
+my $text;
+format STDERR =
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+  $text,
+     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
+    $text
+.
+print STDERR "usage: $name  [options...] sysdef\n  valid options are:\n\n";
+	foreach (
+		"-path [sm-path]\tspecifies the full system-model path to the file which is being processed. By default this is  \"/os/deviceplatformrelease/foundation_system/system_model/system_definition.xml\"",
+			"   This must be an absolute path if you're processing a root sysdef.",
+			"   If processing a pkgdef file, you can use \"./package_definition.xml\" to leave all links relative.",
+		"effective-sysdef [local-file]\tspecifies another local filesystem location the sysdef should be considered when resolving linked metas and unit paths, but not system model item hrefs. This is mainly used for testing system-wide changes to pkgdefs since it allows the pkgdefs to exist in a separate location to the rest of the codeline"
+		) {
+		$text = $_;
+		write STDERR;
+		print STDERR "\n";
+	}
+
+	exit(1);
+	}
+
+
+	
--- a/bldsystemtools/sysdeftools/validate/test-model.xsl	Fri Jun 11 14:46:46 2010 +0300
+++ b/bldsystemtools/sysdeftools/validate/test-model.xsl	Wed Jun 23 19:29:20 2010 +0300
@@ -2,7 +2,7 @@
 <!--Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 	All rights reserved.
 	This component and the accompanying materials are made available
-	under the terms of "Eclipse Public License v1.0"
+	under the terms of the License "Eclipse Public License v1.0"
 	which accompanies this distribution, and is available
 	at the URL "http://www.eclipse.org/legal/epl-v10.html".
 
@@ -52,12 +52,12 @@
 </xsl:apply-templates>
 </xsl:template>
 
-<xsl:template match="/SystemDefinition[@schema='3.0.0']" mode="ids">
+<xsl:template match="/SystemDefinition[starts-with(@schema,'3.0.')]" mode="ids">
 	<xsl:for-each select="//*[@id and not(@href)]"><xsl:value-of select="concat(' ',@id,' ')"/></xsl:for-each>
 	<xsl:apply-templates select="document(//layer/@href | //package/@href | //collection/@href | //component/@href,.)/*" mode="ids"/>
 </xsl:template>
 
-<xsl:template match="/SystemDefinition[@schema='3.0.0' and systemModel]" priority="2">
+<xsl:template match="/SystemDefinition[starts-with(@schema,'3.0.')and systemModel]" priority="2">
 	<xsl:param name="filename" select="$Filename"/>
 <xsl:call-template name="Section">
 	<xsl:with-param name="text">System Definition: <xsl:value-of select="*/@name"/></xsl:with-param>
@@ -68,7 +68,7 @@
 	</xsl:apply-templates>
 </xsl:template>
 
-<xsl:template match="/SystemDefinition[@schema='3.0.0'] | systemModel">
+<xsl:template match="/SystemDefinition[starts-with(@schema,'3.0.')] | systemModel">
 	<xsl:param name="filename"  select="$Filename"/>
 		
 <xsl:if test="//unit">
@@ -97,6 +97,15 @@
 <xsl:template match="component/@introduced|component/@deprecated" mode="valid"/> 
 
 
+
+<xsl:template match="@replace" mode="valid">
+	<xsl:if test="/SystemDefinition[@schema='3.0.0']">
+		<xsl:call-template name="Error"><xsl:with-param name="text">Attribute <b><xsl:value-of select="name()"/></b>="<xsl:value-of select="."/>" not valid in schema <xsl:value-of select="/SystemDefinition/@schema"/>. Must use schema 3.0.1 or higher</xsl:with-param></xsl:call-template>
+	</xsl:if>
+</xsl:template>
+
+
+
 <xsl:template name="validate-class">
 	<ok>plugin</ok>
 	<ok>doc</ok>
@@ -202,11 +211,12 @@
 <xsl:apply-templates select="@id"/>
 <xsl:if test="self::component">
 	<xsl:choose>
-		<xsl:when test="count(*[not(@version)]) &gt; 1 and @filter='s60'">
-			<xsl:call-template name="Warning"><xsl:with-param name="text">S60 Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(*)"/> children.</xsl:with-param></xsl:call-template>
+		<xsl:when test="count(unit[not(@filter | @version)]) = 0 "/>
+		<xsl:when test="count(unit[not(@version)]) &gt; 1 and @filter='s60'">
+			<xsl:call-template name="Warning"><xsl:with-param name="text">S60 Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
 		</xsl:when>
-		<xsl:when test="count(*[not(@version)]) &gt; 1">
-			<xsl:call-template name="Error"><xsl:with-param name="text">Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(*)"/> children.</xsl:with-param></xsl:call-template>
+		<xsl:when test="count(unit[not(@version)]) &gt; 1">
+			<xsl:call-template name="Error"><xsl:with-param name="text">Component "<xsl:value-of select="@id"/>" has <xsl:value-of select="count(unit)"/> units.</xsl:with-param></xsl:call-template>
 		</xsl:when>
 	</xsl:choose>
 	<xsl:choose>
@@ -264,6 +274,13 @@
 </xsl:template>
 
 
+
+<xsl:template match="meta">	<xsl:param name="filename"/>
+	<xsl:apply-templates select="@*"/>
+</xsl:template>
+
+<xsl:template match="meta/@rel | meta/@type | meta/@href"/> <!-- anything is valid -->
+
 <xsl:template match="unit">	<xsl:param name="filename"/>
 	<xsl:apply-templates select="@mrp|@bldFile">
 		<xsl:with-param name="filename" select="$filename"/>
@@ -291,8 +308,63 @@
 </xsl:template>
 
 
+<xsl:template mode="localid" match="*">
+	<xsl:choose>
+		<xsl:when test="contains(@id,':')">/<xsl:value-of select="substring-after(@id,':')"/></xsl:when>
+		<xsl:otherwise><xsl:value-of select="@id"/></xsl:otherwise>
+	</xsl:choose>
+</xsl:template>
 <xsl:template match="@bldFile|@mrp"><xsl:param name="filename"/>
+<xsl:if test="substring(.,string-length(.))='/'">
+		<xsl:call-template name="Warning"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" should not end in /</xsl:with-param></xsl:call-template>
+</xsl:if>
+<xsl:if test="contains(.,'\')">
+		<xsl:call-template name="Error"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" must use only forward slashes</xsl:with-param></xsl:call-template>
+</xsl:if>
 
+<!-- this is a realtive path, so just check that it's the expected number of dirs down -->
+	<xsl:variable name="fullpath"><xsl:call-template name="normpath">
+				<xsl:with-param name="path">
+					<xsl:if test="not(starts-with(.,'/'))">
+						<xsl:call-template name="before">
+							<xsl:with-param name="text" select="$filename"/>
+						</xsl:call-template>
+					</xsl:if>
+					<xsl:value-of select="."/>
+				 </xsl:with-param>
+			</xsl:call-template>
+		</xsl:variable>
+		<xsl:variable name="path">
+			<xsl:choose>
+				<xsl:when test="not(contains($filename,':'))">/<xsl:for-each select="ancestor::*/@id"><xsl:apply-templates mode="path" select="."/>/</xsl:for-each></xsl:when>
+				<xsl:otherwise><xsl:for-each select="../../../@id|../../@id"><xsl:apply-templates mode="path" select="."/>/</xsl:for-each></xsl:otherwise>
+			</xsl:choose>
+		</xsl:variable>
+		<xsl:variable name="segment"> <!-- the part relative to the fragment directory -->
+			<xsl:choose>
+				<xsl:when test="ancestor::layer">
+					<xsl:apply-templates select="ancestor::package" mode="localid"/>/<xsl:apply-templates select="ancestor::collection" mode="localid"/>
+				</xsl:when>
+				<xsl:when test="ancestor::package">
+				<xsl:apply-templates select="ancestor::collection" mode="localid"/>
+				</xsl:when>
+				<xsl:when test="ancestor::collection"/>
+			</xsl:choose>/<xsl:apply-templates select="ancestor::component" mode="localid"/>/</xsl:variable>
+		<xsl:choose>
+			<xsl:when test="not(starts-with(concat(.,'/'),$segment))">
+				<xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong>: "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+			</xsl:when>
+		</xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="@bldFile[starts-with(.,'/') or contains(.,'../') or contains(.,':')] | @mrp[starts-with(.,'/') or contains(.,'../') or contains(.,':')] |@base[starts-with(.,'/') or contains(.,'../') or contains(.,':')]"><xsl:param name="filename"/>
+<xsl:if test="substring(.,string-length(.))='/'">
+		<xsl:call-template name="Warning"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" should not end in /</xsl:with-param></xsl:call-template>
+</xsl:if>
+<xsl:if test="contains(.,'\')">
+		<xsl:call-template name="Error"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" must use only forward slashes</xsl:with-param></xsl:call-template>
+</xsl:if>
 	<xsl:variable name="fullpath"><xsl:call-template name="normpath">
 				<xsl:with-param name="path">
 					<xsl:if test="not(starts-with(.,'/'))">
@@ -330,33 +402,26 @@
 	<xsl:when test="contains($filename,':')">
 		<xsl:choose>
 			<xsl:when test="not(starts-with(.,$path) or concat(.,'/')=$path)">
-				<xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
+				<xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong>: "<xsl:value-of select="."/>"</xsl:with-param></xsl:call-template>
 			</xsl:when>
 		</xsl:choose>
 	</xsl:when>
 	<xsl:otherwise>
 		<xsl:choose>
 			<xsl:when test="substring-before(substring($segment,2),'/') != substring-before(substring($path,2),'/') and (ancestor::SystemDefinition/@id-namespace!='http://www.symbian.org/system-definition' and not(contains(../../@id,':')))">
-				<xsl:call-template name="Warning"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+				<xsl:call-template name="Warning"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong>: "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
 			</xsl:when>
 			<xsl:when test="substring-before(substring($segment,2),'/') != substring-before(substring($path,2),'/')">
-				<xsl:call-template name="Error"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+				<xsl:call-template name="Error"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong>: "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
 			</xsl:when>
 			<xsl:when test="not(starts-with($segment,$path))">
-				<xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong> "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
+				<xsl:call-template name="Note"><xsl:with-param name="text">Unexpected <code><xsl:value-of select="name()"/></code> path for <xsl:apply-templates mode="path" select="../../../@id"/> -&gt; <strong><xsl:apply-templates mode="path" select="../../@id"/></strong>: "<xsl:value-of select="$fullpath"/>"</xsl:with-param></xsl:call-template>
 			</xsl:when>
 		</xsl:choose>
 	</xsl:otherwise>
 </xsl:choose>
-<xsl:if test="substring(.,string-length(.))='/'">
-		<xsl:call-template name="Warning"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" should not end in /</xsl:with-param></xsl:call-template>
-</xsl:if>
-<xsl:if test="contains(.,'\')">
-		<xsl:call-template name="Error"><xsl:with-param name="text"><code><xsl:value-of select="name()"/></code> path "<xsl:value-of select="."/>" must use only forward slashes</xsl:with-param></xsl:call-template>
-</xsl:if>
 </xsl:template>
 
-
 <xsl:template match="SystemDefinition" mode="check-matches">
 	<xsl:param name="which"/>
 	<xsl:param name="other"/>
--- a/package_definition.xml	Fri Jun 11 14:46:46 2010 +0300
+++ b/package_definition.xml	Wed Jun 23 19:29:20 2010 +0300
@@ -5,21 +5,10 @@
       <component id="sysdeftools" name="System Definition Tools" purpose="development" introduced="^2">
         <unit mrp="bldsystemtools/sysdeftools/group/sysdeftools.mrp"/>
       </component>
-      <component id="gttechviewbaseline" name="GT Techview Baseline" purpose="development">
-        <unit mrp="packaging/additionalutils/gt_techview_baseline.mrp"/>
-      </component>
       <component id="commonbldutils" name="Common Utils" purpose="development">
         <unit mrp="bldsystemtools/commonbldutils/tools_utils_common.mrp"/>
       </component>
     </collection>
-    <collection id="packaging" name="Packaging" level="ui">
-      <component id="additionalutils" name="Additional Utils" purpose="development">
-        <unit mrp="packaging/additionalutils/additional_unknown_cedar.mrp"/>
-      </component>
-      <component id="dummy" name="Dummy" purpose="development">
-        <unit bldFile="packaging/dummy" mrp="packaging/dummy/additional_dummy.mrp"/>
-      </component>
-    </collection>
     <collection id="toolsandutils" name="Tools and Utils" level="mw">
       <component id="productionbldtools" name="Production Build Tools" filter="gt" purpose="development">
         <unit mrp="toolsandutils/productionbldtools/product_tools.mrp"/>
@@ -27,15 +16,6 @@
       <component id="e32tools" name="E32 Tools" deprecated="^2" purpose="development" target="desktop">
         <unit bldFile="toolsandutils/e32tools/group" mrp="toolsandutils/e32tools/group/tools_e32tools.mrp"/>
       </component>
-      <component id="wincredistribution" name="WinC Redistribution" purpose="development" filter="test">
-        <unit mrp="dist_os/redistributionwinceka2/tools_redistribution_winc.mrp" bldFile="dist_os/redistributionwinceka2"/>
-      </component>
-      <component id="additionalredistribution" name="Additional Redistribution" purpose="development" filter="test">
-        <unit mrp="perltoolsplat_os/redistribution/additional_tools.mrp" bldFile="perltoolsplat_os/redistribution"/>
-      </component>
-      <component id="statapi" name="STAT API" filter="gt" purpose="development">
-        <unit bldFile="toolsandutils/statapi/source/statapi/console" mrp="toolsandutils/statapi/group/testtools_stat_device_gt.mrp"/>
-      </component>
       <component id="wintunnel" name="Wintunnel" purpose="development" filter="test">
         <unit mrp="toolsandutils/wintunnel/group/testtools_WinTunnel_srconly.mrp" bldFile="toolsandutils/wintunnel/group"/>
       </component>
@@ -44,7 +24,7 @@
       </component>
     </collection>
     <collection id="sbsv1_os" name="Symbian Build System v1" level="fw">
-      <component id="e32toolp" name="E32 Perl Tools" purpose="development" target="desktop" filter="test">
+      <component id="e32toolp" name="E32 Perl Tools" purpose="development" target="desktop" filter="sf_build">
         <unit mrp="sbsv1_os/e32toolp/group/tools_e32toolp.mrp" bldFile="sbsv1_os/e32toolp/group"/>
       </component>
 	  </collection>
--- a/toolsandutils/e32tools/elf2e32/include/h_ver.h	Fri Jun 11 14:46:46 2010 +0300
+++ b/toolsandutils/e32tools/elf2e32/include/h_ver.h	Wed Jun 23 19:29:20 2010 +0300
@@ -18,7 +18,7 @@
 
 const TInt MajorVersion=2;
 const TInt MinorVersion=1;
-const TInt Build=15;
+const TInt Build=16;
 
 #endif
 
--- a/toolsandutils/e32tools/elf2e32/source/parametermanager.cpp	Fri Jun 11 14:46:46 2010 +0300
+++ b/toolsandutils/e32tools/elf2e32/source/parametermanager.cpp	Wed Jun 23 19:29:20 2010 +0300
@@ -25,6 +25,7 @@
 #include "parametermanager.h"
 #include "errorhandler.h"
 #include <iostream>
+#include <ctype.h>
 
 #include "h_utl.h"
 #include "h_ver.h"
--- a/toolsandutils/e32tools/group/release.txt	Fri Jun 11 14:46:46 2010 +0300
+++ b/toolsandutils/e32tools/group/release.txt	Wed Jun 23 19:29:20 2010 +0300
@@ -1,3 +1,13 @@
+Version 2.1.16 (elf2e32)
+===============
+Made by Lorence Wang 29/04/2010
+  1. DEF145126 elf2e32 has compilation errors when buid with Gcc4.4 and STLport 5.2.1
+
+Version 2.2.1
+===============
+Made by Zheng Shen 02/03/2010
+  1. DEF144676 ELFTRAN'd give info in the illegal import of data message to allow debugging
+
 Version is unchanged
 ===============
 Made by Zheng Shen 24/08/2009