Index: XmlTools2/trunk/util.cpp
===================================================================
--- XmlTools2/trunk/util.cpp	(revision 973)
+++ XmlTools2/trunk/util.cpp	(revision 980)
@@ -8,5 +8,5 @@
 QString AppExecutable="./"+AppName; // Mac OS needs unix like executing
 #endif
-QString AppVersion="2.0a";
+QString AppVersion="2.0b";
 }
 
Index: XmlTools2/trunk/xmlcustomcode.cpp
===================================================================
--- XmlTools2/trunk/xmlcustomcode.cpp	(revision 973)
+++ XmlTools2/trunk/xmlcustomcode.cpp	(revision 980)
@@ -1,9 +1,5 @@
 #include "xmlcustomcode.h"
 
-// http://stackoverflow.com/questions/7092765/what-does-it-mean-to-have-an-undefined-reference-to-a-static-member
-QVector<QScriptEngine*> XmlCustomCode::scriptEngines;
-QVector<QScriptValue*> XmlCustomCode::jsFunctions;
-QVector<QScriptValue*> XmlCustomCode::getXmlDataFunctions;
-QVector<QScriptValue*> XmlCustomCode::setXmlDataFunctions;
+XmlCustomCode* XmlCustomCode::uniqueInstance = NULL;
 
 QScriptValue echo(QScriptContext *context, QScriptEngine*)
@@ -16,36 +12,43 @@
 XmlCustomCode::XmlCustomCode(): numThreads(omp_get_num_procs()*2)
 {
-    // create individual thread script engines if empty
-    if(this->scriptEngines.isEmpty()){
-        this->scriptEngines.reserve(this->numThreads);
-        this->jsFunctions.reserve(this->numThreads);
-        this->getXmlDataFunctions.reserve(this->numThreads);
-        this->setXmlDataFunctions.reserve(this->numThreads);
+    // create individual thread script engines
+    this->scriptEngines.reserve(this->numThreads);
+    this->jsFunctions.reserve(this->numThreads);
+    this->getXmlDataFunctions.reserve(this->numThreads);
+    this->setXmlDataFunctions.reserve(this->numThreads);
 
-        QString jsxmlString;
-        QFile jsxmlfile(":/resources/libs/jsxml.js");
+    QString jsxmlString;
+    QFile jsxmlfile(":/resources/libs/jsxml.js");
 
-        jsxmlfile.open(QFile::ReadOnly | QFile::Text);
+    jsxmlfile.open(QFile::ReadOnly | QFile::Text);
 
-        jsxmlString=QTextStream(&jsxmlfile).readAll();
+    jsxmlString=QTextStream(&jsxmlfile).readAll();
 
-        for(int i=0; i<this->numThreads; i++){
-            this->scriptEngines.append(new QScriptEngine());
-            this->jsFunctions.append(new QScriptValue());
+    for(int i=0; i<this->numThreads; i++){
+        this->scriptEngines.append(new QScriptEngine());
+        this->jsFunctions.append(new QScriptValue());
 
-            // main needs to be called so the user code is evaluated
-            // alternatively you can do: myFunc=engine.evaluate('(function main(){})'); myFunc.call();
-            // Note the () around the function
-            this->getXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function getXmlData() { return $xmlData; })")));
-            this->setXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function setXmlData(newXmlData) { $xmlData=newXmlData; })")));
+        // main needs to be called so the user code is evaluated
+        // alternatively you can do: myFunc=engine.evaluate('(function main(){})'); myFunc.call();
+        // Note the () around the function
+        this->getXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function getXmlData() { return $xmlData; })")));
+        this->setXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function setXmlData(newXmlData) { $xmlData=newXmlData; })")));
 
-            // Add echo function so user can debug the code
-            QScriptValue echoFunction = this->scriptEngines.at(i)->newFunction(echo);
-            this->scriptEngines.at(i)->globalObject().setProperty("echo", echoFunction);
+        // Add echo function so user can debug the code
+        QScriptValue echoFunction = this->scriptEngines.at(i)->newFunction(echo);
+        this->scriptEngines.at(i)->globalObject().setProperty("echo", echoFunction);
 
-            // Add the js library for XmlEditing
-            this->scriptEngines.at(i)->evaluate(jsxmlString);
-        }
+        // Add the js library for XmlEditing
+        this->scriptEngines.at(i)->evaluate(jsxmlString);
     }
+}
+
+XmlCustomCode* XmlCustomCode::getInstance(){
+
+    if (uniqueInstance==NULL){   // allow only one instance
+        uniqueInstance = new XmlCustomCode();
+    }
+
+    return uniqueInstance;
 }
 
@@ -69,5 +72,5 @@
 
             customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
-                    *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
+                                *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
         }
     }
@@ -99,5 +102,5 @@
 
                 customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
-                        *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
+                                    *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
             }
         }
Index: XmlTools2/trunk/xmlcustomcode.h
===================================================================
--- XmlTools2/trunk/xmlcustomcode.h	(revision 973)
+++ XmlTools2/trunk/xmlcustomcode.h	(revision 980)
@@ -13,15 +13,22 @@
 #define CUSTOM_FILES_PER_THREAD 2
 
+// Uses a singleton implementation (based on here: http://www.yolinux.com/TUTORIALS/C++Singleton.html)
+// which allows each thread to keep one script engine without always create/destruct them
 class XmlCustomCode
 {
 public:
-    XmlCustomCode();
+    static XmlCustomCode* getInstance();
     void executeCustomCode(const QString &jsString, const QVector<QString> &filesToProcess, const bool backupsEnabled, const bool verboseEnabled);
 private:
+    static XmlCustomCode* uniqueInstance;
     const int numThreads;
-    static QVector<QScriptEngine*> scriptEngines; // allows each thread to keep one script engine without always create/destruct them
-    static QVector<QScriptValue*> jsFunctions;
-    static QVector<QScriptValue*> getXmlDataFunctions;
-    static QVector<QScriptValue*> setXmlDataFunctions;
+    QVector<QScriptEngine*> scriptEngines;
+    QVector<QScriptValue*> jsFunctions;
+    QVector<QScriptValue*> getXmlDataFunctions;
+    QVector<QScriptValue*> setXmlDataFunctions;
+
+    XmlCustomCode(); // constructor is private (use getInstance)
+    XmlCustomCode(XmlCustomCode const&);             // copy constructor is private
+    XmlCustomCode& operator=(XmlCustomCode const&);  // assignment operator is private
 
     void displayJsException(QScriptEngine &engine, QScriptValue &engineResult);
Index: XmlTools2/trunk/xmlpatch.cpp
===================================================================
--- XmlTools2/trunk/xmlpatch.cpp	(revision 973)
+++ XmlTools2/trunk/xmlpatch.cpp	(revision 980)
@@ -220,5 +220,5 @@
     }
 
-    this->customCodeOperation.executeCustomCode(jsString,filesToProcess,this->backupsEnabled,this->verboseEnabled);
+    XmlCustomCode::getInstance()->executeCustomCode(jsString,filesToProcess,this->backupsEnabled,this->verboseEnabled);
 
 
Index: XmlTools2/trunk/xmlpatch.h
===================================================================
--- XmlTools2/trunk/xmlpatch.h	(revision 973)
+++ XmlTools2/trunk/xmlpatch.h	(revision 980)
@@ -17,5 +17,5 @@
     pugi::xml_node rootNode;
     bool backupsEnabled, verboseEnabled;
-    XmlCustomCode customCodeOperation;
+    XmlCustomCode *customCodeOperation;
     QString getPatchParameterValue(const QString& line, QString parameter);
     void insertNodesOperation(const QString &xmlString, XmlFilter &filters, const QString &xPathExpression, const QString &filesWildcard="");
