static function getRelativePath($path, $compareTo)
    {

        // On some windows machines the SCRIPT_FILENAME may be lower or upper case
        // compared to the target path which could be lower, upper or a mixture
        // so convert every thing lower for the comparison
        // Work out if it's Windows by looking for a back slash or a leading
        // driver specifier eg "C:"
        if (preg_match("/\\\/", $compareTo) || preg_match("/^[A-Za-z]:/", $compareTo)) {
            $compareTo = strtolower($compareTo);
            $path = strtolower($path);
        }

        // Convert Windows paths with "\" delimiters to forward delimiters
        $path = preg_replace("+\\\+", "/", $path);
        $compareTo = preg_replace("+\\\+", "/", $compareTo);

        // clean arguments by removing trailing and prefixing slashes
        if (substr($path, -1) == '/') {
            $path = substr($path, 0, -1);
        }

        if (substr($path, 0, 1) == '/') {
            $path = substr($path, 1);
        }

        if (substr($compareTo, -1) == '/') {
            $compareTo = substr($compareTo, 0, -1);
        }
        if (substr($compareTo, 0, 1) == '/') {
            $compareTo = substr($compareTo, 1);
        }

        // simple case: $compareTo is in $path
        if (strpos($path, $compareTo) === 0) {
            $offset = strlen($compareTo) + 1;
            return substr($path, $offset);
        }

        $relative = array();
        $pathParts = explode('/', $path);
        $compareToParts = explode('/', $compareTo);

        foreach ($compareToParts as $index => $part) {
            if (isset($pathParts[$index]) && $pathParts[$index] == $part) {
                continue;
            }

            $relative[] = '..';
        }

        foreach ($pathParts as $index => $part) {
            if (isset($compareToParts[$index]) && $compareToParts[$index] == $part) {
                continue;
            }

            $relative[] = $part;
        }

        return implode('/', $relative);
    }