diff --git a/Glob.cxx b/Glob.cxx
index 0916d2e6f26c1f27df7e6b33356932d5df80b51d..5a96aed430e552c3932dcc620d25dde687b0ca47 100644
--- a/Glob.cxx
+++ b/Glob.cxx
@@ -501,7 +501,7 @@ void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const kwsys_stl:
 {
   if ( !this->Relative.empty() )
     {
-    files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file.c_str()));
+    files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file));
     }
   else
     {
diff --git a/SystemTools.cxx b/SystemTools.cxx
index c0c5baf1370684333b89ebe8b489f348a82312df..1ad91e512427c86ec64217295f1dbb9a60834053 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -2414,7 +2414,7 @@ bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_st
 
 
 // return size of file; also returns zero if no file exists
-unsigned long SystemTools::FileLength(const char* filename)
+unsigned long SystemTools::FileLength(const kwsys_stl::string& filename)
 {
   unsigned long length = 0;
 #ifdef _WIN32
@@ -2432,7 +2432,7 @@ unsigned long SystemTools::FileLength(const char* filename)
     }
 #else
   struct stat fs;
-  if (stat(filename, &fs) == 0)
+  if (stat(filename.c_str(), &fs) == 0)
     {
     length = static_cast<unsigned long>(fs.st_size);
     }
@@ -2698,7 +2698,7 @@ size_t SystemTools::GetMaximumFilePathLength()
  * found.  Otherwise, the empty string is returned.
  */
 kwsys_stl::string SystemTools
-::FindName(const char* name,
+::FindName(const kwsys_stl::string& name,
            const kwsys_stl::vector<kwsys_stl::string>& userPaths,
            bool no_system_path)
 {
@@ -2751,7 +2751,7 @@ kwsys_stl::string SystemTools
  * found.  Otherwise, the empty string is returned.
  */
 kwsys_stl::string SystemTools
-::FindFile(const char* name,
+::FindFile(const kwsys_stl::string& name,
            const kwsys_stl::vector<kwsys_stl::string>& userPaths,
            bool no_system_path)
 {
@@ -2770,7 +2770,7 @@ kwsys_stl::string SystemTools
  * found.  Otherwise, the empty string is returned.
  */
 kwsys_stl::string SystemTools
-::FindDirectory(const char* name,
+::FindDirectory(const kwsys_stl::string& name,
                 const kwsys_stl::vector<kwsys_stl::string>& userPaths,
                 bool no_system_path)
 {
@@ -3113,29 +3113,29 @@ bool SystemTools::FileIsSymlink(const kwsys_stl::string& name)
 }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::CreateSymlink(const char*, const char*)
+bool SystemTools::CreateSymlink(const kwsys_stl::string&, const kwsys_stl::string&)
 {
   return false;
 }
 #else
-bool SystemTools::CreateSymlink(const char* origName, const char* newName)
+bool SystemTools::CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName)
 {
-  return symlink(origName, newName) >= 0;
+  return symlink(origName.c_str(), newName.c_str()) >= 0;
 }
 #endif
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-bool SystemTools::ReadSymlink(const char*, kwsys_stl::string&)
+bool SystemTools::ReadSymlink(const kwsys_stl::string&, kwsys_stl::string&)
 {
   return false;
 }
 #else
-bool SystemTools::ReadSymlink(const char* newName,
+bool SystemTools::ReadSymlink(const kwsys_stl::string& newName,
                               kwsys_stl::string& origName)
 {
   char buf[KWSYS_SYSTEMTOOLS_MAXPATH+1];
   int count =
-    static_cast<int>(readlink(newName, buf, KWSYS_SYSTEMTOOLS_MAXPATH));
+    static_cast<int>(readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH));
   if(count >= 0)
     {
     // Add null-terminator.
@@ -3171,14 +3171,14 @@ kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
   return path;
 }
 
-kwsys_stl::string SystemTools::GetProgramPath(const char* in_name)
+kwsys_stl::string SystemTools::GetProgramPath(const kwsys_stl::string& in_name)
 {
   kwsys_stl::string dir, file;
   SystemTools::SplitProgramPath(in_name, dir, file);
   return dir;
 }
 
-bool SystemTools::SplitProgramPath(const char* in_name,
+bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name,
                                    kwsys_stl::string& dir,
                                    kwsys_stl::string& file,
                                    bool)
@@ -3444,7 +3444,62 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path
 
   SystemTools::CheckTranslationPath(newPath);
 #ifdef _WIN32
-  newPath = SystemTools::GetActualCaseForPath(newPath.c_str());
+  newPath = SystemTools::GetActualCaseForPath(newPath);
+  SystemTools::ConvertToUnixSlashes(newPath);
+#endif
+  // Return the reconstructed path.
+  return newPath;
+}
+
+kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path,
+                                                const kwsys_stl::string& in_base)
+{
+  // Collect the output path components.
+  kwsys_stl::vector<kwsys_stl::string> out_components;
+
+  // Split the input path components.
+  kwsys_stl::vector<kwsys_stl::string> path_components;
+  SystemTools::SplitPath(in_path, path_components);
+
+  // If the input path is relative, start with a base path.
+  if(path_components[0].length() == 0)
+    {
+    kwsys_stl::vector<kwsys_stl::string> base_components;
+    // Use the given base path.
+    SystemTools::SplitPath(in_base, base_components);
+
+    // Append base path components to the output path.
+    out_components.push_back(base_components[0]);
+    SystemToolsAppendComponents(out_components,
+                                base_components.begin()+1,
+                                base_components.end());
+    }
+
+  // Append input path components to the output path.
+  SystemToolsAppendComponents(out_components,
+                              path_components.begin(),
+                              path_components.end());
+
+  // Transform the path back to a string.
+  kwsys_stl::string newPath = SystemTools::JoinPath(out_components);
+
+  // Update the translation table with this potentially new path.  I am not
+  // sure why this line is here, it seems really questionable, but yet I
+  // would put good money that if I remove it something will break, basically
+  // from what I can see it created a mapping from the collapsed path, to be
+  // replaced by the input path, which almost completely does the opposite of
+  // this function, the only thing preventing this from happening a lot is
+  // that if the in_path has a .. in it, then it is not added to the
+  // translation table. So for most calls this either does nothing due to the
+  // ..  or it adds a translation between identical paths as nothing was
+  // collapsed, so I am going to try to comment it out, and see what hits the
+  // fan, hopefully quickly.
+  // Commented out line below:
+  //SystemTools::AddTranslationPath(newPath, in_path);
+
+  SystemTools::CheckTranslationPath(newPath);
+#ifdef _WIN32
+  newPath = SystemTools::GetActualCaseForPath(newPath);
   SystemTools::ConvertToUnixSlashes(newPath);
 #endif
   // Return the reconstructed path.
@@ -3604,7 +3659,7 @@ static int GetCasePathName(const kwsys_stl::string & pathIn,
 
 
 //----------------------------------------------------------------------------
-kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p)
+kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p)
 {
 #ifndef _WIN32
   return p;
@@ -4311,7 +4366,7 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string&
 #endif
 }
 
-void SystemTools::SplitProgramFromArgs(const char* path,
+void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path,
                                        kwsys_stl::string& program, kwsys_stl::string& args)
 {
   // see if this is a full path to a program
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index 2e45fa1ac237faa4900f836810b3d35242a6722f..01d816ba057ad8ecb2d51b4327d63fecb4a18427 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -309,7 +309,7 @@ public:
   /**
    * Return file length
    */
-  static unsigned long FileLength(const char *filename);
+  static unsigned long FileLength(const kwsys_stl::string& filename);
 
   /**
      Change the modification time or create a file
@@ -338,15 +338,15 @@ public:
    *  does not exist path is returned unchanged.  This does nothing
    *  on unix but return path.
    */
-  static kwsys_stl::string GetActualCaseForPath(const char* path);
+  static kwsys_stl::string GetActualCaseForPath(const kwsys_stl::string& path);
 
   /**
    * Given the path to a program executable, get the directory part of
    * the path with the file stripped off.  If there is no directory
    * part, the empty string is returned.
    */
-  static kwsys_stl::string GetProgramPath(const char*);
-  static bool SplitProgramPath(const char* in_name,
+  static kwsys_stl::string GetProgramPath(const kwsys_stl::string&);
+  static bool SplitProgramPath(const kwsys_stl::string& in_name,
                                kwsys_stl::string& dir,
                                kwsys_stl::string& file,
                                bool errorReport = true);
@@ -379,6 +379,8 @@ public:
   static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative);
   static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
                                             const char* in_base);
+  static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative,
+                                            const kwsys_stl::string& in_base);
 
   /** 
    * Get the real path for a given path, removing all symlinks.  In
@@ -449,7 +451,7 @@ public:
    * Split a program from its arguments and handle spaces in the paths
    */
   static void SplitProgramFromArgs(
-    const char* path,
+    const kwsys_stl::string& path,
     kwsys_stl::string& program, kwsys_stl::string& args);
 
   /**
@@ -585,7 +587,7 @@ public:
    * Find a file in the system PATH, with optional extra paths
    */
   static kwsys_stl::string FindFile(
-    const char* name,
+    const kwsys_stl::string& name,
     const kwsys_stl::vector<kwsys_stl::string>& path = 
     kwsys_stl::vector<kwsys_stl::string>(),
     bool no_system_path = false);
@@ -594,7 +596,7 @@ public:
    * Find a directory in the system PATH, with optional extra paths
    */
   static kwsys_stl::string FindDirectory(
-    const char* name,
+    const kwsys_stl::string& name,
     const kwsys_stl::vector<kwsys_stl::string>& path = 
     kwsys_stl::vector<kwsys_stl::string>(),
     bool no_system_path = false);
@@ -665,13 +667,13 @@ public:
    * Create a symbolic link if the platform supports it.  Returns whether
    * creation succeded.
    */
-  static bool CreateSymlink(const char* origName, const char* newName);
+  static bool CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName);
 
   /**
    * Read the contents of a symbolic link.  Returns whether reading
    * succeded.
    */
-  static bool ReadSymlink(const char* newName, kwsys_stl::string& origName);
+  static bool ReadSymlink(const kwsys_stl::string& newName, kwsys_stl::string& origName);
 
   /**
    * Try to locate the file 'filename' in the directory 'dir'.
@@ -928,7 +930,7 @@ private:
    * optional extra paths.
    */
   static kwsys_stl::string FindName(
-    const char* name,
+    const kwsys_stl::string& name,
     const kwsys_stl::vector<kwsys_stl::string>& path = 
     kwsys_stl::vector<kwsys_stl::string>(),
     bool no_system_path = false);
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index 529bf058eaafdbfe9ccfe14b099ab5330c4ffbf8..42b62497b587dac6a0603f894e0c23a748192b00 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -124,7 +124,7 @@ static bool CheckFileOperations()
     res = false;
     }
 
-  if (kwsys::SystemTools::FileLength(testBinFile.c_str()) != 766)
+  if (kwsys::SystemTools::FileLength(testBinFile) != 766)
     {
     kwsys_ios::cerr
       << "Problem with FileLength - incorrect length for: "