Index: src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportMojo.java
===================================================================
--- src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportMojo.java	(revision 439989)
+++ src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportMojo.java	(working copy)
@@ -16,7 +16,12 @@
  * limitations under the License.
  */
 
-import org.apache.maven.artifact.handler.ArtifactHandler;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
 import org.apache.maven.model.ReportPlugin;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.reporting.AbstractMavenReport;
@@ -22,15 +27,9 @@
 import org.apache.maven.reporting.AbstractMavenReport;
 import org.apache.maven.reporting.MavenReportException;
 import org.codehaus.doxia.site.renderer.SiteRenderer;
-import org.codehaus.plexus.util.PathTool;
+import org.codehaus.plexus.util.DirectoryScanner;
 import org.codehaus.plexus.util.StringUtils;
 
-import java.io.File;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-
 /**
  * Creates a nicely formatted Surefire Test Report in html format.
  *
@@ -47,7 +46,7 @@
      *
      * @parameter expression="${project.reporting.outputDirectory}"
      */
-    private String outputDirectory;
+    private File outputDirectory;
 
     /**
      * Doxia Site Renderer
@@ -118,12 +117,12 @@
 
         if ( linkXRef )
         {
-            String relativePath = PathTool.getRelativePath( outputDirectory, xrefLocation.getAbsolutePath() );
-            if ( StringUtils.isEmpty( relativePath ) )
-            {
-                relativePath = ".";
+            String relativePath = PathUtils.calculateRelativePath(
+                outputDirectory, xrefLocation);
+            if (relativePath != null && !relativePath.startsWith(".")) {
+                relativePath = "./" + relativePath;
             }
-            relativePath = relativePath + "/" + xrefLocation.getName();
+            
             if ( xrefLocation.exists() )
             {
                 // XRef was already generated by manual execution of a lifecycle binding
@@ -140,6 +139,7 @@
                     if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
                     {
                         location = relativePath;
+                        break;
                     }
                 }
             }
@@ -144,9 +144,12 @@
                 }
             }
 
-            if ( location == null )
-            {
-                getLog().warn( "Unable to locate Test Source XRef to link to - DISABLED" );
+            if (location == null) {
+                getLog().warn(
+                    "Unable to locate Test Source XRef to link to - DISABLED.");
+            } else {
+                getLog().info("Found relative path '" + location 
+                    + "' to link the Test Source XRef.");
             }
         }
         return location;
@@ -179,7 +182,7 @@
 
     protected String getOutputDirectory()
     {
-        return outputDirectory;
+        return outputDirectory.getAbsolutePath();
     }
 
     private ResourceBundle getBundle( Locale locale )
Index: src/main/java/org/apache/maven/plugins/surefire/report/PathUtils.java
===================================================================
--- src/main/java/org/apache/maven/plugins/surefire/report/PathUtils.java	
+++ src/main/java/org/apache/maven/plugins/surefire/report/PathUtils.java	
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.maven.plugins.surefire.report;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Util class for paths.
+ * 
+ * @author Martin Zeltner (MZE)
+ */
+abstract public class PathUtils {
+    /**
+     * Calculates the relative path from a source path to a target path.
+     * 
+     * @param sourcePath Is the place where to start the relative path.
+     * @param targetPath Is the place where to end the relative path.
+     * @return Returns the calculated relative path.
+     */
+    public static String calculateRelativePath(
+        File sourcePath, File targetPath) {
+        try {
+            String sourceDir = sourcePath.getCanonicalPath();
+            String targetDir = targetPath.getCanonicalPath();
+            return calculateRelativePath(sourceDir, targetDir);
+        } catch (IOException e) {
+            throw new RuntimeException(
+                "There was a problem while getting canonical path.", e);
+        }         
+    }
+
+    /**
+     * Calculates the relative path from a source path to a target path.
+     * 
+     * @param sourcePath Is the place where to start the relative path.
+     * @param targetPath Is the place where to end the relative path.
+     * @return Returns the calculated relative path.
+     */
+    public static String calculateRelativePath(
+        String sourcePath, String targetPath) {
+        if (StringUtils.isEmpty(sourcePath)
+            || StringUtils.isEmpty(targetPath)) {
+            return null;
+        }
+        
+        // Trim the given paths.
+        sourcePath = sourcePath.trim();
+        targetPath = targetPath.trim();
+        
+        // Replace backslashes with slashes.
+        sourcePath = sourcePath.replace('\\', '/');
+        targetPath = targetPath.replace('\\', '/');
+        
+        StringBuffer relativePath = new StringBuffer(); 
+        
+        String[] sourcePathParts = sourcePath.split("/");
+        String[] targetPathParts = targetPath.split("/");
+        
+        if (sourcePathParts.length == 0
+            || targetPathParts.length == 0) {
+            return null;
+        }
+        
+        int partIndex = 0;
+        while (targetPathParts.length > partIndex
+            && sourcePathParts.length > partIndex
+            && targetPathParts[partIndex].equalsIgnoreCase(
+                sourcePathParts[partIndex])) {
+            partIndex++;
+        }
+        for (int dirsUp = sourcePathParts.length - partIndex; 
+            dirsUp > 0; dirsUp--) {
+            if (relativePath.length() > 0) {
+                relativePath.append("/");
+            }
+            relativePath.append("..");
+        }
+        while (targetPathParts.length > partIndex) {
+            if (relativePath.length() > 0) {
+                relativePath.append("/");
+            }
+            relativePath.append(targetPathParts[partIndex]);
+            partIndex++;
+        }
+        return relativePath.length() > 0 ? relativePath.toString() : null;
+    }
+}
Index: src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportMojoTest.java
===================================================================
--- src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportMojoTest.java	(revision 442960)
+++ src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportMojoTest.java	(working copy)
@@ -43,7 +43,7 @@
 
         assertNotNull( mojo );
 
-        String outputDir = ( String ) getVariableValueFromObject( mojo, "outputDirectory" );
+        File outputDir = ( File ) getVariableValueFromObject( mojo, "outputDirectory" );
 
         boolean showSuccess = ( ( Boolean ) getVariableValueFromObject( mojo, "showSuccess" ) ).booleanValue();
 
@@ -55,7 +55,9 @@
 
         boolean linkXRef = ( ( Boolean ) getVariableValueFromObject( mojo, "linkXRef" ) ).booleanValue();
 
-        assertEquals( getBasedir() + "/target/site/unit/basic-surefire-report-test", outputDir );
+        assertEquals( getBasedir().replace('\\', '/') 
+            + "/target/site/unit/basic-surefire-report-test",
+            outputDir.getAbsolutePath().replace('\\', '/') );
 
         assertTrue( showSuccess );
 
Index: src/test/java/org/apache/maven/plugins/surefire/report/PathUtilsTest.java
===================================================================
--- src/test/java/org/apache/maven/plugins/surefire/report/PathUtilsTest.java	
+++ src/test/java/org/apache/maven/plugins/surefire/report/PathUtilsTest.java	
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.maven.plugins.surefire.report;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class for class
+ * <code>org.apache.maven.plugins.surefire.report.PathUtils</code>.
+ *
+ * @author Martin Zeltner (MZE)
+ */
+public class PathUtilsTest extends TestCase {
+    /**
+     * Test the relative path feature.
+     */
+    public void testCalculateRelativePath() {
+        // Test legal usage.
+        assertEquals("../test-set/xref", 
+            PathUtils.calculateRelativePath(
+                new File("C:/myproject/target/site/myreports/"), 
+                new File("C:/myproject/target/site/test-set/xref")));
+        assertEquals("../test-set/xref", 
+            PathUtils.calculateRelativePath(
+                "C:\\myproject\\target/site/myreports/", 
+                "C:/myproject/target/site/test-set/xref"));
+        assertEquals("xref", 
+            PathUtils.calculateRelativePath(
+                "C:\\myproject\\target/site/", 
+                "C:/myproject/target/site/xref/"));
+        assertEquals("..", 
+            PathUtils.calculateRelativePath(
+                "C:\\myproject\\target/site/", 
+                "C:/myproject/target/"));
+        
+        // Test illegal usage.
+        assertEquals(null, 
+            PathUtils.calculateRelativePath(
+                null, 
+                "C:/myproject/target/site/xref/"));
+        assertEquals(null, 
+            PathUtils.calculateRelativePath(
+                "C:\\myproject\\target/site/", 
+                ""));
+        assertEquals(null, 
+            PathUtils.calculateRelativePath(
+                "C:\\myproject\\target/site/", 
+                "  ///\\ "));
+    }
+}

