/* 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 <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 SystemToolsStatic;

/** \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();

  SystemToolsManager(const SystemToolsManager&) = delete;
  SystemToolsManager& operator=(const SystemToolsManager&) = delete;
};

// 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<std::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 read a full line and truncates it if
   * requested via sizeLimit. 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);

  /**
   * Compare the contents of two files, ignoring line ending differences.
   * Return true if different
   */
  static bool TextFilesDiffer(const std::string& path1,
                              const std::string& path2);

  /**
   * 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();

#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP
  /**
   * 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);
#endif

  /**
   * 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;
  }

  static SystemToolsStatic* Statics;
  friend class SystemToolsStatic;
  friend class SystemToolsManager;
};

} // namespace @KWSYS_NAMESPACE@

#endif
