diff --git a/src/xercesc/framework/LocalFileInputSource.cpp b/src/xercesc/framework/LocalFileInputSource.cpp
index 63e26a321987a48b92d1b6efbd0c26026497f168..eef249fee522a83f00f29eddf11eef4b70ee45f0 100644
--- a/src/xercesc/framework/LocalFileInputSource.cpp
+++ b/src/xercesc/framework/LocalFileInputSource.cpp
@@ -60,15 +60,67 @@
 // ---------------------------------------------------------------------------
 #include <xercesc/util/BinFileInputStream.hpp>
 #include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
 #include <xercesc/framework/LocalFileInputSource.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
+/***
+ *
+ * Originated by Chris larsson
+ *
+ * Issue:
+ *
+ * There is an inconsistency in URI resolution in the case where the file itself is a 
+ * symbolic link to another path (or the path has path segment which is a symbolic
+ * link to another path). So, is the base path the directory where the symbolic link resides 
+ * or the directory where the real file resides? I'm sure one could argue either way, 
+ * but I think that having the base path be the directory where the symbolic link resides 
+ * is more intuitive. 
+ *
+ * Defining it this way would then make the behavior consistent with using an absolute 
+ * path as well as with the java behavior. 
+ *
+ * Proposal:
+ *
+ * The URI is resolved within the parser code, and is somewhat independant of the OS. 
+ * 
+ * A relative path is resolved by querying the current directory and appending the 
+ * relative part onto the returned current directory string to obtain the base URI. 
+ * An absolute path is simply used as the base URI. 
+ * Then remove all "./" and "../" path segments using an algorithm like weavepath to obtain 
+ * the resolved base URI. 
+ *
+ * When you need to access another file such as a dtd, use the resolved base URI and add on
+ * the relative URI of the dtd file. Then resolve it using the same weavepath algorithm. 
+ *
+ * Note:
+ *
+ *   Java parser behaves differently for a path containning symbolic path segment. When 
+ *   it is given an absolute path, it can locate the primary instance document, while given 
+ *   relative path, it might not.
+ *
+ *   It is because Java parser uses URI solution where "/segment/../" is required to be removed
+ *   from the resultant path if a relative URI is merged to a baseURI. While this is NOT required
+ *   for an absolute URI. 
+ *   
+ *   So if a path segment, which is symbolic link, happen to be followed by the '/../', it is 
+ *   NOT removed from the path if it is given in absolute form, and the underlying file system 
+ *   will locate the file, if in relative form, that symbolic link path segment together with 
+ *   '../' is removed from the resultant path, and the file system may NOT be able to locate 
+ *   the file, if there is a one, it is definitely not the one expected, in fact by accident.
+ *
+ *   Therefore, to keep consistent with Java parser, for now, we do not apply removeDotDotSlash()
+ *   for absolute path.
+ *  
+ ***/
+
 // ---------------------------------------------------------------------------
 //  LocalFileInputSource: Constructors and Destructor
 // ---------------------------------------------------------------------------
-LocalFileInputSource::LocalFileInputSource( const   XMLCh* const basePath
-                                            , const XMLCh* const relativePath)
+LocalFileInputSource::LocalFileInputSource( const XMLCh* const basePath
+                                          , const XMLCh* const relativePath)
 {
     //
     //  If the relative part is really relative, then weave it together
@@ -81,14 +133,19 @@ LocalFileInputSource::LocalFileInputSource( const   XMLCh* const basePath
         setSystemId(tmpBuf);
         delete [] tmpBuf;
     }
-     else
+    else
     {
-        setSystemId(relativePath);
+        XMLCh* tmpBuf = XMLString::replicate(relativePath);
+        XMLPlatformUtils::removeDotSlash(tmpBuf);
+        setSystemId(tmpBuf);
+        delete [] tmpBuf;
     }
+
 }
 
 LocalFileInputSource::LocalFileInputSource(const XMLCh* const filePath)
 {
+
     //
     //  If the path is relative, then complete it acording to the current
     //  working directory rules of the current platform. Else, just take
@@ -96,14 +153,35 @@ LocalFileInputSource::LocalFileInputSource(const XMLCh* const filePath)
     //
     if (XMLPlatformUtils::isRelative(filePath))
     {
-        XMLCh* tmpBuf = XMLPlatformUtils::getFullPath(filePath);
-        setSystemId(tmpBuf);
-        delete [] tmpBuf;
+        XMLCh* curDir = XMLPlatformUtils::getCurrentDirectory();
+
+        int    curDirLen = XMLString::stringLen(curDir);
+        int    filePathLen = XMLString::stringLen(filePath);
+        XMLCh* fullDir = new XMLCh [ curDirLen + filePathLen + 2];
+
+        fullDir[0] = 0;
+        XMLString::copyString(fullDir, curDir);
+        fullDir[curDirLen] = chForwardSlash;
+        fullDir[curDirLen+1] = 0;
+        XMLString::catString(&fullDir[curDirLen+1], filePath);
+        fullDir[curDirLen+filePathLen+1] = 0;
+        
+        XMLPlatformUtils::removeDotSlash(fullDir);
+        XMLPlatformUtils::removeDotDotSlash(fullDir);
+
+        setSystemId(fullDir);
+
+        delete [] curDir;
+        delete [] fullDir;
     }
      else
     {
-        setSystemId(filePath);
+        XMLCh* tmpBuf = XMLString::replicate(filePath);
+        XMLPlatformUtils::removeDotSlash(tmpBuf);
+        setSystemId(tmpBuf);
+        delete [] tmpBuf;
     }
+
 }
 
 LocalFileInputSource::~LocalFileInputSource()
diff --git a/src/xercesc/util/LogicalPath.c b/src/xercesc/util/LogicalPath.c
new file mode 100644
index 0000000000000000000000000000000000000000..88b68d2ed93902ab5eacd13bf9bec72dca69dd07
--- /dev/null
+++ b/src/xercesc/util/LogicalPath.c
@@ -0,0 +1,242 @@
+#if !defined(WEAVEPATH_CPP)
+#define WEAVEPATH_CPP
+
+/***
+ *
+ *  Previously, each <OS>PlatformUtils.cpp has its onw copy of the
+ *  method weavePaths(), and almost of them implemented the same logic,
+ *  with few platform specific difference, and unfortunately that 
+ *  implementation was wrong.
+ *  
+ *  The only platform specific issue is slash character.
+ *  On all platforms other than Windows, chForwardSlash and chBackSlash 
+ *  are considered slash, while on Windows, two additional characters, 
+ *  chYenSign and chWonSign are slash as well.
+ *
+ *  The idea is to maintain a SINGLE copy of this method rather than
+ *  each <OS>PlatformUtils.cpp has its own copy, we introduce a new
+ *  method, XMLPlatformUtils::isAnySlash(), to replace the direct checking
+ *  code ( if ( c == chForwardSlash || c == chBackSlash).
+ *
+ *  With this approach, we might have a performance hit since isAnySlash() 
+ *  is so frequently used in this implementation, so we intend to make it 
+ *  inline. Then we face a complier issue.
+ *
+ *  There are two compilation units involved, one is PlatformUtils.cpp and 
+ *  the other <OS>PlatformUtils.cpp. When PlatformUtils.cp get compiled,
+ *  the weavePath(), remove**Slash() have dependency upon isAnySlash() which
+ *  is in <OS>PlatformUtils.cpp (and what is worse, it is inlined), so we have
+ *  undefined/unresolved symbol: isAnySlash() on AIX/xlc_r, Solaris/cc and 
+ *  Linux/gcc, while MSVC and HP/aCC are fine with this.
+ *  
+ *  That means we can not place these new methods in PlatformUtils.cpp with
+ *  inlined XMLPlatformUtils::isAnySlash() in <OS>PlatformUtils.cpp.
+ *
+ *  The solution to this is <os>PlatformUtils.cpp will include this file so that
+ *  we have only one copy of these methods while get compiled in <os>PlatformUtils
+ *  inlined isAnySlash().
+ *
+ ***/
+XMLCh* XMLPlatformUtils::weavePaths(const XMLCh* const    basePath
+                                  , const XMLCh* const    relativePath)
+
+{
+    // Create a buffer as large as both parts and empty it
+    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath) + 
+                              XMLString::stringLen(relativePath) + 2];
+    *tmpBuf = 0;
+
+    //
+    //  If we have no base path, then just take the relative path as is.
+    //
+    if ((!basePath) || (!*basePath))
+    {
+        XMLString::copyString(tmpBuf, relativePath);
+        return tmpBuf;
+    }
+
+    //
+    // Remove anything after the last slash
+    //
+    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
+    while ((basePtr >= basePath)  &&  ((isAnySlash(*basePtr) == false)))
+    {
+        basePtr--;
+    }
+
+    // There is no relevant base path, so just take the relative part
+    if (basePtr < basePath)
+    {
+        XMLString::copyString(tmpBuf, relativePath);
+        return tmpBuf;
+    }
+
+    //
+    // 1. concatenate the base and relative
+    // 2. remove all occurences of "/./"
+    // 3. remove all occurences of segment/../ where segment is not ../
+	// 
+
+    XMLString::subString(tmpBuf, basePath, 0, (basePtr - basePath + 1));
+    tmpBuf[basePtr - basePath + 1] = 0;
+    XMLString::catString(tmpBuf, relativePath);
+
+    removeDotSlash(tmpBuf);
+
+    removeDotDotSlash(tmpBuf);
+
+    return tmpBuf;
+
+}
+
+//
+// Remove all occurences of './' when it is part of '/./'
+//
+// Since it could be '.\' or other combination on windows ( eg, '.'+chYanSign)
+// we can't make use of patterMatch().
+//
+//
+void XMLPlatformUtils::removeDotSlash(XMLCh* const path)
+{
+    if ((!path) || (!*path))
+        return;
+
+    XMLCh* srcPtr = XMLString::replicate(path);
+    int    srcLen = XMLString::stringLen(srcPtr);
+    ArrayJanitor<XMLCh>   janName(srcPtr);   
+    XMLCh* tarPtr = path;
+
+    while (*srcPtr)
+    {
+        if ( 3 <= srcLen )
+        {
+            if ( (isAnySlash(*srcPtr))     &&
+                (chPeriod == *(srcPtr+1)) &&
+                (isAnySlash(*(srcPtr+2)))  )
+            {
+                // "\.\x" seen
+                // skip the first two, and start from the 3rd,
+                // since "\x" could be another "\."
+                srcPtr+=2;              
+                srcLen-=2;
+            }
+            else
+            {
+                *tarPtr++ = *srcPtr++;  // eat the current char
+                srcLen--;
+            }
+        }
+        else if ( 1 == srcLen )
+        {
+            *tarPtr++ = *srcPtr++;
+        }
+        else if ( 2 == srcLen)
+        {
+            *tarPtr++ = *srcPtr++;
+            *tarPtr++ = *srcPtr++;
+        }
+
+    }
+
+    *tarPtr = 0;
+
+    return;
+}
+
+//
+// Remove all occurences of '/segment/../' when segment is not '..'
+//
+// Cases with extra /../ is left to the underlying file system.
+//
+void XMLPlatformUtils::removeDotDotSlash(XMLCh* const path)
+{
+    int pathLen = XMLString::stringLen(path);
+    XMLCh* tmp1 = new XMLCh [pathLen+1];
+    ArrayJanitor<XMLCh>   tmp1Name(tmp1);
+
+    XMLCh* tmp2 = new XMLCh [pathLen+1];
+    ArrayJanitor<XMLCh>   tmp2Name(tmp2);
+
+    // remove all "<segment>/../" where "<segment>" is a complete
+    // path segment not equal to ".."
+    int index = -1;
+    int segIndex = -1;
+    int offset = 1;
+
+    while ((index = searchSlashDotDotSlash(&(path[offset]))) != -1)
+    {
+        // Undo offset
+        index += offset;
+
+        // Find start of <segment> within substring ending at found point.
+        XMLString::subString(tmp1, path, 0, index-1);
+        segIndex = index - 1;
+        while ((segIndex >= 0) && (!isAnySlash(tmp1[segIndex])))
+        {
+            segIndex--;
+        }
+
+        // Ensure <segment> exists and != ".."
+        if (segIndex >= 0                 &&
+            (path[segIndex+1] != chPeriod ||
+             path[segIndex+2] != chPeriod ||
+             segIndex + 3 != index))
+        {
+
+            XMLString::subString(tmp1, path, 0, segIndex);
+            XMLString::subString(tmp2, path, index+3, XMLString::stringLen(path));
+
+            path[0] = 0;
+            XMLString::catString(path, tmp1);
+            XMLString::catString(path, tmp2);
+
+            offset = (segIndex == 0 ? 1 : segIndex);
+        }
+        else
+        {
+            offset += 4;
+        }
+
+    }// while
+
+}
+
+int XMLPlatformUtils::searchSlashDotDotSlash(XMLCh* const srcPath)
+{
+    if ((!srcPath) || (!*srcPath))
+        return -1;
+
+    XMLCh* srcPtr = srcPath;
+    int    srcLen = XMLString::stringLen(srcPath);
+    int    retVal = -1;
+
+    while (*srcPtr)
+    {
+        if ( 4 <= srcLen )
+        {
+            if ( (isAnySlash(*srcPtr))     &&
+                 (chPeriod == *(srcPtr+1)) &&
+                 (chPeriod == *(srcPtr+2)) &&
+                 (isAnySlash(*(srcPtr+3)))  )
+            {
+                retVal = (srcPtr - srcPath);
+                break;
+            }
+            else
+            {
+                srcPtr++;
+                srcLen--;
+            }
+        }
+        else 
+        {
+            break;
+        }
+
+    } // while
+
+    return retVal;
+
+}
+
+#endif
diff --git a/src/xercesc/util/Makefile.in b/src/xercesc/util/Makefile.in
index 2c06041fca18734ade61617a7bb9348b1d6e7cd6..73277455a5fd2ba15e60e6e14a0110285fe73acb 100644
--- a/src/xercesc/util/Makefile.in
+++ b/src/xercesc/util/Makefile.in
@@ -55,6 +55,9 @@
 #
 #
 # $Log$
+# Revision 1.34  2003/04/24 02:49:36  peiyongz
+# Logical Path Resolution
+#
 # Revision 1.33  2003/04/21 16:15:10  knoaman
 # Remove MemoryManagerImpl.
 #
@@ -573,7 +576,8 @@ C_FILES = \
     ValueHashTableOf.c \
     ValueStackOf.c \
     ValueVectorOf.c \
-    XMLDeleterFor.c
+    XMLDeleterFor.c \
+    LogicalPath.c
 
 UTIL_CPP_OBJECTS = \
     Base64.$(TO) \
diff --git a/src/xercesc/util/PlatformUtils.hpp b/src/xercesc/util/PlatformUtils.hpp
index be50836c1b258f6278d1cfce0d7560798e2a70f3..538a8e863ee05cf69d69e542b0b0bfa694ea1761 100644
--- a/src/xercesc/util/PlatformUtils.hpp
+++ b/src/xercesc/util/PlatformUtils.hpp
@@ -385,6 +385,51 @@ public :
       */
     static XMLCh* getFullPath(const XMLCh* const srcPath);
 
+    /** Gets the current working directory 
+      *
+      * This must be implemented by the per-platform driver. It returns 
+      * the current working directory is. 
+      *
+      * @return Returns the current working directory. 
+      *         This is dyanmically allocated and must be deleted
+      *         by the caller when its no longer needed!
+      */
+    static XMLCh* getCurrentDirectory();
+
+    /** Check if a charater is a slash
+      *
+      * This must be implemented by the per-platform driver. 
+      *
+      * @param c the character to be examined
+      *
+      * @return true  if the character examined is a slash
+      *         false otherwise
+      */
+    static inline bool isAnySlash(XMLCh c);
+    
+    /** Remove occurences of the pair of dot slash 
+      *
+      * To remove the sequence, dot slash if it is part of the sequence,
+      * slash dot slash.
+      *
+      * @param srcPath The path for which you want to remove the dot slash sequence.
+      *
+      * @return 
+      */
+    static void   removeDotSlash(XMLCh* const srcPath);
+
+    /** Remove occurences of the dot dot slash 
+      *
+      * To remove the sequence, slash dot dot slash and its preceding path segment
+      * if and only if the preceding path segment is not slash dot dot slash.
+      *
+      * @param srcPath The path for which you want to remove the slash dot
+      *        dot slash sequence and its preceding path segment.
+      *
+      * @return 
+      */
+    static void   removeDotDotSlash(XMLCh* const srcPath);
+
     /** Determines if a path is relative or absolute
       *
       * This must be implemented by the per-platform driver, which should
@@ -679,6 +724,15 @@ private :
       */
     static void platformTerm();
 
+    /** Search for sequence, slash dot dot slash
+      *
+      * @param srcPath the path to search
+      *
+      * @return   the position of the first occurence of slash dot dot slash
+      *            -1 if no such sequence is found
+      */
+    static int  searchSlashDotDotSlash(XMLCh* const srcPath);
+
     //@}
 };
 
diff --git a/src/xercesc/util/Platforms/AIX/AIXPlatformUtils.cpp b/src/xercesc/util/Platforms/AIX/AIXPlatformUtils.cpp
index a5bd8cffa7d6a5d9a323193db35a198196428e02..f53bfe8e9cc7e241a80e3268987e6ffdf080af77 100644
--- a/src/xercesc/util/Platforms/AIX/AIXPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/AIX/AIXPlatformUtils.cpp
@@ -352,114 +352,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths
-    (
-        const   XMLCh* const    basePath
-        , const XMLCh* const    relativePath
-    )
-{
-// Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
+{
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -636,5 +540,7 @@ void XMLPlatformUtils::platformInit()
 }
 ********************* End of code attic *******************************/
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/Platforms/BeOS/BeOSPlatformUtils.cpp b/src/xercesc/util/Platforms/BeOS/BeOSPlatformUtils.cpp
index 9e0ca9380c8c12576519bdcdb416e504b388eead..c04c143a910eb0dd53a847d5039feb41d351885b 100644
--- a/src/xercesc/util/Platforms/BeOS/BeOSPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/BeOS/BeOSPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.5  2003/04/24 02:52:34  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.4  2003/04/21 04:26:47  peiyongz
  * performance tuning
  *
@@ -404,113 +407,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -689,5 +597,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
 
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp b/src/xercesc/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
index b04c740287fd18ba3223762457a1217edd94e381..c1ac18c97668453eb5445c63e34cc713879a9033 100644
--- a/src/xercesc/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/FreeBSD/FreeBSDPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.11  2003/04/24 02:53:29  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.10  2003/04/21 04:27:22  peiyongz
  * performance tuning
  *
@@ -440,113 +443,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -725,4 +633,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/HPUX/HPPlatformUtils.cpp b/src/xercesc/util/Platforms/HPUX/HPPlatformUtils.cpp
index 463c625b02fa88654ff1c1f207a64ba1a25d544f..b06d4b38b27a8a1227c10f525bfa3d66c08cceca 100644
--- a/src/xercesc/util/Platforms/HPUX/HPPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/HPUX/HPPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.11  2003/04/24 02:53:52  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.10  2003/03/09 16:53:55  peiyongz
  * PanicHandler
  *
@@ -214,7 +217,6 @@
 
 XERCES_CPP_NAMESPACE_BEGIN
 
-
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Private Static Methods
 // ---------------------------------------------------------------------------
@@ -487,112 +489,17 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths
-    (
-        const   XMLCh* const    basePath
-        , const XMLCh* const    relativePath
-    )
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-// Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
+}
 
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
 }
 
 // ---------------------------------------------------------------------------
@@ -786,4 +693,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/IRIX/IRIXPlatformUtils.cpp b/src/xercesc/util/Platforms/IRIX/IRIXPlatformUtils.cpp
index 644f3b38ce3b36490d70a7b1a9b9b3c92bac3ae3..325ef34ec255c75fcb074ada9cc096226f097ae2 100644
--- a/src/xercesc/util/Platforms/IRIX/IRIXPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/IRIX/IRIXPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.10  2003/04/24 02:54:24  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.9  2003/04/21 04:28:04  peiyongz
  * performance tuning
  *
@@ -457,113 +460,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -853,5 +761,7 @@ void XMLPlatformUtils::platformTerm()
     // We don't have any termination requirements at this time
 //}
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/Platforms/Linux/LinuxPlatformUtils.cpp b/src/xercesc/util/Platforms/Linux/LinuxPlatformUtils.cpp
index 7ae30b46cdf0cdc9101bf0c56e413206bc2275e4..f3a4d48bbcca884013e1dbf49e5883ee11aa1ecd 100644
--- a/src/xercesc/util/Platforms/Linux/LinuxPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Linux/LinuxPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.14  2003/04/24 02:54:46  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.13  2003/04/21 04:28:45  peiyongz
  * performance tuning
  *
@@ -500,113 +503,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -785,5 +693,7 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp b/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp
index 479d522487526055139ef72e3131ad8ce34698c3..1c050c66300625cd6763af9a84b11c111e16fda8 100644
--- a/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp
@@ -119,7 +119,6 @@
 
 XERCES_CPP_NAMESPACE_BEGIN
 
-
 //----------------------------------------------------------------------------
 // Function Prototypes
 //----------------------------------------------------------------------------
@@ -355,106 +354,23 @@ XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return (toCheck[0] != L'/');
 }
 
-
-XMLCh*
-XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Code from Windows largely unmodified for the Macintosh,
-    // with the exception of removing support for '\' path
-    // separator.
-    //
-    // Note that there is no support currently for Macintosh
-    // path separators ':'.
-
-    // Create a buffer as large as both parts and empty it
-    ArrayJanitor<XMLCh> tmpBuf(new XMLCh[XMLString::stringLen(basePath)
-        + XMLString::stringLen(relativePath)
-        + 2]);
-    tmpBuf[0] = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf.get(), relativePath);
-        return tmpBuf.release();
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf.get(), relativePath);
-        return tmpBuf.release();
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if (*basePtr != chForwardSlash)
-    {
-        while ((basePtr >= basePath) && (*basePtr != chForwardSlash))
-            basePtr--;
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf.get(), relativePath);
-        return tmpBuf.release();
-    }
 
-    //  We have some path part, so we need to check to see if we have to
-    //  weave any of the parts together.
-    const XMLCh* pathPtr = relativePath;
+    /*** 
+     *  REVISIT:
+     * 
+     *   To be implemented later
+    ***/
 
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) &&  *pathPtr)
-            break;
-
-        if (*pathPtr)
-            pathPtr++;
-
-        // If it's one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath) && (*basePtr != chForwardSlash))
-                basePtr--;
-
-            // The base cannot provide enough levels, so it's in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf.get();
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    return tmpBuf.release();
+    XMLCh curDir[]={ chPeriod, chForwardSlash, chNull};
+    return getFullPath(curDir);
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -1583,4 +1499,6 @@ TranscodeUTF8ToUniChars(const char* src, UniChar* dst, std::size_t maxChars)
 	return result;
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/OS2/OS2PlatformUtils.cpp b/src/xercesc/util/Platforms/OS2/OS2PlatformUtils.cpp
index 129fb4b163103ff138144a653bd6b9b1bcc00563..d6fa79cb5b4c69a3f5924dbd32cf1640a43785bb 100644
--- a/src/xercesc/util/Platforms/OS2/OS2PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/OS2/OS2PlatformUtils.cpp
@@ -232,107 +232,23 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths( const   XMLCh* const    basePath
-                                   , const XMLCh* const    relativePath )
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
 
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath || !*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
+    /*** 
+     *  REVISIT:
+     * 
+     *   To be implemented later
+    ***/
 
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            if (basePtr < basePath)
-            {
-                // The base cannot provide enough levels, so its in error
-                // <TBD>
-            }
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    XMLCh curDir[]={ chPeriod, chForwardSlash, chNull};
+    return getFullPath(curDir);
 }
 
-
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // -----------------------------------------------------------------------
 //  Timing methods
@@ -514,5 +430,7 @@ XMLTransService* XMLPlatformUtils::makeTransService()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp b/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp
index 6aa14096326b10965e6b85fdca7bcf15de7ed9ea..b7f794d41fe79ede7698533e51af3e54161dd8d8 100644
--- a/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp
@@ -901,117 +901,24 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     // let Path390 do the final determination
     return pathobj.isRelative();
 
-
-
-
-
 }
 
-XMLCh* XMLPlatformUtils::weavePaths
-    (
-        const   XMLCh* const    basePath
-        , const XMLCh* const    relativePath
-    )
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-// Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
 
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-                // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
+    /*** 
+     *  REVISIT:
+     * 
+     *   To be implemented later
+    ***/
 
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-            ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
-
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
+    XMLCh curDir[]={ chPeriod, chForwardSlash, chNull};
+    return getFullPath(curDir);
+}
 
-    // Orphan the buffer and return it
-    janBuf.orphan();
-        return tmpBuf;
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
 }
 
 // ---------------------------------------------------------------------------
@@ -1192,4 +1099,6 @@ void XMLPlatformUtils::platformTerm()
     // We don't have any termination requirements at this time
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
index 7010cc365923943f5f07c2fea4e5063dfa322ecb..043a10315dccf2378d8bae19cd38ffd5182b0edb 100644
--- a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
@@ -425,120 +425,19 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     // Else assume its a relative path
     return true;
 }
-XMLCh* XMLPlatformUtils::weavePaths
-    (
-        const   XMLCh* const    basePath
-        , const XMLCh* const    relativePath
-    )
-{
-// Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
 
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (*relativePath == chForwardSlash)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-		// If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-	return tmpBuf;
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
+{
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
-
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 void send_message (char * text, char * messageid, char type)
 {
@@ -873,4 +772,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/OpenServer/OpenServerPlatformUtils.cpp b/src/xercesc/util/Platforms/OpenServer/OpenServerPlatformUtils.cpp
index 2e4d0d35fdab73e5b121e8ee26e74ae499808926..3e06d65c5036249052319d04494071f6d2648599 100644
--- a/src/xercesc/util/Platforms/OpenServer/OpenServerPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/OpenServer/OpenServerPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.6  2003/04/24 02:55:58  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.5  2003/03/09 16:57:18  peiyongz
  * PanicHandler
  *
@@ -381,107 +384,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths(const XMLCh* const   basePath,
-                                    const XMLCh* const   relativePath)
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-		&& (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-			   && ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            basePtr--;
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash)
-			&& (*pathPtr != chBackSlash)
-			&&  *pathPtr)
-            break;
-
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath) &&
-				   ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-                basePtr--;
-
-            // The base cannot provide enough levels, so its in error
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -723,5 +637,7 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/Platforms/QNX/QNXPlatformUtils.cpp b/src/xercesc/util/Platforms/QNX/QNXPlatformUtils.cpp
index e4049b2935e7390be03066d98a81f32bec48385d..64a30dd47bee613a69831719c0ad3f90a4f2f491 100644
--- a/src/xercesc/util/Platforms/QNX/QNXPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/QNX/QNXPlatformUtils.cpp
@@ -246,48 +246,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    tmpBuf[0] = (XMLCh)0;
-
-    //
-    //  If we have no base path, then just use the relative path.
-    //
-    if (!basePath && !*basePath) {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    //
-    // Make sure we get cleanup of all our local data.
-    //
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    // Create a path separator string.
-    //
-    XMLCh* slash = XMLString::transcode("/");
-    ArrayJanitor<XMLCh> slashJan(slash);
-
-    //
-    // Slap everything together.
-    //
-    XMLString::copyString(tmpBuf, basePath);
-    XMLString::copyString(tmpBuf, slash);
-    XMLString::copyString(tmpBuf, relativePath);
-
-    //
-    // Use our existing method to make the real full path.
-    //
-    return getFullPath( tmpBuf );
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -441,4 +411,6 @@ void XMLPlatformUtils::platformTerm()
 {
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/Solaris/SolarisPlatformUtils.cpp b/src/xercesc/util/Platforms/Solaris/SolarisPlatformUtils.cpp
index 06d105434d6cf1f7bc37b48438ec372ac1a48898..fd777065416dbb7751c4e10919de940d79c7e223 100644
--- a/src/xercesc/util/Platforms/Solaris/SolarisPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Solaris/SolarisPlatformUtils.cpp
@@ -373,116 +373,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths
-    (
-        const   XMLCh* const    basePath
-        , const XMLCh* const    relativePath
-    )
-{
-// Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
+{
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
-
-
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -762,4 +664,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/Tandem/TandemPlatformUtils.cpp b/src/xercesc/util/Platforms/Tandem/TandemPlatformUtils.cpp
index 219edb36a175cc88296f0ccb76856bf2178d95b1..ddbc0192421fc52ab20aabbd232e2784bddae0e0 100644
--- a/src/xercesc/util/Platforms/Tandem/TandemPlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Tandem/TandemPlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.8  2003/04/24 02:58:31  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.7  2003/03/09 17:00:11  peiyongz
  * PanicHandler
  *
@@ -263,6 +266,7 @@ XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
     // Return a copy of the path, in Unicode format
     return XMLString::transcode(newXMLString);
 }
+
 bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
 {
     // Check for pathological case of empty path
@@ -281,6 +285,23 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
+{
+
+    /*** 
+     *  REVISIT:
+     * 
+     *   To be implemented later
+    ***/
+
+    XMLCh curDir[]={ chPeriod, chForwardSlash, chNull};
+    return getFullPath(curDir);
+}
+
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -379,5 +400,6 @@ void XMLPlatformUtils::platformTerm()
     // We don't have any termination requirements at this time
 }
 
+#include <xercesc/util/LogicalPath.c>
 
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/Tru64/Tru64PlatformUtils.cpp b/src/xercesc/util/Platforms/Tru64/Tru64PlatformUtils.cpp
index 2fc3a7ced042c498c2ea2eb0674761b50354911b..99ea0fb52a4a9bcebb5cba3b535690fde0da8a41 100644
--- a/src/xercesc/util/Platforms/Tru64/Tru64PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Tru64/Tru64PlatformUtils.cpp
@@ -373,113 +373,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
   return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths (
-  const XMLCh* const basePath,
-  const XMLCh* const relativePath)
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-// Create a buffer as large as both parts and empty it
-  XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-			   + XMLString::stringLen(relativePath)
-			   + 2];
-  *tmpBuf = 0;
-
-  //
-  //  If we have no base path, then just take the relative path as
-  //  is.
-  //
-  if (!basePath)
-  {
-    XMLString::copyString(tmpBuf, relativePath);
-    return tmpBuf;
-  }
-
-  if (!*basePath)
-  {
-    XMLString::copyString(tmpBuf, relativePath);
-    return tmpBuf;
-  }
-
-  const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-  if ((*basePtr != chForwardSlash)
-      &&  (*basePtr != chBackSlash))
-  {
-    while ((basePtr >= basePath)
-	   &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-    {
-      basePtr--;
-    }
-  }
-
-  // There is no relevant base path, so just take the relative part
-  if (basePtr < basePath)
-  {
-    XMLString::copyString(tmpBuf, relativePath);
-    return tmpBuf;
-  }
-
-  // After this, make sure the buffer gets handled if we exit early
-  ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-  //
-  //  We have some path part, so we need to check to see if we ahve to
-  //  weave any of the parts together.
-  //
-  const XMLCh* pathPtr = relativePath;
-  while (true)
-  {
-    // If it does not start with some period, then we are done
-    if (*pathPtr != chPeriod)
-      break;
-
-    unsigned int periodCount = 1;
-    pathPtr++;
-    if (*pathPtr == chPeriod)
-    {
-      pathPtr++;
-      periodCount++;
-    }
-
-    // Has to be followed by a \ or / or the null to mean anything
-    if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-    {
-      break;
-    }
-    if (*pathPtr)
-      pathPtr++;
-
-    // If its one period, just eat it, else move backwards in the base
-    if (periodCount == 2)
-    {
-      basePtr--;
-      while ((basePtr >= basePath)
-	     &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-      {
-	basePtr--;
-      }
-
-      if (basePtr < basePath)
-      {
-	// The base cannot provide enough levels, so its in error
-	// <TBD>
-      }
-    }
-  }
-
-  // Copy the base part up to the base pointer
-  XMLCh* bufPtr = tmpBuf;
-  const XMLCh* tmpPtr = basePath;
-  while (tmpPtr <= basePtr)
-    *bufPtr++ = *tmpPtr++;
-
-  // And then copy on the rest of our path
-  XMLString::copyString(bufPtr, pathPtr);
-
-  // Orphan the buffer and return it
-  janBuf.orphan();
-  return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -722,4 +627,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/UnixWare/UnixWarePlatformUtils.cpp b/src/xercesc/util/Platforms/UnixWare/UnixWarePlatformUtils.cpp
index cad2961d1f2ed9ac8b18cc8f116579b1686fc5cd..609e13aa519bc1ea45e3f3ab32053b8c208c4261 100644
--- a/src/xercesc/util/Platforms/UnixWare/UnixWarePlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/UnixWare/UnixWarePlatformUtils.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.8  2003/04/24 02:59:20  peiyongz
+ * Logical Path Resolution
+ *
  * Revision 1.7  2003/04/21 04:32:10  peiyongz
  * performance tuning
  *
@@ -432,112 +435,18 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    if ((*basePtr != chForwardSlash)
-    &&  (*basePtr != chBackSlash))
-    {
-        while ((basePtr >= basePath)
-        &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-        {
-            basePtr--;
-        }
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException,
-                         XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = getcwd(NULL, PATH_MAX+1);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
+{
+    return ( chBackSlash == c || chForwardSlash == c);
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -759,4 +668,6 @@ void XMLPlatformUtils::platformTerm()
 #endif
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp b/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
index 4a61a17857d5a9f7d0b79782692d4447999a93e0..6858fda3cd50b8c38fcb493b65258a3bf0ee9a05 100644
--- a/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
@@ -73,6 +73,7 @@
 #include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <direct.h>
 
 #ifdef _DEBUG
  #ifdef _MSC_VER
@@ -167,15 +168,6 @@ static bool isBackSlash(XMLCh c) {
            c == chWonSign;
 }
 
-static bool isAnySlash(XMLCh c) {
-    return c == chBackSlash    ||
-           c == chForwardSlash ||
-           c == chYenSign      ||
-           c == chWonSign;
-}
-
-
-
 unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
 {
     // Get the current position
@@ -634,106 +626,21 @@ bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
     return true;
 }
 
-
-XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
-                                    , const XMLCh* const    relativePath)
-
+XMLCh* XMLPlatformUtils::getCurrentDirectory()
 {
-    // Create a buffer as large as both parts and empty it
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
-                              + XMLString::stringLen(relativePath)
-                              + 2];
-    *tmpBuf = 0;
-
-    //
-    //  If we have no base path, then just take the relative path as
-    //  is.
-    //
-    if (!basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    if (!*basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
-    while ((basePtr >= basePath)  &&  ((isAnySlash(*basePtr) == false)))
-    {
-        basePtr--;
-    }
-
-    // There is no relevant base path, so just take the relative part
-    if (basePtr < basePath)
-    {
-        XMLString::copyString(tmpBuf, relativePath);
-        return tmpBuf;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    const XMLCh* pathPtr = relativePath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a \ or / or the null to mean anything
-        if (isAnySlash(*pathPtr) == false &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePath) &&  (isAnySlash(*basePtr) == false))
-            {
-                basePtr--;
-            }
-
-            // The base cannot provide enough levels, so its in error/
-            if (basePtr < basePath)
-                ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePath;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Orphan the buffer and return it
-    janBuf.orphan();
-    return tmpBuf;
+    char  *tempDir = _getcwd(NULL, 0);
+    XMLCh *curDir = tempDir ? XMLString::transcode(tempDir) : 0;
+    free(tempDir);
+    return curDir;
 }
 
-
+inline bool XMLPlatformUtils::isAnySlash(XMLCh c)
+{
+    return c == chBackSlash    ||
+           c == chForwardSlash ||
+           c == chYenSign      ||
+           c == chWonSign;
+}
 
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: Timing Methods
@@ -943,4 +850,6 @@ void XMLPlatformUtils::platformTerm()
     // We don't have any temrination requirements for win32 at this time
 }
 
+#include <xercesc/util/LogicalPath.c>
+
 XERCES_CPP_NAMESPACE_END