class PathUtil {

    static String getRelativeFileInternal(File canonicalBaseFile, File canonicalFileToRelativize) {
        List<String> basePath = getPathComponents(canonicalBaseFile);
        List<String> pathToRelativize = getPathComponents(canonicalFileToRelativize);

        //if the roots aren't the same (i.e. different drives on a windows machine), we can't construct a relative
        //path from one to the other, so just return the canonical file
        if (!basePath.get(0).equals(pathToRelativize.get(0))) {
            return canonicalFileToRelativize.getPath();
        }

        int commonDirs;
        StringBuilder sb = new StringBuilder();

        for (commonDirs=1; commonDirs<basePath.size() && commonDirs<pathToRelativize.size(); commonDirs++) {
            if (!basePath.get(commonDirs).equals(pathToRelativize.get(commonDirs))) {
                break;
            }
        }

        boolean first = true;
        for (int i=commonDirs; i<basePath.size(); i++) {
            if (!first) {
                sb.append(File.separatorChar);
            } else {
                first = false;
            }

            sb.append("..");
        }

        first = true;
        for (int i=commonDirs; i<pathToRelativize.size(); i++) {
            if (first) {
                if (sb.length() != 0) {
                    sb.append(File.separatorChar);
                }
                first = false;
            } else {
                sb.append(File.separatorChar);
            }
            
            sb.append(pathToRelativize.get(i));
        }

        if (sb.length() == 0) {
            return ".";
        }

        return sb.toString();
    }

    private  PathUtil();

}