diff --git a/Common/ConnectionManager.cpp b/Common/ConnectionManager.cpp
index 77372de68017f580bf0da596e0e96a5d3b5619a4..c10007bf98b02cf9ee1aeacece95917fbdb7d4f4 100644
--- a/Common/ConnectionManager.cpp
+++ b/Common/ConnectionManager.cpp
@@ -49,19 +49,19 @@ void ConnectionManager::runToGetOptions()
 {
   if(inputFileName.empty()) return;
   
-  std::string inputArg = inputFileName.empty() ? "" : ReplacePercentS
-    (inputFileSwitch, std::string("\"") + FixWindowsPath(inputFileName) + "\"");
-  std::string optionArg = ReplacePercentS(optionSwitch, "");
+  std::string inputArg = inputFileName.empty() ? "" : ReplaceSubString
+    ("%s", std::string("\"") + FixWindowsPath(inputFileName) + "\"", inputFileSwitch);
+  std::string optionArg = ReplaceSubString("%s", "", optionSwitch);
   run(inputArg + " " + optionArg);
 }
 
 void ConnectionManager::runCommand(int commandIndex, int optionIndex, int optionChoice)
 {
-  std::string inputArg = inputFileName.empty() ? "" : ReplacePercentS
-    (inputFileSwitch, std::string("\"") + FixWindowsPath(inputFileName) + "\"");
+  std::string inputArg = inputFileName.empty() ? "" : ReplaceSubString
+    ("%s", std::string("\"") + FixWindowsPath(inputFileName) + "\"", inputFileSwitch);
 
-  std::string meshArg = meshFileName.empty() ? "" : ReplacePercentS
-    (meshFileSwitch, std::string("\"") + FixWindowsPath(meshFileName) + "\"");
+  std::string meshArg = meshFileName.empty() ? "" : ReplaceSubString
+    ("%s", std::string("\"") + FixWindowsPath(meshFileName) + "\"", meshFileSwitch);
 
   if(commandIndex < 0 || commandIndex >= (int)buttonSwitch.size()){
     Msg::Error("Wrong command index");
@@ -79,8 +79,8 @@ void ConnectionManager::runCommand(int commandIndex, int optionIndex, int option
       Msg::Error("Wrong option choice");
       return;
     }
-    commandArg = ReplacePercentS
-      (buttonSwitch[commandIndex], optionValue[optionIndex][optionChoice]);
+    commandArg = ReplaceSubString
+      ("%s", optionValue[optionIndex][optionChoice], buttonSwitch[commandIndex]);
   }
   else{ // no options
     commandArg = buttonSwitch[commandIndex];
diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp
index 484032be852720f3d40f673e32a7e227ebb43ebf..5b289fee6759746738f47c79bb56ce9db65b17ab 100644
--- a/Common/StringUtils.cpp
+++ b/Common/StringUtils.cpp
@@ -62,7 +62,7 @@ std::string SanitizeTeXString(const char *in, int equation)
   return out;
 }
 
-std::string FixWindowsPath(std::string in)
+std::string FixWindowsPath(const std::string &in)
 {
 #if defined(__CYGWIN__)
   char tmp[1024];
@@ -73,7 +73,7 @@ std::string FixWindowsPath(std::string in)
 #endif
 }
 
-std::string FixRelativePath(std::string reference, std::string in)
+std::string FixRelativePath(const std::string &reference, const std::string &in)
 {
   if(in.empty()) return "";
 
@@ -88,7 +88,7 @@ std::string FixRelativePath(std::string reference, std::string in)
   }
 }
 
-std::vector<std::string> SplitFileName(std::string fileName)
+std::vector<std::string> SplitFileName(const std::string &fileName)
 {
   // returns [path, baseName, extension]
   int idot = fileName.find_last_of('.');
@@ -104,33 +104,7 @@ std::vector<std::string> SplitFileName(std::string fileName)
   return s;
 }
 
-std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len)
-{
-  std::vector<std::string> out(1);
-  for(unsigned int i = 0; i < in.size(); i++){
-    out.back() += in[i];
-    if(out.back().size() > len && in[i] == ' ')
-      out.resize(out.size() + 1);
-  }
-  return out;
-}
-
-std::string ReplacePercentS(std::string in, std::string val)
-{
-  std::string out;
-  for(unsigned int i = 0; i < in.size(); i++){
-    if(in[i] == '%' && i + 1 < in.size() && in[i + 1] == 's'){
-      out += val;
-      i++;
-    }
-    else{
-      out += in[i];
-    }
-  }
-  return out;
-}
-
-std::string ConvertFileToString(std::string fileName)
+std::string ConvertFileToString(const std::string &fileName)
 {
   FILE *fp = fopen(fileName.c_str(), "r");
   if(!fp) return "";
@@ -141,28 +115,28 @@ std::string ConvertFileToString(std::string fileName)
   return out;
 }
 
-void ConvertToHTML(std::string &in)
+void ReplaceSubStringInPlace(const std::string &olds, const std::string &news, 
+                             std::string &str)
 {
   while(1){
-    int pos = in.find("<");
-    if(pos == std::string::npos) break;
-    in.replace(pos, 1, "&lt;");
-  }
-  while(1){
-    int pos = in.find(">");
-    if(pos == std::string::npos) break;
-    in.replace(pos, 1, "&gt;");
-  }
-  while(1){
-    const char n2[3] = {'\n', '\n', '\0'};
-    int pos = in.find(n2);
-    if(pos == std::string::npos) break;
-    in.replace(pos, 2, "<p>");
-  }
-  while(1){
-    const char n1[2] = {'\n', '\0'};
-    int pos = in.find(n1);
+    int pos = str.find(olds.c_str());
     if(pos == std::string::npos) break;
-    in.replace(pos, 1, "<br>");
+    str.replace(pos, olds.size(), news.c_str());
   }
 }
+
+std::string ReplaceSubString(const std::string &olds, const std::string &news, 
+                             const std::string &str)
+{
+  std::string copy(str);
+  ReplaceSubStringInPlace(olds, news, copy);
+  return copy;
+}
+
+void ConvertToHTML(std::string &str)
+{
+  ReplaceSubStringInPlace("<", "&lt;", str);
+  ReplaceSubStringInPlace(">", "&gt;", str);
+  ReplaceSubStringInPlace("\n\n", "<p>", str);
+  ReplaceSubStringInPlace("\n", "<br>", str);
+}
diff --git a/Common/StringUtils.h b/Common/StringUtils.h
index 84699e5e2589eb5fd7e67340156532593fb18bea..7a50f119fad1c7d33a8bd2f0a43cf63208b98751 100644
--- a/Common/StringUtils.h
+++ b/Common/StringUtils.h
@@ -13,12 +13,14 @@
 void SwapBytes(char *array, int size, int n);
 std::string ExtractDoubleQuotedString(const char *str, int len);
 std::string SanitizeTeXString(const char *in, int equation);
-std::string FixWindowsPath(std::string in);
-std::string FixRelativePath(std::string reference, std::string in);
-std::vector<std::string> SplitFileName(std::string fileName);
-std::vector<std::string> SplitWhiteSpace(std::string in, unsigned int len);
-std::string ReplacePercentS(std::string in, std::string val);
-std::string ConvertFileToString(std::string fileName);
+std::string FixWindowsPath(const std::string &in);
+std::string FixRelativePath(const std::string &reference, const std::string &in);
+std::vector<std::string> SplitFileName(const std::string &fileName);
+std::string ConvertFileToString(const std::string &fileName);
+void ReplaceSubStringInPlace(const std::string &olds, const std::string &news, 
+                             std::string &str);
+std::string ReplaceSubString(const std::string &olds, const std::string &news, 
+                             const std::string &str);
 void ConvertToHTML(std::string &in);
 
 #endif
diff --git a/Fltk/aboutWindow.cpp b/Fltk/aboutWindow.cpp
index e5a87e7c60983998799c6d91893281cdd45db7d9..3cfb2ace55adccd789a2ceb7a33dfc077afd2d71 100644
--- a/Fltk/aboutWindow.cpp
+++ b/Fltk/aboutWindow.cpp
@@ -16,7 +16,7 @@
 static const char *help_link(Fl_Widget *w, const char *uri)
 {
   std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
-  SystemCall(ReplacePercentS(prog, uri));
+  SystemCall(ReplaceSubString("%s", uri, prog));
   return 0;
 }
 
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 23c3f4a4061307d27b1f1e79229a45886e512243..515cdeb642b57e2e74d9df1afa4793b102979c0b 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -547,7 +547,7 @@ static void help_command_line_cb(Fl_Widget *w, void *data)
 static void help_online_cb(Fl_Widget *w, void *data)
 {
   std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
-  SystemCall(ReplacePercentS(prog, "http://geuz.org/gmsh/doc/texinfo/"));
+  SystemCall(ReplaceSubString("%s", "http://geuz.org/gmsh/doc/texinfo/", prog));
 }
 
 static void help_about_cb(Fl_Widget *w, void *data)
@@ -599,7 +599,7 @@ static void geometry_edit_cb(Fl_Widget *w, void *data)
 {
   std::string prog = FixWindowsPath(CTX::instance()->editor);
   std::string file = FixWindowsPath(GModel::current()->getFileName());
-  SystemCall(ReplacePercentS(prog, file));
+  SystemCall(ReplaceSubString("%s", file, prog));
 }
 
 void geometry_reload_cb(Fl_Widget *w, void *data)
diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp
index a8348a460367b82d8aa2c4de4987d7835d7b55e5..f96075937a5d1380cf732f261a021ca3588f5c50 100644
--- a/Fltk/solverWindow.cpp
+++ b/Fltk/solverWindow.cpp
@@ -116,8 +116,8 @@ void ConnectionManager::run(std::string args)
   std::string command;
 
   if(prog.size()){
-    command = prog + " " + args + " " + ReplacePercentS
-      (socketSwitch, std::string("\"") + sockname + "\"");
+    command = prog + " " + args + " " + ReplaceSubString
+      ("%s", std::string("\"") + sockname + "\"", socketSwitch);
 #if !defined(WIN32)
     command += " &";
 #endif
@@ -362,7 +362,7 @@ static void solver_file_edit_cb(Fl_Widget *w, void *data)
   int num = (int)(long)data;
   std::string prog = FixWindowsPath(CTX::instance()->editor);
   std::string file = FixWindowsPath(FlGui::instance()->solver[num]->input[0]->value());
-  SystemCall(ReplacePercentS(prog, file));
+  SystemCall(ReplaceSubString("%s", file, prog));
 }
 
 static void solver_choose_mesh_cb(Fl_Widget *w, void *data)