/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx
#define @KWSYS_NAMESPACE@_SystemTools_hxx

#include <@KWSYS_NAMESPACE@/Configure.hxx>

#include <iosfwd>
#include <map>
#include <string>
#include <vector>

#include <@KWSYS_NAMESPACE@/String.hxx>

#include <sys/types.h>
// include sys/stat.h after sys/types.h
#include <sys/stat.h>

#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h> // For access permissions for use with access()
#endif

// Required for va_list
#include <stdarg.h>
// Required for FILE*
#include <stdio.h>
#if !defined(va_list)
// Some compilers move va_list into the std namespace and there is no way to
// tell that this has been done. Playing with things being included before or
// after stdarg.h does not solve things because we do not have control over
// what the user does. This hack solves this problem by moving va_list to our
// own namespace that is local for kwsys.
namespace std {
} // Required for platforms that do not have std namespace
namespace @KWSYS_NAMESPACE@_VA_LIST {
using namespace std;
typedef va_list hack_va_list;
}
namespace @KWSYS_NAMESPACE@ {
typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
}
#endif // va_list

namespace @KWSYS_NAMESPACE@ {

class SystemToolsTranslationMap;
class SystemToolsPathCaseMap;
class SystemToolsEnvMap;

/** \class SystemToolsManager
 * \brief Use to make sure SystemTools is initialized before it is used
 * and is the last static object destroyed
 */
class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager
{
public:
  SystemToolsManager();
  ~SystemToolsManager();
};

// This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;

// Flags for use with TestFileAccess.  Use a typedef in case any operating
// system in the future needs a special type.  These are flags that may be
// combined using the | operator.
typedef int TestFilePermissions;
#if defined(_WIN32) && !defined(__CYGWIN__)
// On Windows (VC and Borland), no system header defines these constants...
static const TestFilePermissions TEST_FILE_OK = 0;
static const TestFilePermissions TEST_FILE_READ = 4;
static const TestFilePermissions TEST_FILE_WRITE = 2;
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
#else
// Standard POSIX constants
static const TestFilePermissions TEST_FILE_OK = F_OK;
static const TestFilePermissions TEST_FILE_READ = R_OK;
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
#endif

/** \class SystemTools
 * \brief A collection of useful platform-independent system functions.
 */
class @KWSYS_NAMESPACE@_EXPORT SystemTools
{
public:
  /** -----------------------------------------------------------------
   *               String Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Replace symbols in str that are not valid in C identifiers as
   * defined by the 1999 standard, ie. anything except [A-Za-z0-9_].
   * They are replaced with `_' and if the first character is a digit
   * then an underscore is prepended.  Note that this can produce
   * identifiers that the standard reserves (_[A-Z].* and __.*).
   */
  static std::string MakeCidentifier(const std::string& s);

  static std::string MakeCindentifier(const std::string& s)
  {
    return MakeCidentifier(s);
  }

  /**
   * Replace replace all occurrences of the string in the source string.
   */
  static void ReplaceString(std::string& source, const char* replace,
                            const char* with);
  static void ReplaceString(std::string& source, const std::string& replace,
                            const std::string& with);

  /**
   * Return a capitalized string (i.e the first letter is uppercased,
   * all other are lowercased).
   */
  static std::string Capitalized(const std::string&);

  /**
   * Return a 'capitalized words' string (i.e the first letter of each word
   * is uppercased all other are left untouched though).
   */
  static std::string CapitalizedWords(const std::string&);

  /**
   * Return a 'uncapitalized words' string (i.e the first letter of each word
   * is lowercased all other are left untouched though).
   */
  static std::string UnCapitalizedWords(const std::string&);

  /**
   * Return a lower case string
   */
  static std::string LowerCase(const std::string&);

  /**
   * Return a lower case string
   */
  static std::string UpperCase(const std::string&);

  /**
   * Count char in string
   */
  static size_t CountChar(const char* str, char c);

  /**
   * Remove some characters from a string.
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveChars(const char* str, const char* toremove);

  /**
   * Remove remove all but 0->9, A->F characters from a string.
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveCharsButUpperHex(const char* str);

  /**
   * Replace some characters by another character in a string (in-place)
   * Return a pointer to string
   */
  static char* ReplaceChars(char* str, const char* toreplace,
                            char replacement);

  /**
   * Returns true if str1 starts (respectively ends) with str2
   */
  static bool StringStartsWith(const char* str1, const char* str2);
  static bool StringStartsWith(const std::string& str1, const char* str2);
  static bool StringEndsWith(const char* str1, const char* str2);
  static bool StringEndsWith(const std::string& str1, const char* str2);

  /**
   * Returns a pointer to the last occurrence of str2 in str1
   */
  static const char* FindLastString(const char* str1, const char* str2);

  /**
   * Make a duplicate of the string similar to the strdup C function
   * but use new to create the 'new' string, so one can use
   * 'delete' to remove it. Returns 0 if the input is empty.
   */
  static char* DuplicateString(const char* str);

  /**
   * Return the string cropped to a given length by removing chars in the
   * center of the string and replacing them with an ellipsis (...)
   */
  static std::string CropString(const std::string&, size_t max_len);

  /** split a path by separator into an array of strings, default is /.
      If isPath is true then the string is treated like a path and if
      s starts with a / then the first element of the returned array will
      be /, so /foo/bar will be [/, foo, bar]
  */
  static std::vector<String> SplitString(const std::string& s,
                                         char separator = '/',
                                         bool isPath = false);
  /**
   * Perform a case-independent string comparison
   */
  static int Strucmp(const char* s1, const char* s2);

  /**
   * Split a string on its newlines into multiple lines
   * Return false only if the last line stored had no newline
   */
  static bool Split(const std::string& s, std::vector<std::string>& l);
  static bool Split(const std::string& s, std::vector<std::string>& l,
                    char separator);

  /**
   * Return string with space added between capitalized words
   * (i.e. EatMyShorts becomes Eat My Shorts )
   * (note that IEatShorts becomes IEat Shorts)
   */
  static std::string AddSpaceBetweenCapitalizedWords(const std::string&);

  /**
   * Append two or more strings and produce new one.
   * Programmer must 'delete []' the resulting string, which was allocated
   * with 'new'.
   * Return 0 if inputs are empty or there was an error
   */
  static char* AppendStrings(const char* str1, const char* str2);
  static char* AppendStrings(const char* str1, const char* str2,
                             const char* str3);

  /**
   * Estimate the length of the string that will be produced
   * from printing the given format string and arguments.  The
   * returned length will always be at least as large as the string
   * that will result from printing.
   * WARNING: since va_arg is called to iterate of the argument list,
   * you will not be able to use this 'ap' anymore from the beginning.
   * It's up to you to call va_end though.
   */
  static int EstimateFormatLength(const char* format, va_list ap);

  /**
   * Escape specific characters in 'str'.
   */
  static std::string EscapeChars(const char* str, const char* chars_to_escape,
                                 char escape_char = '\\');

  /** -----------------------------------------------------------------
   *               Filename Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Replace Windows file system slashes with Unix-style slashes.
   */
  static void ConvertToUnixSlashes(std::string& path);

#ifdef _WIN32
  /** Calls Encoding::ToWindowsExtendedPath.  */
  static std::wstring ConvertToWindowsExtendedPath(const std::string&);
#endif

  /**
   * For windows this calls ConvertToWindowsOutputPath and for unix
   * it calls ConvertToUnixOutputPath
   */
  static std::string ConvertToOutputPath(const std::string&);

  /**
   * Convert the path to a string that can be used in a unix makefile.
   * double slashes are removed, and spaces are escaped.
   */
  static std::string ConvertToUnixOutputPath(const std::string&);

  /**
   * Convert the path to string that can be used in a windows project or
   * makefile.   Double slashes are removed if they are not at the start of
   * the string, the slashes are converted to windows style backslashes, and
   * if there are spaces in the string it is double quoted.
   */
  static std::string ConvertToWindowsOutputPath(const std::string&);

  /**
   * Return true if a path with the given name exists in the current directory.
   */
  static bool PathExists(const std::string& path);

  /**
   * Return true if a file exists in the current directory.
   * If isFile = true, then make sure the file is a file and
   * not a directory.  If isFile = false, then return true
   * if it is a file or a directory.  Note that the file will
   * also be checked for read access.  (Currently, this check
   * for read access is only done on POSIX systems.)
   */
  static bool FileExists(const char* filename, bool isFile);
  static bool FileExists(const std::string& filename, bool isFile);
  static bool FileExists(const char* filename);
  static bool FileExists(const std::string& filename);

  /**
   * Test if a file exists and can be accessed with the requested
   * permissions.  Symbolic links are followed.  Returns true if
   * the access test was successful.
   *
   * On POSIX systems (including Cygwin), this maps to the access
   * function.  On Windows systems, all existing files are
   * considered readable, and writable files are considered to
   * have the read-only file attribute cleared.
   */
  static bool TestFileAccess(const char* filename,
                             TestFilePermissions permissions);
  static bool TestFileAccess(const std::string& filename,
                             TestFilePermissions permissions);
/**
 * Cross platform wrapper for stat struct
 */
#if defined(_WIN32) && !defined(__CYGWIN__)
#if defined(__BORLANDC__)
  typedef struct stati64 Stat_t;
#else
  typedef struct _stat64 Stat_t;
#endif
#else
  typedef struct stat Stat_t;
#endif

  /**
   * Cross platform wrapper for stat system call
   *
   * On Windows this may not work for paths longer than 250 characters
   * due to limitations of the underlying '_wstat64' call.
   */
  static int Stat(const char* path, Stat_t* buf);
  static int Stat(const std::string& path, Stat_t* buf);

/**
 * Converts Cygwin path to Win32 path. Uses dictionary container for
 * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
 * for actual translation.  Returns true on success, else false.
 */
#ifdef __CYGWIN__
  static bool PathCygwinToWin32(const char* path, char* win32_path);
#endif

  /**
   * Return file length
   */
  static unsigned long FileLength(const std::string& filename);

  /**
     Change the modification time or create a file
  */
  static bool Touch(const std::string& filename, bool create);

  /**
   *  Compare file modification times.
   *  Return true for successful comparison and false for error.
   *  When true is returned, result has -1, 0, +1 for
   *  f1 older, same, or newer than f2.
   */
  static bool FileTimeCompare(const std::string& f1, const std::string& f2,
                              int* result);

  /**
   *  Get the file extension (including ".") needed for an executable
   *  on the current platform ("" for unix, ".exe" for Windows).
   */
  static const char* GetExecutableExtension();

  /**
   * Given a path on a Windows machine, return the actual case of
   * the path as it exists on disk.  Path components that do not
   * exist on disk are returned unchanged.  Relative paths are always
   * returned unchanged.  Drive letters are always made upper case.
   * This does nothing on non-Windows systems but return the path.
   */
  static std::string GetActualCaseForPath(const std::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 std::string GetProgramPath(const std::string&);
  static bool SplitProgramPath(const std::string& in_name, std::string& dir,
                               std::string& file, bool errorReport = true);

  /**
   *  Given argv[0] for a unix program find the full path to a running
   *  executable.  argv0 can be null for windows WinMain programs
   *  in this case GetModuleFileName will be used to find the path
   *  to the running executable.  If argv0 is not a full path,
   *  then this will try to find the full path.  If the path is not
   *  found false is returned, if found true is returned.  An error
   *  message of the attempted paths is stored in errorMsg.
   *  exeName is the name of the executable.
   *  buildDir is a possibly null path to the build directory.
   *  installPrefix is a possibly null pointer to the install directory.
   */
  static bool FindProgramPath(const char* argv0, std::string& pathOut,
                              std::string& errorMsg, const char* exeName = 0,
                              const char* buildDir = 0,
                              const char* installPrefix = 0);

  /**
   * Given a path to a file or directory, convert it to a full path.
   * This collapses away relative paths relative to the cwd argument
   * (which defaults to the current working directory).  The full path
   * is returned.
   */
  static std::string CollapseFullPath(const std::string& in_relative);
  static std::string CollapseFullPath(const std::string& in_relative,
                                      const char* in_base);
  static std::string CollapseFullPath(const std::string& in_relative,
                                      const std::string& in_base);

  /**
   * Get the real path for a given path, removing all symlinks.  In
   * the event of an error (non-existent path, permissions issue,
   * etc.) the original path is returned if errorMessage pointer is
   * NULL.  Otherwise empty string is returned and errorMessage
   * contains error description.
   */
  static std::string GetRealPath(const std::string& path,
                                 std::string* errorMessage = 0);

  /**
   * Split a path name into its root component and the rest of the
   * path.  The root component is one of the following:
   *    "/"   = UNIX full path
   *    "c:/" = Windows full path (can be any drive letter)
   *    "c:"  = Windows drive-letter relative path (can be any drive letter)
   *    "//"  = Network path
   *    "~/"  = Home path for current user
   *    "~u/" = Home path for user 'u'
   *    ""    = Relative path
   *
   * A pointer to the rest of the path after the root component is
   * returned.  The root component is stored in the "root" string if
   * given.
   */
  static const char* SplitPathRootComponent(const std::string& p,
                                            std::string* root = 0);

  /**
   * Split a path name into its basic components.  The first component
   * always exists and is the root returned by SplitPathRootComponent.
   * The remaining components form the path.  If there is a trailing
   * slash then the last component is the empty string.  The
   * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to
   * produce the original path.  Home directory references are
   * automatically expanded if expand_home_dir is true and this
   * platform supports them.
   *
   * This does *not* normalize the input path.  All components are
   * preserved, including empty ones.  Typically callers should use
   * this only on paths that have already been normalized.
   */
  static void SplitPath(const std::string& p,
                        std::vector<std::string>& components,
                        bool expand_home_dir = true);

  /**
   * Join components of a path name into a single string.  See
   * SplitPath for the format of the components.
   *
   * This does *not* normalize the input path.  All components are
   * preserved, including empty ones.  Typically callers should use
   * this only on paths that have already been normalized.
   */
  static std::string JoinPath(const std::vector<std::string>& components);
  static std::string JoinPath(std::vector<std::string>::const_iterator first,
                              std::vector<std::string>::const_iterator last);

  /**
   * Compare a path or components of a path.
   */
  static bool ComparePath(const std::string& c1, const std::string& c2);

  /**
   * Return path of a full filename (no trailing slashes)
   */
  static std::string GetFilenamePath(const std::string&);

  /**
   * Return file name of a full filename (i.e. file name without path)
   */
  static std::string GetFilenameName(const std::string&);

  /**
   * Return longest file extension of a full filename (dot included)
   */
  static std::string GetFilenameExtension(const std::string&);

  /**
   * Return shortest file extension of a full filename (dot included)
   */
  static std::string GetFilenameLastExtension(const std::string& filename);

  /**
   * Return file name without extension of a full filename
   */
  static std::string GetFilenameWithoutExtension(const std::string&);

  /**
   * Return file name without its last (shortest) extension
   */
  static std::string GetFilenameWithoutLastExtension(const std::string&);

  /**
   * Return whether the path represents a full path (not relative)
   */
  static bool FileIsFullPath(const std::string&);
  static bool FileIsFullPath(const char*);

  /**
   * For windows return the short path for the given path,
   * Unix just a pass through
   */
  static bool GetShortPath(const std::string& path, std::string& result);

  /**
   * Read line from file. Make sure to get everything. Due to a buggy stream
   * library on the HP and another on Mac OS X, we need this very carefully
   * written version of getline. Returns true if any data were read before the
   * end-of-file was reached. If the has_newline argument is specified, it will
   * be true when the line read had a newline character.
   */
  static bool GetLineFromStream(std::istream& istr, std::string& line,
                                bool* has_newline = 0, long sizeLimit = -1);

  /**
   * Get the parent directory of the directory or file
   */
  static std::string GetParentDirectory(const std::string& fileOrDir);

  /**
   * Check if the given file or directory is in subdirectory of dir
   */
  static bool IsSubDirectory(const std::string& fileOrDir,
                             const std::string& dir);

  /** -----------------------------------------------------------------
   *               File Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Open a file considering unicode.
   */
  static FILE* Fopen(const std::string& file, const char* mode);

/**
 * Visual C++ does not define mode_t (note that Borland does, however).
 */
#if defined(_MSC_VER)
  typedef unsigned short mode_t;
#endif

  /**
   * Make a new directory if it is not there.  This function
   * can make a full path even if none of the directories existed
   * prior to calling this function.
   */
  static bool MakeDirectory(const char* path, const mode_t* mode = 0);
  static bool MakeDirectory(const std::string& path, const mode_t* mode = 0);

  /**
   * Copy the source file to the destination file only
   * if the two files differ.
   */
  static bool CopyFileIfDifferent(const std::string& source,
                                  const std::string& destination);

  /**
   * Compare the contents of two files.  Return true if different
   */
  static bool FilesDiffer(const std::string& source,
                          const std::string& destination);

  /**
   * Return true if the two files are the same file
   */
  static bool SameFile(const std::string& file1, const std::string& file2);

  /**
   * Copy a file.
   */
  static bool CopyFileAlways(const std::string& source,
                             const std::string& destination);

  /**
   * Copy a file.  If the "always" argument is true the file is always
   * copied.  If it is false, the file is copied only if it is new or
   * has changed.
   */
  static bool CopyAFile(const std::string& source,
                        const std::string& destination, bool always = true);

  /**
   * Copy content directory to another directory with all files and
   * subdirectories.  If the "always" argument is true all files are
   * always copied.  If it is false, only files that have changed or
   * are new are copied.
   */
  static bool CopyADirectory(const std::string& source,
                             const std::string& destination,
                             bool always = true);

  /**
   * Remove a file
   */
  static bool RemoveFile(const std::string& source);

  /**
   * Remove a directory
   */
  static bool RemoveADirectory(const std::string& source);

  /**
   * Get the maximum full file path length
   */
  static size_t GetMaximumFilePathLength();

  /**
   * Find a file in the system PATH, with optional extra paths
   */
  static std::string FindFile(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find a directory in the system PATH, with optional extra paths
   */
  static std::string FindDirectory(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find an executable in the system PATH, with optional extra paths
   */
  static std::string FindProgram(
    const char* name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);
  static std::string FindProgram(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);
  static std::string FindProgram(
    const std::vector<std::string>& names,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find a library in the system PATH, with optional extra paths
   */
  static std::string FindLibrary(const std::string& name,
                                 const std::vector<std::string>& path);

  /**
   * Return true if the file is a directory
   */
  static bool FileIsDirectory(const std::string& name);

  /**
   * Return true if the file is a symlink
   */
  static bool FileIsSymlink(const std::string& name);

  /**
   * Return true if the file is a FIFO
   */
  static bool FileIsFIFO(const std::string& name);

  /**
   * Return true if the file has a given signature (first set of bytes)
   */
  static bool FileHasSignature(const char* filename, const char* signature,
                               long offset = 0);

  /**
   * Attempt to detect and return the type of a file.
   * Up to 'length' bytes are read from the file, if more than 'percent_bin' %
   * of the bytes are non-textual elements, the file is considered binary,
   * otherwise textual. Textual elements are bytes in the ASCII [0x20, 0x7E]
   * range, but also \\n, \\r, \\t.
   * The algorithm is simplistic, and should probably check for usual file
   * extensions, 'magic' signature, unicode, etc.
   */
  enum FileTypeEnum
  {
    FileTypeUnknown,
    FileTypeBinary,
    FileTypeText
  };
  static SystemTools::FileTypeEnum DetectFileType(const char* filename,
                                                  unsigned long length = 256,
                                                  double percent_bin = 0.05);

  /**
   * Create a symbolic link if the platform supports it.  Returns whether
   * creation succeeded.
   */
  static bool CreateSymlink(const std::string& origName,
                            const std::string& newName);

  /**
   * Read the contents of a symbolic link.  Returns whether reading
   * succeeded.
   */
  static bool ReadSymlink(const std::string& newName, std::string& origName);

  /**
   * Try to locate the file 'filename' in the directory 'dir'.
   * If 'filename' is a fully qualified filename, the basename of the file is
   * used to check for its existence in 'dir'.
   * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to
   * get its directory first (thus, you can pass a filename as 'dir', as
   * a convenience).
   * 'filename_found' is assigned the fully qualified name/path of the file
   * if it is found (not touched otherwise).
   * If 'try_filename_dirs' is true, try to find the file using the
   * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
   * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
   * etc.
   * Return true if the file was found, false otherwise.
   */
  static bool LocateFileInDir(const char* filename, const char* dir,
                              std::string& filename_found,
                              int try_filename_dirs = 0);

  /** compute the relative path from local to remote.  local must
      be a directory.  remote can be a file or a directory.
      Both remote and local must be full paths.  Basically, if
      you are in directory local and you want to access the file in remote
      what is the relative path to do that.  For example:
      /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
      from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
  */
  static std::string RelativePath(const std::string& local,
                                  const std::string& remote);

  /**
   * Return file's modified time
   */
  static long int ModifiedTime(const std::string& filename);

  /**
   * Return file's creation time (Win32: works only for NTFS, not FAT)
   */
  static long int CreationTime(const std::string& filename);

  /**
   * Get and set permissions of the file.  If honor_umask is set, the umask
   * is queried and applied to the given permissions.  Returns false if
   * failure.
   *
   * WARNING:  A non-thread-safe method is currently used to get the umask
   * if a honor_umask parameter is set to true.
   */
  static bool GetPermissions(const char* file, mode_t& mode);
  static bool GetPermissions(const std::string& file, mode_t& mode);
  static bool SetPermissions(const char* file, mode_t mode,
                             bool honor_umask = false);
  static bool SetPermissions(const std::string& file, mode_t mode,
                             bool honor_umask = false);

  /** -----------------------------------------------------------------
   *               Time Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /** Get current time in seconds since Posix Epoch (Jan 1, 1970).  */
  static double GetTime();

  /**
   * Get current date/time
   */
  static std::string GetCurrentDateTime(const char* format);

  /** -----------------------------------------------------------------
   *               Registry Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Specify access to the 32-bit or 64-bit application view of
   * registry values.  The default is to match the currently running
   * binary type.
   */
  enum KeyWOW64
  {
    KeyWOW64_Default,
    KeyWOW64_32,
    KeyWOW64_64
  };

  /**
   * Get a list of subkeys.
   */
  static bool GetRegistrySubKeys(const std::string& key,
                                 std::vector<std::string>& subkeys,
                                 KeyWOW64 view = KeyWOW64_Default);

  /**
   * Read a registry value
   */
  static bool ReadRegistryValue(const std::string& key, std::string& value,
                                KeyWOW64 view = KeyWOW64_Default);

  /**
   * Write a registry value
   */
  static bool WriteRegistryValue(const std::string& key,
                                 const std::string& value,
                                 KeyWOW64 view = KeyWOW64_Default);

  /**
   * Delete a registry value
   */
  static bool DeleteRegistryValue(const std::string& key,
                                  KeyWOW64 view = KeyWOW64_Default);

  /** -----------------------------------------------------------------
   *               Environment Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   *  Add the paths from the environment variable PATH to the
   *  string vector passed in.  If env is set then the value
   *  of env will be used instead of PATH.
   */
  static void GetPath(std::vector<std::string>& path, const char* env = 0);

  /**
   * Read an environment variable
   */
  static const char* GetEnv(const char* key);
  static const char* GetEnv(const std::string& key);
  static bool GetEnv(const char* key, std::string& result);
  static bool GetEnv(const std::string& key, std::string& result);
  static bool HasEnv(const char* key);
  static bool HasEnv(const std::string& key);

  /** Put a string into the environment
      of the form var=value */
  static bool PutEnv(const std::string& env);

  /** Remove a string from the environment.
      Input is of the form "var" or "var=value" (value is ignored). */
  static bool UnPutEnv(const std::string& env);

  /**
   * Get current working directory CWD
   */
  static std::string GetCurrentWorkingDirectory(bool collapse = true);

  /**
   * Change directory to the directory specified
   */
  static int ChangeDirectory(const std::string& dir);

  /**
   * Get the result of strerror(errno)
   */
  static std::string GetLastSystemError();

  /**
   * When building DEBUG with MSVC, this enables a hook that prevents
   * error dialogs from popping up if the program is being run from
   * DART.
   */
  static void EnableMSVCDebugHook();

  /**
   * Get the width of the terminal window. The code may or may not work, so
   * make sure you have some reasonable defaults prepared if the code returns
   * some bogus size.
   */
  static int GetTerminalWidth();

  /**
   * Add an entry in the path translation table.
   */
  static void AddTranslationPath(const std::string& dir,
                                 const std::string& refdir);

  /**
   * If dir is different after CollapseFullPath is called,
   * Then insert it into the path translation table
   */
  static void AddKeepPath(const std::string& dir);

  /**
   * Update path by going through the Path Translation table;
   */
  static void CheckTranslationPath(std::string& path);

  /**
   * Delay the execution for a specified amount of time specified
   * in milliseconds
   */
  static void Delay(unsigned int msec);

  /**
   * Get the operating system name and version
   * This is implemented for Win32 only for the moment
   */
  static std::string GetOperatingSystemNameAndVersion();

  /** -----------------------------------------------------------------
   *               URL Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Parse a character string :
   *       protocol://dataglom
   * and fill protocol as appropriate.
   * Return false if the URL does not have the required form, true otherwise.
   */
  static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
                               std::string& dataglom);

  /**
   * Parse a string (a URL without protocol prefix) with the form:
   *  protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
   * and fill protocol, username, password, hostname, dataport, and datapath
   * when values are found.
   * Return true if the string matches the format; false otherwise.
   */
  static bool ParseURL(const std::string& URL, std::string& protocol,
                       std::string& username, std::string& password,
                       std::string& hostname, std::string& dataport,
                       std::string& datapath);

private:
  /**
   * Allocate the stl map that serve as the Path Translation table.
   */
  static void ClassInitialize();

  /**
   * Deallocate the stl map that serve as the Path Translation table.
   */
  static void ClassFinalize();

  /**
   * This method prevents warning on SGI
   */
  SystemToolsManager* GetSystemToolsManager()
  {
    return &SystemToolsManagerInstance;
  }

  /**
   * Actual implementation of ReplaceString.
   */
  static void ReplaceString(std::string& source, const char* replace,
                            size_t replaceSize, const std::string& with);

  /**
   * Actual implementation of FileIsFullPath.
   */
  static bool FileIsFullPath(const char*, size_t);

  /**
   * Find a filename (file or directory) in the system PATH, with
   * optional extra paths.
   */
  static std::string FindName(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  static const char* GetEnvImpl(const char* key);

  /**
   * Path translation table from dir to refdir
   * Each time 'dir' will be found it will be replace by 'refdir'
   */
  static SystemToolsTranslationMap* TranslationMap;
#ifdef _WIN32
  static std::string GetActualCaseForPathCached(std::string const& path);
  static SystemToolsPathCaseMap* PathCaseMap;
  static SystemToolsEnvMap* EnvMap;
#endif
#ifdef __CYGWIN__
  static SystemToolsTranslationMap* Cyg2Win32Map;
#endif
  friend class SystemToolsManager;
};

} // namespace @KWSYS_NAMESPACE@

#endif
