Index: src/main/java/org/apache/maven/doxia/site/decoration/inheritance/DefaultDecorationModelInheritanceAssembler.java
===================================================================
--- src/main/java/org/apache/maven/doxia/site/decoration/inheritance/DefaultDecorationModelInheritanceAssembler.java	(revision 491401)
+++ src/main/java/org/apache/maven/doxia/site/decoration/inheritance/DefaultDecorationModelInheritanceAssembler.java	(working copy)
@@ -16,6 +16,11 @@
  *
  */
 
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.maven.doxia.site.decoration.Banner;
 import org.apache.maven.doxia.site.decoration.Body;
 import org.apache.maven.doxia.site.decoration.DecorationModel;
@@ -23,14 +28,8 @@
 import org.apache.maven.doxia.site.decoration.Logo;
 import org.apache.maven.doxia.site.decoration.Menu;
 import org.apache.maven.doxia.site.decoration.MenuItem;
-import org.codehaus.plexus.util.PathTool;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
 /**
  * Manage inheritance of the decoration model.
  *
@@ -43,28 +42,22 @@
     public void assembleModelInheritance( String name, DecorationModel child, DecorationModel parent,
                                           String childBaseUrl, String parentBaseUrl )
     {
-        String prefix = getParentPrefix( parentBaseUrl, childBaseUrl );
+        URLContainer urlContainer = new URLContainer(parentBaseUrl, childBaseUrl);
 
-        if ( !prefix.endsWith( "/" ) )
-        {
-            prefix += "/";
-        }
-
         // cannot inherit from null parent.
         if ( parent != null )
         {
             if ( child.getBannerLeft() == null )
             {
                 child.setBannerLeft( parent.getBannerLeft() );
-
-                resolveBannerPaths( child.getBannerLeft(), prefix, parentBaseUrl );
+                resolveBannerPaths( child.getBannerLeft(), urlContainer);
             }
 
             if ( child.getBannerRight() == null )
             {
                 child.setBannerRight( parent.getBannerRight() );
 
-                resolveBannerPaths( child.getBannerRight(), prefix, parentBaseUrl );
+                resolveBannerPaths( child.getBannerRight(), urlContainer);
             }
 
             if ( child.getPublishDate() == null )
@@ -83,33 +76,33 @@
             }
 
             child.setPoweredBy(
-                mergePoweredByLists( child.getPoweredBy(), parent.getPoweredBy(), prefix, parentBaseUrl ) );
+                mergePoweredByLists( child.getPoweredBy(), parent.getPoweredBy(), urlContainer));
 
-            assembleBodyInheritance( name, childBaseUrl, child, parent, prefix, parentBaseUrl );
+            assembleBodyInheritance( name, child, parent, urlContainer );
 
             assembleCustomInheritance( child, parent );
         }
     }
 
-    public void resolvePaths( DecorationModel decoration, String baseUrl )
+    public void resolvePaths(final DecorationModel decoration, final String childBaseUrl)
     {
-        String prefix = ".";
+        URLContainer urlContainer = new URLContainer(null, childBaseUrl);
 
         if ( decoration.getBannerLeft() != null )
         {
-            resolveBannerPaths( decoration.getBannerLeft(), prefix, baseUrl );
+            resolveBannerPaths( decoration.getBannerLeft(), urlContainer);
         }
 
         if ( decoration.getBannerRight() != null )
         {
-            resolveBannerPaths( decoration.getBannerRight(), prefix, baseUrl );
+            resolveBannerPaths( decoration.getBannerRight(), urlContainer);
         }
 
         for ( Iterator i = decoration.getPoweredBy().iterator(); i.hasNext(); )
         {
             Logo logo = (Logo) i.next();
 
-            resolveLogoPaths( logo, prefix, baseUrl );
+            resolveLogoPaths( logo, urlContainer);
         }
 
         if ( decoration.getBody() != null )
@@ -118,50 +111,43 @@
             {
                 LinkItem linkItem = (LinkItem) i.next();
 
-                resolveLinkItemPaths( linkItem, prefix, baseUrl );
+                resolveLinkItemPaths( linkItem, urlContainer);
             }
 
             for ( Iterator i = decoration.getBody().getBreadcrumbs().iterator(); i.hasNext(); )
             {
                 LinkItem linkItem = (LinkItem) i.next();
 
-                resolveLinkItemPaths( linkItem, prefix, baseUrl );
+                resolveLinkItemPaths( linkItem, urlContainer);
             }
 
             for ( Iterator i = decoration.getBody().getMenus().iterator(); i.hasNext(); )
             {
                 Menu menu = (Menu) i.next();
 
-                resolveMenuPaths( menu.getItems(), prefix, baseUrl );
+                resolveMenuPaths( menu.getItems(), urlContainer);
             }
         }
     }
 
-    private void resolveBannerPaths( Banner banner, String prefix, String baseUrl )
+    /**
+     * Resolves all relative pathes between the elements in a banner. The
+     * banner element might contain relative pathes to the oldBaseUrl, these
+     * are changed to the newBannerUrl.
+     *
+     * @param banner
+     * @param prefix
+     * @param baseUrl
+     */
+    private void resolveBannerPaths(final Banner banner, final URLContainer urlContainer)
     {
         if ( banner != null )
         {
-            banner.setHref( resolvePath( banner.getHref(), prefix, baseUrl ) );
-            banner.setSrc( resolvePath( banner.getSrc(), prefix, baseUrl ) );
+            banner.setHref( convertPath( banner.getHref(), urlContainer));
+            banner.setSrc( convertPath( banner.getSrc(), urlContainer));
         }
     }
 
-    private String resolvePath( String href, String prefix, String baseUrl )
-    {
-        String path = null;
-        if ( href != null )
-        {
-            String relativePath = getParentPrefix( href, baseUrl );
-
-            if ( relativePath.startsWith( "/" ) )
-            {
-                relativePath = relativePath.substring( 1 );
-            }
-            path = PathTool.calculateLink( relativePath, prefix );
-        }
-        return path;
-    }
-
     private void assembleCustomInheritance( DecorationModel child, DecorationModel parent )
     {
         if ( child.getCustom() == null )
@@ -174,8 +160,8 @@
         }
     }
 
-    private void assembleBodyInheritance( String name, String childUrl, DecorationModel child, DecorationModel parent,
-                                          String prefix, String baseUrl )
+    private void assembleBodyInheritance( final String name, final DecorationModel child, final DecorationModel parent,
+                                          final URLContainer urlContainer )
     {
         Body cBody = child.getBody();
         Body pBody = parent.getBody();
@@ -202,27 +188,27 @@
                 cBody.setHead( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) cBody.getHead(), (Xpp3Dom) pBody.getHead() ) );
             }
 
-            cBody.setLinks( mergeLinkItemLists( cBody.getLinks(), pBody.getLinks(), prefix, baseUrl ) );
+            cBody.setLinks( mergeLinkItemLists( cBody.getLinks(), pBody.getLinks(), urlContainer ) );
 
             if ( cBody.getBreadcrumbs().isEmpty() && !pBody.getBreadcrumbs().isEmpty() )
             {
                 LinkItem breadcrumb = new LinkItem();
                 breadcrumb.setName( name );
-                breadcrumb.setHref( childUrl );
+                breadcrumb.setHref( urlContainer.getNewPath());
                 cBody.getBreadcrumbs().add( breadcrumb );
             }
             cBody.setBreadcrumbs(
-                mergeLinkItemLists( cBody.getBreadcrumbs(), pBody.getBreadcrumbs(), prefix, baseUrl ) );
+                mergeLinkItemLists( cBody.getBreadcrumbs(), pBody.getBreadcrumbs(), urlContainer ) );
 
-            cBody.setMenus( mergeMenus( cBody.getMenus(), pBody.getMenus(), prefix, baseUrl ) );
+            cBody.setMenus( mergeMenus( cBody.getMenus(), pBody.getMenus(), urlContainer ) );
         }
     }
 
-    private List mergeMenus( List dominant, List recessive, String prefix, String baseUrl )
+    private List mergeMenus(final List childMenus, final List parentMenus, final URLContainer urlContainer)
     {
         List menus = new ArrayList();
 
-        for ( Iterator it = dominant.iterator(); it.hasNext(); )
+        for ( Iterator it = childMenus.iterator(); it.hasNext(); )
         {
             Menu menu = (Menu) it.next();
 
@@ -230,7 +216,7 @@
         }
 
         int topCounter = 0;
-        for ( Iterator it = recessive.iterator(); it.hasNext(); )
+        for ( Iterator it = parentMenus.iterator(); it.hasNext(); )
         {
             Menu menu = (Menu) it.next();
 
@@ -239,48 +225,48 @@
                 menus.add( topCounter, menu );
                 topCounter++;
 
-                resolveMenuPaths( menu.getItems(), prefix, baseUrl );
+                resolveMenuPaths( menu.getItems(), urlContainer);
             }
             else if ( "bottom".equals( menu.getInherit() ) )
             {
                 menus.add( menu );
 
-                resolveMenuPaths( menu.getItems(), prefix, baseUrl );
+                resolveMenuPaths( menu.getItems(), urlContainer);
             }
         }
 
         return menus;
     }
 
-    private void resolveMenuPaths( List items, String prefix, String baseUrl )
+    private void resolveMenuPaths(final List items, final URLContainer urlContainer)
     {
         for ( Iterator i = items.iterator(); i.hasNext(); )
         {
             MenuItem item = (MenuItem) i.next();
-            resolveLinkItemPaths( item, prefix, baseUrl );
-            resolveMenuPaths( item.getItems(), prefix, baseUrl );
+            resolveLinkItemPaths( item, urlContainer);
+            resolveMenuPaths( item.getItems(), urlContainer);
         }
     }
 
-    private void resolveLinkItemPaths( LinkItem item, String prefix, String baseUrl )
+    private void resolveLinkItemPaths( LinkItem item, final URLContainer urlContainer)
     {
         if ( item.getHref() != null )
         {
-            item.setHref( resolvePath( item.getHref(), prefix, baseUrl ) );
+            item.setHref( convertPath( item.getHref(), urlContainer));
         }
         else
         {
-            item.setHref( "" );
+            item.setHref( convertPath( "", urlContainer) );
         }
     }
 
-    private void resolveLogoPaths( Logo logo, String prefix, String baseUrl )
+    private void resolveLogoPaths(final Logo logo, final URLContainer urlContainer)
     {
-        logo.setImg( resolvePath( logo.getImg(), prefix, baseUrl ) );
-        resolveLinkItemPaths( logo, prefix, baseUrl );
+        logo.setImg( convertPath(logo.getImg(), urlContainer));
+        resolveLinkItemPaths( logo, urlContainer);
     }
 
-    private List mergeLinkItemLists( List childList, List parentList, String prefix, String baseUrl )
+    private List mergeLinkItemLists(final List childList, final List parentList, final URLContainer urlContainer)
     {
         List items = new ArrayList();
 
@@ -288,7 +274,7 @@
         {
             LinkItem item = (LinkItem) it.next();
 
-            resolveLinkItemPaths( item, prefix, baseUrl );
+            resolveLinkItemPaths( item, urlContainer);
 
             if ( !items.contains( item ) )
             {
@@ -309,7 +295,7 @@
         return items;
     }
 
-    private List mergePoweredByLists( List childList, List parentList, String prefix, String baseUrl )
+    private List mergePoweredByLists(final List childList, final List parentList, final URLContainer urlContainer)
     {
         List logos = new ArrayList();
 
@@ -322,7 +308,7 @@
                 logos.add( logo );
             }
 
-            resolveLogoPaths( logo, prefix, baseUrl );
+            resolveLogoPaths( logo, urlContainer);
         }
 
         for ( Iterator it = childList.iterator(); it.hasNext(); )
@@ -338,105 +324,37 @@
         return logos;
     }
 
-    private static String getParentPrefix( String parentUrl, String childUrl )
+    private String convertPath(final String relativePath, final URLContainer urlContainer)
     {
-        String prefix = parentUrl;
-
-        if ( childUrl.startsWith( parentUrl ) )
+        try
         {
-            prefix = getRelativePath( childUrl, parentUrl );
+            PathDescriptor oldPathDescriptor = new PathDescriptor(urlContainer.getOldPath(),relativePath);
+            PathDescriptor newPathDescriptor = new PathDescriptor(urlContainer.getNewPath(), "");
 
-            String parentPath = "";
-            for ( StringTokenizer tok = new StringTokenizer( prefix, "/" ); tok.hasMoreTokens(); tok.nextToken() )
-            {
-                parentPath += "../";
-            }
-            prefix = parentPath;
-        }
-        else if ( parentUrl.startsWith( childUrl ) )
-        {
-            prefix = getRelativePath( parentUrl, childUrl );
-        }
-/*
-        // [MSITE-62] This is to test the ../ relative paths, which I am inclined not to use
-        else
-        {
-            String[] parentSplit = splitUrl( parentUrl );
-            String[] childSplit = splitUrl( childUrl );
+            PathDescriptor relativePathDescriptor = PathUtils.convertPath(oldPathDescriptor, newPathDescriptor);
 
-            if ( parentSplit != null && childSplit != null )
-            {
-                if ( parentSplit[0].equals( childSplit[0] ) && parentSplit[1].equals( childSplit[1] ) )
-                {
-                    prefix = "";
-                    boolean mismatched = false;
-                    String parentPath = parentSplit[2].substring( 1 );
-                    String childPath = childSplit[2].substring( 1 );
-                    StringTokenizer tok = new StringTokenizer( childPath, "/" );
-                    while ( tok.hasMoreTokens() )
-                    {
-                        String part = tok.nextToken();
-
-                        if ( !mismatched && parentPath.startsWith( part ) )
-                        {
-                            parentPath = parentPath.substring( part.length() + 1 );
-                        }
-                        else
-                        {
-                            mismatched = true;
-                            prefix += "../";
-                        }
-                    }
-                    prefix += parentPath;
-                }
-            }
+            return relativePathDescriptor.getLocation();
+        } catch (MalformedURLException mue) {
+            throw new RuntimeException("While converting Pathes:", mue);
         }
-*/
-
-        return prefix;
     }
 
-/* [MSITE-62] This is to test the ../ relative paths, which I am inclined not to use
-    private static String[] splitUrl( String url )
-    {
-        String[] retValue = null;
+    public final class URLContainer {
 
-        int protocolIndex = url.indexOf( "://" );
+        private final String oldPath;
+        private final String newPath;
 
-        if ( protocolIndex >= 0 )
-        {
-            String protocol = url.substring( 0, protocolIndex );
+        public URLContainer(final String oldPath, final String newPath) {
+            this.oldPath = oldPath;
+            this.newPath = newPath;
+        }
 
-            String host = url.substring( protocolIndex + 3 );
-
-            int pathIndex = host.indexOf( '/' );
-
-            if ( pathIndex >= 0 )
-            {
-                String path = host.substring( pathIndex );
-                host = host.substring( 0, pathIndex );
-                if ( host.length() == 0 && "file".equals( protocol ) )
-                {
-                    host = "localhost";
-                }
-
-                retValue = new String[3];
-                retValue[0] = protocol;
-                retValue[1] = host;
-                retValue[2] = path;
-            }
+        public String getNewPath() {
+            return this.newPath;
         }
-        return retValue;
-    }
-*/
 
-    private static String getRelativePath( String childUrl, String parentUrl )
-    {
-        String relative = childUrl.substring( parentUrl.length() );
-        if ( relative.startsWith( "/" ) )
-        {
-            relative = relative.substring( 1 );
+        public String getOldPath() {
+            return this.oldPath;
         }
-        return relative;
     }
 }
Index: src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathDescriptor.java
===================================================================
--- src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathDescriptor.java	(revision 0)
+++ src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathDescriptor.java	(revision 0)
@@ -0,0 +1,169 @@
+package org.apache.maven.doxia.site.decoration.inheritance;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/*
+ * Copyright 2004-2006 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.
+ *
+ */
+
+/**
+ * This class holds an instance of a maven path. This consists of a
+ * relative path (e.g. images/maven-logo.png) and a base reference which
+ * can also be a relative path (e.g. '.' or '../doxia') or an URL that
+ * is used for an absolute anchor.
+ *
+ * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
+ * @version $Id$
+ */
+
+public class PathDescriptor
+{
+    private final URL baseUrl;
+
+    private final URL pathUrl;
+
+    private final String relativePath;
+
+    public PathDescriptor(final String path)
+    throws MalformedURLException
+    {
+        this((URL) null, path);
+    }
+
+    public PathDescriptor(final String base, final String path)
+            throws MalformedURLException
+    {
+        this(PathDescriptor.buildBaseUrl(base), path);
+    }
+
+    public PathDescriptor (final URL baseUrl, final String path)
+        throws MalformedURLException
+    {
+        this.baseUrl = baseUrl;
+
+        URL pathUrl = null;
+        String relativePath = null;
+        try
+        {
+            pathUrl = new URL(path);
+        }
+        catch (MalformedURLException e)
+        {
+            try
+            {
+                pathUrl = buildUrl(baseUrl, path);
+            }
+            catch (MalformedURLException e2)
+            {
+                // If we got an absolute path passed in and end here, then the path
+                // is converted to relative because we have no reference URL anyway
+                // to which it has been anchored.
+                if (path != null && path.startsWith("/")) {
+                    relativePath = path.substring(1);
+                } else {
+                    relativePath = path;
+                }
+            }
+        }
+        this.pathUrl = pathUrl;
+        this.relativePath = relativePath;
+    }
+
+    private static final URL buildBaseUrl(final String base)
+        throws MalformedURLException
+    {
+        if (base == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            return new URL(base);
+        }
+        catch (MalformedURLException e)
+        {
+            return new File(base).toURL();
+        }
+    }
+
+    private static final URL buildUrl(final URL baseUrl, final String path)
+        throws MalformedURLException
+    {
+        if (baseUrl == null) {
+            throw new MalformedURLException("Base is null!");
+        }
+
+        if (path == null) {
+            return baseUrl;
+        }
+
+        if (path.startsWith("/") && baseUrl.getPath().endsWith("/"))
+        {
+            return new URL(baseUrl, path.substring(1));
+        }
+
+        return new URL(baseUrl, path);
+    }
+
+    public boolean isFile() {
+        return isRelative() || pathUrl.getProtocol().equals("file");
+    }
+
+    public boolean isRelative() {
+        return pathUrl == null;
+    }
+
+    public URL getBaseUrl() {
+        return baseUrl;
+    }
+
+    public URL getPathUrl() {
+        return pathUrl;
+    }
+
+    public String getPath() {
+        if (getPathUrl() != null)
+        {
+            return getPathUrl().getPath();
+        } else {
+            return relativePath;
+        }
+    }
+
+    public String getLocation() {
+        if (isFile())
+        {
+            if (getPathUrl() != null) {
+                return getPathUrl().getFile();
+            } else {
+                return relativePath;
+            }
+        }
+        else
+        {
+            return getPathUrl().toExternalForm();
+        }
+    }
+
+    public String toString()
+    {
+        StringBuffer res = new StringBuffer((relativePath != null) ? relativePath : String.valueOf(pathUrl));
+        res.append(" (Base: ").append(baseUrl).append(") Location: ").append(getLocation());
+        return res.toString();
+    }
+}

Property changes on: src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathDescriptor.java
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Index: src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathUtils.java
===================================================================
--- src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathUtils.java	(revision 0)
+++ src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathUtils.java	(revision 0)
@@ -0,0 +1,222 @@
+package org.apache.maven.doxia.site.decoration.inheritance;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+/*
+ * Copyright 2004-2006 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.
+ *
+ */
+
+public abstract class PathUtils
+{
+    private PathUtils()
+    {
+    }
+
+    public static final PathDescriptor convertPath(final PathDescriptor oldPath, final PathDescriptor newPath)
+            throws MalformedURLException
+    {
+        String relative = getRelativePath(oldPath, newPath);
+
+        if (relative == null)
+        {
+            return oldPath;
+        }
+
+        return new PathDescriptor(relative);
+    }
+
+    public static final String getRelativePath(final PathDescriptor oldPathDescriptor, final PathDescriptor newPathDescriptor)
+        throws MalformedURLException
+    {
+        // Cannot convert from URL to file.
+        if (oldPathDescriptor.isFile())
+        {
+            if (!newPathDescriptor.isFile()) {
+                // We want to convert from a file to an URL. This is normally not possible...
+                if(oldPathDescriptor.isRelative()) {
+                    // unless the old path is a relative path. Then we might convert an existing
+                    // site into a new URL using resolvePaths()..
+                    return oldPathDescriptor.getPath();
+                }
+                else
+                {
+                    // The old path is not relative. Bail out.
+                    return null;
+                }
+            }
+        }
+
+        // Don't optimize to else. This might also be old.isFile && new.isFile ...
+        if (!oldPathDescriptor.isFile())
+        {
+            // URLs, determine if they share protocol and domain info
+            URL oldUrl = oldPathDescriptor.getPathUrl();
+            URL newUrl = newPathDescriptor.getPathUrl();
+
+            if ((newUrl.getProtocol().equalsIgnoreCase(oldUrl.getProtocol()))
+                    && (newUrl.getHost().equalsIgnoreCase(oldUrl.getHost()))
+                    && (newUrl.getPort() == oldUrl.getPort()))
+            {
+                // Both pathes point to the same site. So we can use relative pathes.
+
+                String oldPath = oldPathDescriptor.getPath();
+                String newPath = newPathDescriptor.getPath();
+
+                return getRelativePath(newPath, oldPath);
+            }
+            else
+            {
+                // Different sites. No relative Path possible.
+                return null;
+            }
+        }
+        else
+        {
+            // Both Descriptors point to a path. We can build a relative path.
+            String oldPath = oldPathDescriptor.getPath();
+            String newPath = oldPathDescriptor.getPath();
+
+            return getRelativePath(oldPath, newPath);
+        }
+    }
+
+    /**
+     * This method can calculate the relative path between two pathes on a file system.
+     */
+    public static final String getRelativePath(final String oldPath, final String newPath)
+    {
+        // normalise the path delimters
+
+        String fromPath = new File(oldPath).getPath();
+        String toPath = new File(newPath).getPath();
+
+        // strip any leading slashes if its a windows path
+        if (toPath.matches("^\\[a-zA-Z]:"))
+        {
+            toPath = toPath.substring(1);
+        }
+        if (fromPath.matches("^\\[a-zA-Z]:"))
+        {
+            fromPath = fromPath.substring(1);
+        }
+
+        // lowercase windows drive letters.
+        if (fromPath.startsWith(":", 1))
+        {
+            fromPath = fromPath.substring(0, 1).toLowerCase() + fromPath.substring(1);
+        }
+        if (toPath.startsWith(":", 1))
+        {
+            toPath = toPath.substring(0, 1).toLowerCase() + toPath.substring(1);
+        }
+
+        // check for the presence of windows drives. No relative way of
+        // traversing from one to the other.
+        if ((toPath.startsWith(":", 1) && fromPath.startsWith(":", 1)) &&
+            (!toPath.substring(0, 1).equals(fromPath.substring(0, 1))))
+        {
+            // they both have drive path element but they dont match, no
+            // relative path
+            return null;
+        }
+
+        if ((toPath.startsWith(":", 1) && !fromPath.startsWith(":", 1)) ||
+            (!toPath.startsWith(":", 1) && fromPath.startsWith(":", 1)))
+        {
+            // one has a drive path element and the other doesnt, no relative
+            // path.
+            return null;
+        }
+
+        // use tokeniser to traverse paths and for lazy checking
+        StringTokenizer toTokeniser = new StringTokenizer(toPath, File.separator);
+        StringTokenizer fromTokeniser = new StringTokenizer(fromPath, File.separator);
+
+        int count = 0;
+
+        // walk along the to path looking for divergence from the from path
+        while (toTokeniser.hasMoreTokens() && fromTokeniser.hasMoreTokens())
+        {
+            if (File.separatorChar == '\\')
+            {
+                if (!fromTokeniser.nextToken().equalsIgnoreCase(toTokeniser.nextToken()))
+                {
+                    break;
+                }
+            }
+            else
+            {
+                if (!fromTokeniser.nextToken().equals(toTokeniser.nextToken()))
+                {
+                    break;
+                }
+            }
+
+            count++;
+        }
+
+        // reinitialise the tokenisers to count positions to retrieve the
+        // gobbled token
+
+        toTokeniser = new StringTokenizer(toPath, File.separator);
+        fromTokeniser = new StringTokenizer(fromPath, File.separator);
+
+        while (count-- > 0)
+        {
+            fromTokeniser.nextToken();
+            toTokeniser.nextToken();
+        }
+
+        String relativePath = "";
+
+        // add back refs for the rest of from location.
+        while (fromTokeniser.hasMoreTokens())
+        {
+            fromTokeniser.nextToken();
+
+            relativePath += "..";
+
+            if (fromTokeniser.hasMoreTokens())
+            {
+                relativePath += File.separatorChar;
+            }
+        }
+
+        if (relativePath.length() != 0 && toTokeniser.hasMoreTokens())
+        {
+            relativePath += File.separatorChar;
+        }
+
+        // add fwd fills for whatevers left of newPath.
+        while (toTokeniser.hasMoreTokens())
+        {
+            relativePath += toTokeniser.nextToken();
+
+            if (toTokeniser.hasMoreTokens())
+            {
+                relativePath += File.separatorChar;
+            }
+        }
+
+        if (newPath.endsWith("/") && !relativePath.endsWith("/")) {
+            return relativePath + "/";
+        }
+
+        return relativePath;
+    }
+}

Property changes on: src/main/java/org/apache/maven/doxia/site/decoration/inheritance/PathUtils.java
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

