From bf91858cd5838cfb6f1e04c36a58619f840014e8 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 20 Feb 2015 14:37:18 +0100
Subject: [PATCH 001/200] jsroot: implement raw Text output from THttpServer

1. One could create now 'Text' item on the server side,
   which just disaplyed in the browser.
2. For text display MathJax can be used - one should
   specify 'mathjax' property for Text item.
3. Provide example with Text in httpcontrol.C macro
4. Support 'autozoom' draw option
5. Support _same_ identifier in items list
6. Remove default-ui class from droppable, hide nasty
   effects in StreamerInfo and Text display

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/scripts/JSRootCore.js      |  65 ++++++++------
 etc/http/scripts/JSRootInterface.js |  35 ++++----
 etc/http/scripts/JSRootPainter.js   | 126 ++++++++++++++++++++++++----
 etc/http/style/JSRootPainter.css    |   9 +-
 tutorials/http/httpcontrol.C        |  25 +++---
 5 files changed, 189 insertions(+), 71 deletions(-)

diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index f67eeb4e63739..d0f01e031ca8e 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,7 +14,7 @@
 
    JSROOT = {};
 
-   JSROOT.version = "3.3 dev 18/02/2015";
+   JSROOT.version = "3.3 dev 20/02/2015";
 
    JSROOT.source_dir = "";
 
@@ -153,6 +153,35 @@
       return dflt;
    }
 
+   JSROOT.ParseAsArray = function(val) {
+      // parse string value as array.
+      // It could be just simple string:  "value"
+      //  or array with or without string quotes:  [element], ['eleme1',elem2]
+
+      var res = [];
+
+      if (typeof val != 'string') return res;
+
+      val = val.trim();
+      if (val=="") return res;
+
+      // return as array with single element
+      if ((val.length<2) || (val[0]!='[') || (val[val.length-1]!=']')) {
+         res.push(val); return res;
+      }
+
+      // try to parse ourself
+      var arr = val.substr(1, val.length-2).split(","); // remove brackets
+
+      for (var i in arr) {
+         var sub = arr[i].trim();
+         if ((sub.length>1) && (sub[0]==sub[sub.length-1]) && ((sub[0]=='"') || (sub[0]=="'")))
+            sub = sub.substr(1, sub.length-2);
+         res.push(sub);
+      }
+      return res;
+   }
+
    JSROOT.GetUrlOptionAsArray = function(opt, url) {
       // special handling of URL options to produce array
       // if normal option is specified ...?opt=abc, than array with single element will be created
@@ -169,24 +198,7 @@
          if (separ>0) opt = opt.substr(separ+1); else opt = "";
 
          var val = this.GetUrlOption(part, url, null);
-         if (val==null) continue;
-         val = val.trim();
-         if (val=="") continue;
-
-         // return as array with single element
-         if ((val[0]!='[') && (val[val.length-1]!=']')) {
-            res.push(val); continue;
-         }
-
-         // try to parse ourself
-         var arr = val.substr(1, val.length-2).split(","); // remove brackets
-
-         for (var i in arr) {
-            var sub = arr[i].trim();
-            if ((sub.length>1) && (sub[0]==sub[sub.length-1]) && ((sub[0]=='"') || (sub[0]=="'")))
-               sub = sub.substr(1, sub.length-2);
-            res.push(sub);
-         }
+         res = res.concat(JSROOT.ParseAsArray(val));
       }
       return res;
    }
@@ -208,10 +220,12 @@
 
       if (func==null) return;
 
-      if (typeof func=='function') return func(arg1,arg2);
+      if (typeof func == 'string') func = JSROOT.findFunction(func);
+
+      if (typeof func == 'function') return func(arg1,arg2);
 
-      if (typeof func=='obj' && typeof func.obj == 'object' &&
-         typeof func.fun == 'string' && typeof func.obj[func.func] == 'function') return func.obj[func.func](arg1, arg2);
+      if (typeof func == 'object' && typeof func.obj == 'object' &&
+         typeof func.func == 'string' && typeof func.obj[func.func] == 'function') return func.obj[func.func](arg1, arg2);
    }
 
    JSROOT.NewHttpRequest = function(url, kind, user_call_back) {
@@ -349,9 +363,7 @@
          if (debugout)
             document.getElementById(debugout).innerHTML = "";
 
-         if (typeof callback == 'string') callback = JSROOT.findFunction(callback);
-
-         if (typeof callback == 'function') callback();
+         JSROOT.CallBack(callback);
       }
 
       if ((urllist==null) || (urllist.length==0))
@@ -475,6 +487,9 @@
                      ";$$$scripts/helvetiker_bold.typeface.js" +
                      ";$$$scripts/JSRoot3DPainter.js";
 
+      if (kind.indexOf("mathjax;")>=0)
+         allfiles += ";https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+
       if (kind.indexOf("simple;")>=0)
          allfiles += ';$$$scripts/JSRootInterface.js' +
                      ';$$$style/JSRootInterface.css';
diff --git a/etc/http/scripts/JSRootInterface.js b/etc/http/scripts/JSRootInterface.js
index 63bfdb8a0aef7..f041f5434d84d 100644
--- a/etc/http/scripts/JSRootInterface.js
+++ b/etc/http/scripts/JSRootInterface.js
@@ -31,7 +31,6 @@ function setGuiLayout(value) {
    }
 }
 
-
 function ReadFile() {
    var navigator_version = navigator.appVersion;
    if (typeof ActiveXObject == "function") { // Windows
@@ -155,8 +154,9 @@ function BuildSimpleGUI() {
 
    var monitor = JSROOT.GetUrlOption("monitoring");
 
-   var layout = JSROOT.GetUrlOption("layout");
-   if (layout=="") layout = null;
+   var ilayout = JSROOT.GetUrlOption("layout");
+   if (ilayout=="") ilayout = null;
+   var layout = ilayout;
 
    hpainter = new JSROOT.HierarchyPainter('root', nobrowser ? null : 'browser');
 
@@ -183,14 +183,14 @@ function BuildSimpleGUI() {
 
    hpainter.SetDisplay(layout, drawDivId);
 
-   hpainter.EnableMonitoring(monitor!=null);
+   hpainter.SetMonitoring(monitor);
 
    var h0 = null;
 
    if (online) {
       if (!nobrowser)
          $("#monitoring")
-          .prop('checked', monitor!=null)
+          .prop('checked', hpainter.IsMonitoring())
           .click(function() {
              hpainter.EnableMonitoring(this.checked);
              if (this.checked) hpainter.updateAll();
@@ -212,23 +212,24 @@ function BuildSimpleGUI() {
 
    function AfterOnlineOpened() {
       // check if server enables monitoring
-      if ('_monitoring' in hpainter.h) {
-         var v = parseInt(hpainter.h._monitoring);
-         if ((v == NaN) || (hpainter.h._monitoring == 'false')) {
-            hpainter.EnableMonitoring(false);
-         } else {
-            hpainter.EnableMonitoring(true);
-            hpainter.MonitoringInterval(v);
-         }
+      if (('_monitoring' in hpainter.h) && (monitor==null)) {
+         hpainter.SetMonitoring(hpainter.h._monitoring);
          if (!nobrowser) $("#monitoring").prop('checked', hpainter.IsMonitoring());
       }
 
-      if ('_loadfile' in hpainter.h)
-         filesarr.push(hpainter.h._loadfile);
+      if (('_layout' in hpainter.h) && (ilayout==null)) {
+         setGuiLayout(hpainter.h._layout);
+         hpainter.SetDisplay(hpainter.h._layout, drawDivId);
+      }
+
+      if ('_loadfile' in hpainter.h) {
+         filesarr = filesarr.concat(JSROOT.ParseAsArray(hpainter.h._loadfile));
+      }
 
       if ('_drawitem' in hpainter.h) {
-         itemsarr.push(hpainter.h._drawitem);
-         optionsarr.push('_drawopt' in hpainter.h ? hpainter.h._drawopt : "");
+         itemsarr = itemsarr.concat(JSROOT.ParseAsArray(hpainter.h._drawitem));
+         if ('_drawopt' in hpainter.h)
+            optionsarr = optionsarr.concat(JSROOT.ParseAsArray(hpainter.h._drawopt));
       }
 
       OpenAllFiles();
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index 780251e75272f..cb60093e0b412 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -3074,7 +3074,7 @@
          Lego: 0, Surf: 0, Off: 0, Tri: 0, Proj: 0, AxisPos: 0,
          Spec: 0, Pie: 0, List: 0, Zscale: 0, FrontBox: 1, BackBox: 1,
          System: JSROOT.Painter.Coord.kCARTESIAN,
-         AutoColor : 0, NoStat : 0,
+         AutoColor : 0, NoStat : 0, AutoZoom : false,
          HighRes: 0, Zero: 0, Logx: 0, Logy: 0, Logz: 0, Gridx: 0, Gridy: 0
       };
       // check for graphical cuts
@@ -3089,6 +3089,11 @@
          option.Hist = 1;
          chopt = chopt.replace('AUTOCOL', '');
       }
+      if (chopt.indexOf('AUTOZOOM') != -1) {
+         option.AutoZoom = 1;
+         option.Hist = 1;
+         chopt = chopt.replace('AUTOZOOM', '');
+      }
       if (chopt.indexOf('NOSTAT') != -1) {
          option.NoStat = 1;
          chopt = chopt.replace('NOSTAT', '');
@@ -5272,6 +5277,8 @@
 
       painter.AddInteractive();
 
+      if (painter.options.AutoZoom) painter.AutoZoom();
+
       return painter;
    }
 
@@ -5957,6 +5964,8 @@
 
       this.AddInteractive();
 
+      if (this.options.AutoZoom) this.AutoZoom();
+
       this['done2d'] = true; // indicate that 2d drawing was once done
    }
 
@@ -6723,8 +6732,64 @@
       return painter;
    }
 
-   // ===========================================================
+   // ================= painer of raw text ========================================
+
+   JSROOT.RawTextPainter = function(txt) {
+      JSROOT.TBasePainter.call(this);
+      this.txt = txt;
+      return this;
+   }
+
+   JSROOT.RawTextPainter.prototype = Object.create( JSROOT.TBasePainter.prototype );
+
+   JSROOT.RawTextPainter.prototype.RedrawObject = function(obj) {
+      this.txt = obj;
+      this.Draw();
+      return true;
+   }
+
+   JSROOT.RawTextPainter.prototype.Draw = function() {
+      var frame = $("#" + this.divid);
+
+      var txt = this.txt.value;
+      if (txt==null) txt = "<undefined>";
 
+      var mathjax = 'mathjax' in this.txt;
+
+      if (!mathjax && !('as_is' in this.txt)) {
+         var arr = [];
+         while (txt.length > 0) {
+            var pos = txt.indexOf("\\n");
+            if (pos<0) break;
+            arr.push(txt.substr(0,pos));
+            txt = txt.substr(pos+2);
+         }
+         arr.push(txt); txt = "";
+         for (var i in arr)
+            txt += "<pre>" + arr[i] + "</pre>";
+      }
+
+      frame.html("<div style='overflow:hidden'>" + txt + "</div>");
+
+      // (re) set painter to first child element
+      this.SetDivId(this.divid);
+
+      if (mathjax)
+         JSROOT.AssertPrerequisites('mathjax', function() {
+            if (typeof MathJax == 'object') {
+               MathJax.Hub.Queue(["Typeset", MathJax.Hub, frame.get()]);
+            }
+         });
+   }
+
+   JSROOT.Painter.drawRawText = function(divid, txt, opt) {
+      var painter = new JSROOT.RawTextPainter(txt);
+      painter.SetDivId(divid);
+      painter.Draw();
+      return painter;
+   }
+
+   // ========== performs tree drawing on server ==================
 
    JSROOT.TTreePlayer = function(itemname) {
       JSROOT.TBasePainter.call(this);
@@ -7184,6 +7249,10 @@
          cando.ctxt = true;
          cando.execute = true;
          cando.img1 = "img_execute";
+      } else if (kind=="Text") {
+         cando.ctxt = true;
+         cando.display = true;
+         cando.img1 = "img_text";
       } else if (kind.match(/^ROOT.TH1/)) {
          cando.img1 = "img_histo1d";
          cando.scan = false;
@@ -7230,6 +7299,11 @@
          cando.img1 = "img_histo1d";
          cando.scan = false;
          cando.display = true;
+      } else
+      if (JSROOT.canDraw('kind:' + kind)) {
+         cando.img1 = "img_leaf";
+         cando.scan = false;
+         cando.display = true;
       }
 
       if ((cando.img1.length==0) && ('_online' in node)) cando.img1 = "img_globe";
@@ -7703,7 +7777,7 @@
                         if (dropname==null) return false;
                         return h.dropitem(dropname, frame.attr("id"));
                      }
-                  });
+                  }).removeClass('ui-state-default');
             }
          }
 
@@ -7788,6 +7862,11 @@
                   dropitems[i][j] = dropitems[i][j].substr(0,pos) + items[i].substr(pos);
             }
          }
+
+         // also check if subsequent items has _same_, than use name from first item
+         var pos = items[i].indexOf("_same_");
+         if ((pos>0) && !this.Find(items[i]) && (i>0))
+            items[i] = items[i].substr(0,pos) + items[0].substr(pos);
       }
 
       // Than create empty frames for each item
@@ -7942,17 +8021,22 @@
    JSROOT.HierarchyPainter.prototype.GetOnlineItem = function(item, itemname, callback) {
       // method used to request object from the http server
 
-      var url = itemname, h_get = false;
+      var url = itemname, h_get = false, req = 'root.json.gz?compact=3';
 
       if (item != null) {
          var top = item;
          while ((top!=null) && (!('_online' in top))) top = top._parent;
          url = this.itemFullName(item, top);
-         h_get = ('_doing_expand' in item);
+         if ('_doing_expand' in item) {
+            h_get = true;
+            req  = 'h.json?compact=3';
+         } else
+         if (item._kind.indexOf("ROOT.")!=0)
+            req = 'get.json?compact=3';
       }
 
       if (url.length > 0) url += "/";
-      url += h_get ? 'h.json?compact=3' : 'root.json.gz?compact=3';
+      url += req;
 
       var itemreq = JSROOT.NewHttpRequest(url, 'object', function(obj) {
 
@@ -8082,18 +8166,21 @@
       this.RefreshHtml();
    }
 
+   JSROOT.HierarchyPainter.prototype.SetMonitoring = function(val) {
+      this['_monitoring_on'] = false;
+      this['_monitoring_interval'] = 3000;
+
+      if ((val!=null) && (val!='0')) {
+         this['_monitoring_on'] = true;
+         this['_monitoring_interval'] = parseInt(val);
+         if ((this['_monitoring_interval'] == NaN) || (this['_monitoring_interval']<100))
+            this['_monitoring_interval'] = 3000;
+      }
+   }
+
    JSROOT.HierarchyPainter.prototype.MonitoringInterval = function(val) {
       // returns interval
-      if (val!=null) this['_monitoring_interval'] = val;
-      var monitor = this['_monitoring_interval'];
-      if (monitor == null) {
-         monitor = JSROOT.GetUrlOption("monitoring");
-         if ((monitor == "") || (monitor==null)) monitor = 3000;
-                                            else monitor = parseInt(monitor);
-         if ((monitor == NaN) || (monitor<=0)) monitor = 3000;
-         this['_monitoring_interval'] = monitor;
-      }
-      return monitor;
+      return ('_monitoring_interval' in this) ? this['_monitoring_interval'] : 3000;
    }
 
    JSROOT.HierarchyPainter.prototype.EnableMonitoring = function(on) {
@@ -8729,6 +8816,7 @@
    JSROOT.addDrawFunc(/^RooCurve/, JSROOT.Painter.drawGraph,";L;P");
    JSROOT.addDrawFunc("TMultiGraph", JSROOT.Painter.drawMultiGraph);
    JSROOT.addDrawFunc("TStreamerInfoList", JSROOT.Painter.drawStreamerInfo);
+   JSROOT.addDrawFunc("kind:Text", JSROOT.Painter.drawRawText);
 
    JSROOT.getDrawFunc = function(classname, drawopt) {
       if (typeof classname != 'string') return null;
@@ -8796,9 +8884,11 @@
     * Draw object in specified HTML element with given draw options  */
 
    JSROOT.draw = function(divid, obj, opt) {
-      if ((typeof obj != 'object') || (!('_typename' in obj))) return null;
+      if (typeof obj != 'object') return null;
 
-      var draw_func = JSROOT.getDrawFunc(obj['_typename'], opt);
+      var draw_func = null;
+      if ('_typename' in obj) draw_func = JSROOT.getDrawFunc(obj['_typename'], opt);
+      else if ('_kind' in obj) draw_func = JSROOT.getDrawFunc('kind:' + obj['_kind'], opt);
 
       if (draw_func==null) return null;
 
diff --git a/etc/http/style/JSRootPainter.css b/etc/http/style/JSRootPainter.css
index 8523ecbb44d2c..ce51d84dddc2d 100644
--- a/etc/http/style/JSRootPainter.css
+++ b/etc/http/style/JSRootPainter.css
@@ -1,5 +1,5 @@
 /* Interface stylesheet for Javascript ROOT Web Page. */
-
+ 
 /*--------------------------------------------------|
 | dTree 2.05 | www.destroydrop.com/javascript/tree/ |
 |---------------------------------------------------|
@@ -223,6 +223,13 @@
     background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAA2klEQVRIx61VURbDIAgTX+9ljg4n2z5sNouj1ml+LE9rQkSU5PA6kTZBToTznj5aqKqq+py4lFJKScnMzCwlAAB6IbnNuyXycd1g3oHrf32CmR9mZqpVOdDHs2DmI+c+AiJixu1RAN9xFUcdWCjVIr8xCX8Jubc8Ao9CJF8nRFgNJBxZSCEkjmrIxxSS0yIAoBU4OkpfU8sCPEbEvqaOXcR31zWORbYJ8EI8rsK+DWm7gMVb8F/GK7eg6818jNjJZjMn0agY7x6oxqL5sWbIbhLHoQN78PQ5F3kDgX8u9tphBfoAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDItMDZUMTA6Mjc6MzErMDE6MDChLu/mAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE0LTExLTEyVDA4OjM5OjIwKzAxOjAwIGvf8wAAAABJRU5ErkJggg==');
 }
 
+.img_text {
+    display: inline-block;
+    height: 18px;
+    width: 18px;
+    background-image: url('data:image/gif;base64,R0lGODlhEgASALMAAP/////MzP+Zmf9mZv8zM/8AAMzM/8zMzJmZ/5mZmWZm/2ZmZjMz/zMzMwAA/////yH5BAUUAA8ALAAAAAASABIAAARo8MlJq73SKGSwdSDjUQoIjhNYOujDnGAnFXRBZKoBIpMw1ICHaaigBAq/AUK1CVEIhcfPNFlRbAEBEvWr0VDYQLYgkCQWh8XiAfgRymPyoTFRa2uPO009maP8ZmsjAHxnBygLDQ1zihEAOw==');
+}
+
 
 /*--------------------------------------------------|
 | tooltip style                                     |
diff --git a/tutorials/http/httpcontrol.C b/tutorials/http/httpcontrol.C
index 4513b0d3d43a7..36943105f81d3 100644
--- a/tutorials/http/httpcontrol.C
+++ b/tutorials/http/httpcontrol.C
@@ -16,7 +16,7 @@ void httpcontrol()
 //  After macro started, open in browser with url
 //      http://localhost:8080
 //
-//  Histogram hpxpy will be automatically displayed and
+//  Histograms will be automatically displayed and
 //  monitoring with interval 2000 ms started
 
    // create histograms
@@ -38,9 +38,10 @@ void httpcontrol()
    serv->Register("/", hpxpy);
 
    // enable monitoring and
-   // specify item to draw when page is opened
+   // specify items to draw when page is opened
    serv->SetItemField("/","_monitoring","2000");
-   serv->SetItemField("/","_drawitem","hpxpy");
+   serv->SetItemField("/","_layout","grid2x2");
+   serv->SetItemField("/","_drawitem","[hpxpy,hpx,Debug]");
    serv->SetItemField("/","_drawopt","col");
 
    // register simple start/stop commands
@@ -52,14 +53,15 @@ void httpcontrol()
    serv->Hide("/Stop");
 
    // register commands, invoking object methods
-   // one could set command properties directly
-   serv->RegisterCommand("/ResetHPX","/hpx/->Reset()");
-   serv->SetIcon("/ResetHPX", "/rootsys/icons/ed_delete.png");
-   serv->SetItemField("/ResetHPX","_fastcmd", "true");
+   serv->RegisterCommand("/ResetHPX","/hpx/->Reset()", "button;/rootsys/icons/ed_delete.png");
+   serv->RegisterCommand("/ResetHPXPY","/hpxpy/->Reset()", "button;/rootsys/icons/bld_delete.png");
 
-   serv->RegisterCommand("/ResetHPXPY","/hpxpy/->Reset()");
-   serv->SetIcon("/ResetHPXPY", "/rootsys/icons/bld_delete.png");
-   serv->SetItemField("/ResetHPXPY", "_fastcmd", "true");
+
+   // create debug text element, use MathJax - works only on Firefox
+   serv->CreateItem("/Debug","debug output");
+   serv->SetItemField("/Debug", "_kind", "Text");
+   serv->SetItemField("/Debug", "value","\\(\\displaystyle{x+1\\over y-1}\\)");
+   serv->SetItemField("/Debug", "mathjax", "true");
 
    // Fill histograms randomly
    TRandom3 random;
@@ -79,6 +81,9 @@ void httpcontrol()
       if ((cnt % kUPDATE==0) || !bFillHist) {
          // IMPORTANT: one should regularly call ProcessEvents
          // to let http server process requests
+
+         serv->SetItemField("/Debug", "value", Form("\\(\\displaystyle{x+1\\over y-1}\\) Loop:%d", cnt/kUPDATE));
+
          if (gSystem->ProcessEvents()) break;
       }
    }

From cb20a75b328d9d9566953a6aa1410595a611a99e Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 20 Feb 2015 14:38:11 +0100
Subject: [PATCH 002/200] json: correctly process escape characters in the JSON
 string

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 net/http/src/TRootSnifferStore.cxx | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/net/http/src/TRootSnifferStore.cxx b/net/http/src/TRootSnifferStore.cxx
index 2dd5f13369b13..c3b9c97424979 100644
--- a/net/http/src/TRootSnifferStore.cxx
+++ b/net/http/src/TRootSnifferStore.cxx
@@ -144,10 +144,25 @@ void TRootSnifferStoreJson::SetField(Int_t lvl, const char *field,
    fBuf->Append(",");
    if (!fCompact) fBuf->Append("\n");
    fBuf->Append(TString::Format("%*s\"%s\"%s", fCompact ? 0 : lvl * 4 + 2, "", field, (fCompact ? ":" : " : ")));
-   if (with_quotes) {
-      fBuf->Append(TString::Format("\"%s\"", value));
-   } else {
+   if (!with_quotes) {
       fBuf->Append(value);
+   } else {
+      fBuf->Append("\"");
+      for (const char *v = value; *v != 0; v++) {
+         switch (*v) {
+            case '\n':
+               fBuf->Append("\\\\n");
+               break;
+            case '\t':
+               fBuf->Append("\\\\t");
+               break;
+            default:
+               fBuf->Append(*v);
+               // double escape character, only keep \' and \" sequences untouched
+               if ((*v == '\\') && (*(v+1) != '\'') && (*(v+1) != '\"')) fBuf->Append("\\");
+         }
+      }
+      fBuf->Append("\"");
    }
 }
 

From 53f1465a4e0f77464474df478e89c1564871e2de Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 20 Feb 2015 14:39:22 +0100
Subject: [PATCH 003/200] jsroot: provide JSROOT changelog in md format

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/{changes.txt => changes.md} | 170 ++++++++++++++-------------
 1 file changed, 86 insertions(+), 84 deletions(-)
 rename etc/http/{changes.txt => changes.md} (55%)

diff --git a/etc/http/changes.txt b/etc/http/changes.md
similarity index 55%
rename from etc/http/changes.txt
rename to etc/http/changes.md
index 30fa30c30edd8..a4632659e4b9a 100644
--- a/etc/http/changes.txt
+++ b/etc/http/changes.md
@@ -1,9 +1,9 @@
-JSROOT project
+# JSROOT changelog {#jsroot_changes}
 
 This is further development of JSRootIO project of Bertrand Bellenot. 
 Many old problems and errors are fixed, new functions are provided.  
 
-Changes in 3.3
+## Changes in v 3.3
 1. Use d3.time.scale for display of time scales
 2. Within JSRootCore.js script URL one could specify JSROOT
    functionality to be loaded: '2d', '3d', 'io', 'load', 'onload'.
@@ -17,13 +17,20 @@ Changes in 3.3
 8. Implement 'autocol' draw option  - when superimposing histograms,
    their line colors will be automatically assigned
 9. Implement 'nostat' draw option - disabled stat drawing
-10.Using '_same_' identifier in item name, one can easily superimpose
-   same items from different files. Could be used in URL like:
-      &files=[file1.root,file2.root]&item=file1.root/hpx+file2.root/_same_
-   Main limitation - file names should have similar length.   
-
-
-Changes in 3.2
+10. Using '_same_' identifier in item name, one can easily draw or superimpose
+    similar items from different files. Could be used in URL like:
+      `...&files=[file1.root,file2.root]&items=[file1.root/hpx, file2.root/_same_]`
+      `...&files=[file1.root,file2.root]&item=file1.root/hpx+file2.root/_same_`
+    Main limitation - file names should have similar length.   
+11. When 'autozoom' specified in draw options, histogram zoomed into
+    non-empty content. Same command available via context menu. 
+12. Item of 'Text' kind can be created. It is displayed as 
+    plain text in the browser. If property 'mathjax' specified,
+    MathJax.js library will be loaded and used for rendering.
+    See httpcontrol.C macro for example.
+   
+
+## Changes in 3.2
 1. Support JSON objects embedding in html pages, produced by THttpServer
 2. For small resize of canvas use autoscale functionality of SVG. Only when
    relative changes too large, redraw complete canvas again.
@@ -36,7 +43,7 @@ Changes in 3.2
 8. 3D graphic (three.js) works only with IE11
 
 
-Changes in 3.1
+## Changes in 3.1
 1. Correctly show tooltips in case of overlapped objects
 2. Implement JSROOT.Create() method to create supported
    in JavaScript ROOT classes like TH1 or TGraph
@@ -49,12 +56,12 @@ Changes in 3.1
 8. Implement dragging objects from hierarchy browser into existing canvas 
    to superimpose several objects 
 9. Implement col2 and col3 draw options, using html5 canvas
-10.Support 'p' and 'p0' draw options for TH1 class
+10. Support 'p' and 'p0' draw options for TH1 class
 
 
-Development of version 3.0
+## Development of version 3.0
 
-November 2014:
+### November 2014
 1. Better font size and position in pave stats
 2. Resize/move of element only inside correspondent pad
 3. Adjust of frame size when Y-axis exceed pad limits
@@ -63,33 +70,32 @@ November 2014:
 6. Drawing of canvas without TFrame object
 7. Many other small bug fixes and improvements, thanks to Maximilian Dietrich
 
-October 2014:
-1. Add "shortcut icon"
-2. Add demo of online THttpServer - shell script copies data from
-   running httpserver.C macro on Apache webserver
-3. Evaluate 'monitoring' parameter for online server like:
-      http://localhost:8080/?monitoring=1000.
-   Parameter defines how often displayed objects should be updated.
-4. Implement 'opt' and 'opts' URL parameters for main page.
-5. Show progress with scripts loading in the browser window
-6. When one appends "+" to the filename, its content read completely with first I/O operation.
-7. Implement JS custom streamer for TCanvas, restore aspect ratio when drawing
-8. Major redesign of drawing classes. Resize and update of TCanvas are implemented.
-   All major draw functions working with HTML element id as first argument.
-9. Extract 3D drawings into separate JSRoot3DPainter.js script
-10.Use newest three.min.js (r68) for 3D drawings, solves problem with Firefox.
-11.Introduce generic list of draw functions for all supported classes.
-12.Add possibility to 'expand' normal objects in the hierarchy browser.
-   For instance, this gives access to single elements of canvas,
-   when whole canvas cannot be drawn.
-13.Correct usage of colors map, provided with TCanvas.
-14.Introduce JSROOT.redraw() function which is capable to create or update object drawing.
-15.In main index.htm page browser can be disabled (nobrowser parameter) and
-   page can be used to display only specified items from the file
-16.Add support of TPolyMarker3D in binary I/O
-
-
-September 2014:
+### October 2014
+1.  Add "shortcut icon"
+2.  Add demo of online THttpServer - shell script copies data from
+    running httpserver.C macro on Apache webserver
+3.  Evaluate 'monitoring' parameter for online server like:
+      <http://localhost:8080/?monitoring=1000>
+    Parameter defines how often displayed objects should be updated.
+4.  Implement 'opt' and 'opts' URL parameters for main page.
+5.  Show progress with scripts loading in the browser window
+6.  When one appends "+" to the filename, its content read completely with first I/O operation.
+7.  Implement JS custom streamer for TCanvas, restore aspect ratio when drawing
+8.  Major redesign of drawing classes. Resize and update of TCanvas are implemented.
+    All major draw functions working with HTML element id as first argument.
+9.  Extract 3D drawings into separate JSRoot3DPainter.js script
+10. Use newest three.min.js (r68) for 3D drawings, solves problem with Firefox.
+11. Introduce generic list of draw functions for all supported classes.
+12. Add possibility to 'expand' normal objects in the hierarchy browser.
+    For instance, this gives access to single elements of canvas,
+    when whole canvas cannot be drawn.
+13. Correct usage of colors map, provided with TCanvas.
+14. Introduce JSROOT.redraw() function which is capable to create or update object drawing.
+15. In main index.htm page browser can be disabled (nobrowser parameter) and
+    page can be used to display only specified items from the file
+16. Add support of TPolyMarker3D in binary I/O
+
+### September 2014
 1. First try to handle resize of the browser,
    for the moment works only with collapsible layout
 2. Also first try to interactively move separation line between
@@ -104,22 +110,21 @@ September 2014:
 8. Implement 'grid' display, one could specify any number of devision like
    'grid 3x3' or 'grid 4x2'.
 9. MDI display object created at the moment when first draw is performed.
-10.Introduce painter class for TCanvas, support resize and update of canvas drawing
-11.Resize almost works for all layouts and all objects kinds.
-12.Implement JSROOT.GetUrlOption to extract options from document URL.
-13.Provide example fileitem.htm how read and display item from ROOT file.
-14.In default index.htm page one could specify 'file', 'layout',
-   'item' and 'items' parameters like:
-      http://root.cern.ch/js/3.0/index.htm?file=files/hsimple.root&layout=grid5x5&item=hpx;1
-15.Support direct reading of objects from sub-sub-directories.
-16.Introduce demo.htm, which demonstrates online usage of JSROOT.
-17.One could use demo.htm directly with THttpServer providing address like:
-     http://localhost:8080/jsrootsys/demo/demo.htm?addr=../../Files/job1.root/hpx/root.json.gz&layout=3x3
-18.Also for online server process url options like 'item', 'items', 'layout'
-19.Possibility to generate URL, which reproduces opened page with layout and drawn items
-
-
-August 2014:
+10. Introduce painter class for TCanvas, support resize and update of canvas drawing
+11. Resize almost works for all layouts and all objects kinds.
+12. Implement JSROOT.GetUrlOption to extract options from document URL.
+13. Provide example fileitem.htm how read and display item from ROOT file.
+14. In default index.htm page one could specify 'file', 'layout',
+    'item' and 'items' parameters like:
+      <http://root.cern.ch/js/3.0/index.htm?file=../files/hsimple.root&layout=grid3x2&item=hpx;1>
+15. Support direct reading of objects from sub-sub-directories.
+16. Introduce demo.htm, which demonstrates online usage of JSROOT.
+17. One could use demo.htm directly with THttpServer providing address like:
+     <http://localhost:8080/jsrootsys/demo/demo.htm?addr=../../Files/job1.root/hpx/root.json.gz&layout=3x3>
+18. Also for online server process url options like 'item', 'items', 'layout'
+19. Possibility to generate URL, which reproduces opened page with layout and drawn items
+
+### August 2014
 1. All communication between server and browser done with JSON format.
 2. Fix small error in dtree.js - one should always set
    last sibling (_ls) property while tree can be dynamically changed.
@@ -137,43 +142,40 @@ August 2014:
 8. In example.htm also use AssertPrerequisites to load necessary scripts.
    This helps to keep code up-to-date even by big changes in JavaScript code.
 9. Provide monitoring of online THttpServer with similar interface as for ROOT files.
-10.Fix several errors in TKey Streamer, use member names as in ROOT itself.
-11.Keep the only version identifier JSROOT.version for JS code
-12.One can specify in JSROOT.AssertPrerequisites functionality which is required.
-   One could specify '2d', 'io' (default) or '3d'.
-13.Use new AssertPrerequisites functionality to load only required functionality.
-14.When displaying single element, one could specify draw options and monitor property like:
-       http://localhost:8080/Files/job1.root/hpxpy/draw.htm?opt=col&monitor=2000
-   Such link is best possibility to integrate display into different HTML pages,
-   using <iframe/> tag like:
-      <iframe src="http://localhost:8080/Files/job1.root/hpx/draw.htm"
-             style="width: 800px; height:600px"></iframe>
-15.Remove 'JSROOTIO.' prefix from _typename. Now real class name is used.
-16.Use in all scripts JSROOT as central 'namespace'
-17.Introduce context menu in 3D, use it for switch between 2D/3D modes
-18.Use own code to generate hierarchical structure in HTML, replace dtree.js which is
-   extremely slow for complex hierarchies. Dramatically improve performance for
-   structures with large (~1000) number of items.
-19.Deliver to the server title of the objects, display it as hint in the browser.
-20.Better handling of special characters in the hierarchies - allows to display
-   symbols like ' or " in the file structure.
-
-
-July 2014:
+10. Fix several errors in TKey Streamer, use member names as in ROOT itself.
+11. Keep the only version identifier JSROOT.version for JS code
+12. One can specify in JSROOT.AssertPrerequisites functionality which is required.
+    One could specify '2d', 'io' (default) or '3d'.
+13. Use new AssertPrerequisites functionality to load only required functionality.
+14. When displaying single element, one could specify draw options and monitor property like:
+        <http://localhost:8080/Files/job1.root/hpxpy/draw.htm?opt=col&monitor=2000>
+     Such link is best possibility to integrate display into different HTML pages,
+     using `<iframe/>` tag like:
+        `<iframe src="http://localhost:8080/Files/job1.root/hpx/draw.htm"` 
+          `style="width: 800px; height:600px"></iframe>`
+15. Remove 'JSROOTIO.' prefix from _typename. Now real class name is used.
+16. Use in all scripts JSROOT as central 'namespace'
+17. Introduce context menu in 3D, use it for switch between 2D/3D modes
+18. Use own code to generate hierarchical structure in HTML, replace dtree.js which is
+    extremely slow for complex hierarchies. Dramatically improve performance for
+    structures with large (~1000) number of items.
+19. Deliver to the server title of the objects, display it as hint in the browser.
+20. Better handling of special characters in the hierarchies - allows to display
+    symbols like ' or " in the file structure.
+
+### July 2014
 1. Migration to d3.v3.js and jQuery v2.1.1
 2. Fix errors in filling of histogram statbox
 3. Possibility of move and resize of statbox, title, color palete
 4. Remove many (not all) global variables
 5. Example with direct usage of JSRootIO graphics
-6. Example of inserting ROOT graphics from THttpServer into <iframe></iframe>
+6. Example of inserting ROOT graphics from THttpServer into `<iframe></iframe>`
 
-
-May 2014:
+### May 2014
 1. This JSRootIO code together with THttpServer class included
    in ROOT repository
 
-
-March 2014:
+### March 2014
 1. Introduce JSROOT.TBuffer class, which plays similar role
    as TBuffer in native ROOT I/O. Simplifies I/O logic,
    reduce duplication of code in many places, fix errors.

From a2c69450173db98d5d2d18eb8abca64d1cc79086 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Fri, 20 Feb 2015 15:36:32 +0100
Subject: [PATCH 004/200] - `\mu` is now working for Postscript output.

---
 graf2d/doc/v604/index.md               | 4 ++++
 graf2d/postscript/src/AdobeGlyphList.h | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/graf2d/doc/v604/index.md b/graf2d/doc/v604/index.md
index 3b4c5268e879d..97367c83d3aab 100644
--- a/graf2d/doc/v604/index.md
+++ b/graf2d/doc/v604/index.md
@@ -58,3 +58,7 @@
   because the `GetTextExtend` method behaved differently in batch mode and "screen"
   mode. This is now fixed. See http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=18883
 - Improve the square-root drawing in case it is small.
+
+### TMathText
+
+- `\mu` is now working for Postscript output.
diff --git a/graf2d/postscript/src/AdobeGlyphList.h b/graf2d/postscript/src/AdobeGlyphList.h
index c05e79fb4499e..8103fb76af242 100644
--- a/graf2d/postscript/src/AdobeGlyphList.h
+++ b/graf2d/postscript/src/AdobeGlyphList.h
@@ -205,7 +205,7 @@ static const char *adobe_glyph_name[nadobe_glyph] = {
    "alphatonos", "epsilontonos", "etatonos", "iotatonos",
    "upsilondieresistonos", "alpha", "beta", "gamma", "delta",
    "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda",
-   "mu", "nu", "xi", "omicron", "pi", "rho", "sigma1", "sigma",
+   "uni03BC", "nu", "xi", "omicron", "pi", "rho", "sigma1", "sigma",
    "tau", "upsilon", "phi", "chi", "psi", "omega", "iotadieresis",
    "upsilondieresis", "omicrontonos", "upsilontonos", "omegatonos",
    "theta1", "Upsilon1", "phi1", "omega1", "afii10023", "afii10051",

From 95e792a3b6f550e879f7076964f1f6f1626a1a41 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Fri, 20 Feb 2015 16:39:12 +0100
Subject: [PATCH 005/200] stressIOPlugins needs libEvent; make it depend on
 Event.exe to express that.

---
 test/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/Makefile b/test/Makefile
index 94713d1472946..729575bf20203 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -574,7 +574,7 @@ $(STRESS):      $(STRESSO) $(EVENT)
 		$(MT_EXE)
 		@echo "$@ done"
 
-$(IOPLUGINS):   $(IOPLUGINSO) $(EVENTO)
+$(IOPLUGINS):   $(IOPLUGINSO) $(EVENT)
 		$(LD) $(LDFLAGS) $(IOPLUGINSO) $(EVENTO) $(LIBS) $(OutPutOpt)$@
 		$(MT_EXE)
 		@echo "$@ done"

From ca41af36d15a5bb24cc8a46ce3f54a75917f366a Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 20 Feb 2015 16:42:53 +0100
Subject: [PATCH 006/200] json: handle all escape characters

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/scripts/JSRootInterface.js | 11 ++--
 etc/http/scripts/JSRootPainter.js   |  9 +---
 net/http/inc/TBufferJSON.h          |  2 +
 net/http/src/TBufferJSON.cxx        | 80 ++++++++++++++++++++---------
 net/http/src/TRootSnifferStore.cxx  | 32 +++++++++---
 5 files changed, 88 insertions(+), 46 deletions(-)

diff --git a/etc/http/scripts/JSRootInterface.js b/etc/http/scripts/JSRootInterface.js
index f041f5434d84d..c94877edbe3c7 100644
--- a/etc/http/scripts/JSRootInterface.js
+++ b/etc/http/scripts/JSRootInterface.js
@@ -222,14 +222,13 @@ function BuildSimpleGUI() {
          hpainter.SetDisplay(hpainter.h._layout, drawDivId);
       }
 
-      if ('_loadfile' in hpainter.h) {
-         filesarr = filesarr.concat(JSROOT.ParseAsArray(hpainter.h._loadfile));
+      if (('_loadfile' in hpainter.h) && (filesarr.length==0)) {
+         filesarr = JSROOT.ParseAsArray(hpainter.h._loadfile);
       }
 
-      if ('_drawitem' in hpainter.h) {
-         itemsarr = itemsarr.concat(JSROOT.ParseAsArray(hpainter.h._drawitem));
-         if ('_drawopt' in hpainter.h)
-            optionsarr = optionsarr.concat(JSROOT.ParseAsArray(hpainter.h._drawopt));
+      if (('_drawitem' in hpainter.h) && (itemsarr.length==0)) {
+         itemsarr = JSROOT.ParseAsArray(hpainter.h._drawitem);
+         optionsarr = JSROOT.ParseAsArray(hpainter.h['_drawopt']);
       }
 
       OpenAllFiles();
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index cb60093e0b412..c4ed30774e914 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -6757,14 +6757,7 @@
       var mathjax = 'mathjax' in this.txt;
 
       if (!mathjax && !('as_is' in this.txt)) {
-         var arr = [];
-         while (txt.length > 0) {
-            var pos = txt.indexOf("\\n");
-            if (pos<0) break;
-            arr.push(txt.substr(0,pos));
-            txt = txt.substr(pos+2);
-         }
-         arr.push(txt); txt = "";
+         var arr = txt.split("\n"); txt = "";
          for (var i in arr)
             txt += "<pre>" + arr[i] + "</pre>";
       }
diff --git a/net/http/inc/TBufferJSON.h b/net/http/inc/TBufferJSON.h
index a0a91f35ce454..4a8e0f2ffa3de 100644
--- a/net/http/inc/TBufferJSON.h
+++ b/net/http/inc/TBufferJSON.h
@@ -440,6 +440,8 @@ class TBufferJSON : public TBuffer {
    void              JsonWriteBasic(ULong_t value);
    void              JsonWriteBasic(ULong64_t value);
 
+   void              JsonWriteConstChar(const char* value, Int_t len = -1);
+
    void              JsonWriteObject(const void *obj, const TClass *objClass, Bool_t check_map = kTRUE);
 
    void              JsonStreamCollection(TCollection *obj, const TClass *objClass);
diff --git a/net/http/src/TBufferJSON.cxx b/net/http/src/TBufferJSON.cxx
index f769873c305ba..374bfc073bab8 100644
--- a/net/http/src/TBufferJSON.cxx
+++ b/net/http/src/TBufferJSON.cxx
@@ -2188,26 +2188,12 @@ void TBufferJSON::WriteFastArray(const Char_t *c, Int_t n)
    // If array does not include any special characters,
    // it will be reproduced as CharStar node with string as attribute
 
-   Bool_t usedefault = fExpectedChain;
-   const Char_t *buf = c;
-   if (!usedefault)
-      for (int i = 0; i < n; i++) {
-         if (*buf < 27) {
-            usedefault = kTRUE;
-            break;
-         }
-         buf++;
-      }
-   if (usedefault) {
-      // TODO - write as array of characters
+   if (fExpectedChain) {
       TBufferJSON_WriteFastArray(c);
    } else {
       TJSONPushValue();
 
-      // special case - not a zero-reminated string
-      fValue.Append("\"");
-      if ((c != 0) && (n > 0)) fValue.Append(c, n);
-      fValue.Append("\"");
+      JsonWriteConstChar(c, n);
    }
 }
 
@@ -2684,9 +2670,7 @@ void TBufferJSON::WriteCharP(const Char_t *c)
 
    TJSONPushValue();
 
-   fValue.Append("\"");
-   fValue.Append(c);
-   fValue.Append("\"");
+   JsonWriteConstChar(c);
 }
 
 //______________________________________________________________________________
@@ -2696,9 +2680,7 @@ void TBufferJSON::WriteTString(const TString &s)
 
    TJSONPushValue();
 
-   fValue.Append("\"");
-   fValue.Append(s);
-   fValue.Append("\"");
+   JsonWriteConstChar(s.Data(), s.Length());
 }
 
 //______________________________________________________________________________
@@ -2708,9 +2690,7 @@ void TBufferJSON::WriteStdString(const std::string &s)
 
    TJSONPushValue();
 
-   fValue.Append("\"");
-   fValue.Append(s);
-   fValue.Append("\"");
+   JsonWriteConstChar(s.c_str(), s.length());
 }
 
 //______________________________________________________________________________
@@ -2841,6 +2821,56 @@ void TBufferJSON::JsonWriteBasic(ULong64_t value)
    fValue.Append(buf);
 }
 
+//______________________________________________________________________________
+void TBufferJSON::JsonWriteConstChar(const char* value, Int_t len)
+{
+   // writes string value, processing all kind of special characters
+
+   fValue.Append("\"");
+
+   if (value!=0) {
+      if (len<0) len = strlen(value);
+
+      for (Int_t n=0;n<len;n++) {
+         char c = value[n];
+         switch(c) {
+            case '\n':
+               fValue.Append("\\n");
+               break;
+            case '\t':
+               fValue.Append("\\t");
+               break;
+            case '\"':
+               fValue.Append("\\\"");
+               break;
+            case '\\':
+               fValue.Append("\\\\");
+               break;
+            case '\b':
+               fValue.Append("\\b");
+               break;
+            case '\f':
+               fValue.Append("\\f");
+               break;
+            case '\r':
+               fValue.Append("\\r");
+               break;
+            case '/':
+               fValue.Append("\\/");
+               break;
+            default:
+               if ((c > 31) && (c < 127))
+                  fValue.Append(c);
+               else
+                  fValue.Append(TString::Format("\\u%04x", (unsigned) c));
+         }
+      }
+   }
+
+   fValue.Append("\"");
+}
+
+
 //______________________________________________________________________________
 void TBufferJSON::SetFloatFormat(const char *fmt)
 {
diff --git a/net/http/src/TRootSnifferStore.cxx b/net/http/src/TRootSnifferStore.cxx
index c3b9c97424979..cbf5ccec8bdb2 100644
--- a/net/http/src/TRootSnifferStore.cxx
+++ b/net/http/src/TRootSnifferStore.cxx
@@ -148,20 +148,38 @@ void TRootSnifferStoreJson::SetField(Int_t lvl, const char *field,
       fBuf->Append(value);
    } else {
       fBuf->Append("\"");
-      for (const char *v = value; *v != 0; v++) {
+      for (const char *v = value; *v != 0; v++)
          switch (*v) {
             case '\n':
-               fBuf->Append("\\\\n");
+               fBuf->Append("\\n");
                break;
             case '\t':
-               fBuf->Append("\\\\t");
+               fBuf->Append("\\t");
+               break;
+            case '\"':
+               fBuf->Append("\\\"");
+               break;
+            case '\\':
+               fBuf->Append("\\\\");
+               break;
+            case '\b':
+               fBuf->Append("\\b");
+               break;
+            case '\f':
+               fBuf->Append("\\f");
+               break;
+            case '\r':
+               fBuf->Append("\\r");
+               break;
+            case '/':
+               fBuf->Append("\\/");
                break;
             default:
-               fBuf->Append(*v);
-               // double escape character, only keep \' and \" sequences untouched
-               if ((*v == '\\') && (*(v+1) != '\'') && (*(v+1) != '\"')) fBuf->Append("\\");
+               if ((*v > 31) && (*v < 127))
+                  fBuf->Append(*v);
+               else
+                  fBuf->Append(TString::Format("\\u%04x", (unsigned) *v));
          }
-      }
       fBuf->Append("\"");
    }
 }

From 98e8a64f9691435abec4d91c6f8c891270bb6768 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 20 Feb 2015 17:26:48 +0100
Subject: [PATCH 007/200] Add TEX option in the Canvas "Save" menu

---
 gui/gui/src/TRootCanvas.cxx | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gui/gui/src/TRootCanvas.cxx b/gui/gui/src/TRootCanvas.cxx
index 06515a9a5bb89..3ecc399260ad4 100644
--- a/gui/gui/src/TRootCanvas.cxx
+++ b/gui/gui/src/TRootCanvas.cxx
@@ -87,6 +87,7 @@ enum ERootCanvasCommands {
    kFileSaveAsGIF,
    kFileSaveAsJPG,
    kFileSaveAsPNG,
+   kFileSaveAsTEX,
    kFilePrint,
    kFileCloseCanvas,
    kFileQuit,
@@ -339,6 +340,7 @@ void TRootCanvas::CreateCanvas(const char *name)
    fFileSaveMenu->AddEntry(Form("%s.&ps",  name), kFileSaveAsPS);
    fFileSaveMenu->AddEntry(Form("%s.&eps", name), kFileSaveAsEPS);
    fFileSaveMenu->AddEntry(Form("%s.p&df", name), kFileSaveAsPDF);
+   fFileSaveMenu->AddEntry(Form("%s.&tex", name), kFileSaveAsTEX);
    fFileSaveMenu->AddEntry(Form("%s.&gif", name), kFileSaveAsGIF);
 
    static Int_t img = 0;
@@ -926,6 +928,9 @@ Bool_t TRootCanvas::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
                   case kFileSaveAsPNG:
                      fCanvas->SaveAs(".png");
                      break;
+                  case kFileSaveAsTEX:
+                     fCanvas->SaveAs(".tex");
+                     break;
                   case kFilePrint:
                      PrintCanvas();
                      break;

From 7ef8ce19c05b0ffedfed06ec86ea9157fa5c7632 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Fri, 20 Feb 2015 18:35:19 +0100
Subject: [PATCH 008/200] Implement the transparency.

---
 graf2d/postscript/inc/TTeXDump.h   |  4 ++--
 graf2d/postscript/src/TTeXDump.cxx | 29 +++++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/graf2d/postscript/inc/TTeXDump.h b/graf2d/postscript/inc/TTeXDump.h
index 98225a064b897..b5a9e205ba900 100644
--- a/graf2d/postscript/inc/TTeXDump.h
+++ b/graf2d/postscript/inc/TTeXDump.h
@@ -38,7 +38,7 @@ class TTeXDump : public TVirtualPS {
    Float_t      fCurrentRed;      //Current Red component
    Float_t      fCurrentGreen;    //Current Green component
    Float_t      fCurrentBlue;     //Current Blue component
-
+   Float_t      fCurrentAlpha;    //Current Alpha value
 
 public:
    TTeXDump();
@@ -84,7 +84,7 @@ class TTeXDump : public TVirtualPS {
    Float_t XtoTeX(Double_t x);
    Float_t YtoTeX(Double_t y);
 
-   ClassDef(TTeXDump,0)  //Tex driver
+   ClassDef(TTeXDump,1)  //Tex driver
 };
 
 #endif
diff --git a/graf2d/postscript/src/TTeXDump.cxx b/graf2d/postscript/src/TTeXDump.cxx
index 4b7857faa100e..8251f62b6b63e 100644
--- a/graf2d/postscript/src/TTeXDump.cxx
+++ b/graf2d/postscript/src/TTeXDump.cxx
@@ -98,6 +98,7 @@ TTeXDump::TTeXDump() : TVirtualPS()
    fCurrentRed   = -1.;
    fCurrentGreen = -1.;
    fCurrentBlue  = -1.;
+   fCurrentAlpha = 1.;
 }
 
 
@@ -122,6 +123,7 @@ TTeXDump::TTeXDump(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
    fCurrentRed   = -1.;
    fCurrentGreen = -1.;
    fCurrentBlue  = -1.;
+   fCurrentAlpha = 1.;
 
    Open(fname, wtype);
 }
@@ -245,7 +247,12 @@ void TTeXDump::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
    if (fillis==1) {
       SetColor(fFillColor);
       PrintStr("@");
-      PrintStr("\\draw [color=c, fill=c] (");
+      PrintStr("\\draw [color=c, fill=c");
+      if (fCurrentAlpha != 1.) {
+         PrintStr(", fill opacity=");
+         WriteReal(fCurrentAlpha, kFALSE);
+      }
+      PrintStr("] (");
       WriteReal(x1c, kFALSE);
       PrintFast(1,",");
       WriteReal(y1c, kFALSE);
@@ -267,7 +274,12 @@ void TTeXDump::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
       if (fillsi==7)  PrintStr("horizontal lines");
       if (fillsi==10) PrintStr("bricks");
       if (fillsi==13) PrintStr("crosshatch");
-      PrintStr(", pattern color=c] (");
+      PrintStr(", pattern color=c");
+      if (fCurrentAlpha != 1.) {
+         PrintStr(", fill opacity=");
+         WriteReal(fCurrentAlpha, kFALSE);
+      }
+      PrintStr("] (");
       WriteReal(x1c, kFALSE);
       PrintFast(1,",");
       WriteReal(y1c, kFALSE);
@@ -280,7 +292,12 @@ void TTeXDump::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
    if (fillis == 0) {
       SetColor(fLineColor);
       PrintStr("@");
-      PrintStr("\\draw [c] (");
+      PrintStr("\\draw [c");
+      if (fCurrentAlpha != 1.) {
+         PrintStr(", opacity=");
+         WriteReal(fCurrentAlpha, kFALSE);
+      }
+      PrintStr("] (");
       WriteReal(x1c, kFALSE);
       PrintFast(1,",");
       WriteReal(y1c, kFALSE);
@@ -548,8 +565,11 @@ void TTeXDump::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
          if (fillsi==13) PrintStr("crosshatch");
          PrintStr(", pattern color=c");
       }
+      if (fCurrentAlpha != 1.) {
+         PrintStr(", fill opacity=");
+         WriteReal(fCurrentAlpha, kFALSE);
+      }
    }
-
    PrintStr("] (");
    WriteReal(x, kFALSE);
    PrintFast(1,",");
@@ -673,6 +693,7 @@ void TTeXDump::SetColor(Int_t color)
    TColor *col = gROOT->GetColor(color);
    if (col) SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
    else     SetColor(1., 1., 1.);
+   fCurrentAlpha = col->GetAlpha();
 }
 
 

From d845ea4639d3b7b81e5aab0d8bcec9b68507599c Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Fri, 20 Feb 2015 18:38:24 +0100
Subject: [PATCH 009/200] TTeXDump

---
 graf2d/doc/v604/index.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/graf2d/doc/v604/index.md b/graf2d/doc/v604/index.md
index 97367c83d3aab..05b6abc051394 100644
--- a/graf2d/doc/v604/index.md
+++ b/graf2d/doc/v604/index.md
@@ -25,6 +25,7 @@
 - Text color was ignored. It was always black.
 - The underscore `_` produced an error outside the TeX math context.
 - Fix an issue with transparent pads.
+- Implement transparent colors using TiKZ "opacity".
 
 ### TPostScript
 

From 8a954360c793161c2fc70da327bf19c8407cb867 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <gerardo.ganis@cern.ch>
Date: Thu, 12 Feb 2015 22:24:34 +0100
Subject: [PATCH 010/200] Proof-Packetizer: implement AddWorkers

  AddWorkers is the method to add workers while running. Added a basic implementation
  for testing.
  The patch also moves fInput from TPacketizerUnit to TVirtualPacketizer to that it can be
  used more generally reducing code duplications.
---
 proof/proofplayer/inc/TPacketizer.h          |  5 ++
 proof/proofplayer/inc/TPacketizerUnit.h      |  1 -
 proof/proofplayer/inc/TVirtualPacketizer.h   |  2 +
 proof/proofplayer/src/TPacketizer.cxx        | 76 +++++++++++++++-----
 proof/proofplayer/src/TVirtualPacketizer.cxx |  1 +
 5 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/proof/proofplayer/inc/TPacketizer.h b/proof/proofplayer/inc/TPacketizer.h
index 00e07971d36b5..55bf213c02179 100644
--- a/proof/proofplayer/inc/TPacketizer.h
+++ b/proof/proofplayer/inc/TPacketizer.h
@@ -67,6 +67,10 @@ class TPacketizer : public TVirtualPacketizer {
                                  // is (#events processed by 1 slave) / fPacketSizeAsAFraction.
                                  // It can be set with PROOF_PacketAsAFraction in input list.
 
+   // Add workers controls
+   Bool_t fHeuristicPSiz;   // Whether the packet size is calculated heuristically
+   Bool_t fDefMaxWrkNode;   // Whether the default is used for the max workers per node
+
    TPacketizer();
    TPacketizer(const TPacketizer&);     // no implementation, will generate
    void operator=(const TPacketizer&);  // error on accidental usage
@@ -89,6 +93,7 @@ class TPacketizer : public TVirtualPacketizer {
                 TList *input, TProofProgressStatus *st);
    virtual ~TPacketizer();
 
+   Int_t         AddWorkers(TList *workers);
    TDSetElement *GetNextPacket(TSlave *sl, TMessage *r);
    Long64_t      GetEntriesProcessed(TSlave *sl) const;
 
diff --git a/proof/proofplayer/inc/TPacketizerUnit.h b/proof/proofplayer/inc/TPacketizerUnit.h
index 5dcf73d1c8506..fff75c8ccefdd 100644
--- a/proof/proofplayer/inc/TPacketizerUnit.h
+++ b/proof/proofplayer/inc/TPacketizerUnit.h
@@ -60,7 +60,6 @@ class TPacketizerUnit : public TVirtualPacketizer {
    Bool_t      fFixedNum;        // Whether we must assign a fixed number of cycles per worker
 
    Long64_t    fPacketSeq;       // Sequential number of the last packet assigned
-   TList      *fInput;           // Input list
 
    TPacketizerUnit();
    TPacketizerUnit(const TPacketizerUnit&);     // no implementation, will generate
diff --git a/proof/proofplayer/inc/TVirtualPacketizer.h b/proof/proofplayer/inc/TVirtualPacketizer.h
index 8cb3813b73cd9..899097cce09b3 100644
--- a/proof/proofplayer/inc/TVirtualPacketizer.h
+++ b/proof/proofplayer/inc/TVirtualPacketizer.h
@@ -109,6 +109,8 @@ class TVirtualPacketizer : public TObject {
 
    TString  fDataSet;         // Name of the dataset being processed (for dataset-driven runs)
 
+   TList      *fInput;        // Input list
+
    TVirtualPacketizer(TList *input, TProofProgressStatus *st = 0);
    TVirtualPacketizer(const TVirtualPacketizer &);  // no implementation, will generate
    void operator=(const TVirtualPacketizer &);      // error on accidental usage
diff --git a/proof/proofplayer/src/TPacketizer.cxx b/proof/proofplayer/src/TPacketizer.cxx
index 2001006103ed9..8c85078d5b845 100644
--- a/proof/proofplayer/src/TPacketizer.cxx
+++ b/proof/proofplayer/src/TPacketizer.cxx
@@ -289,6 +289,8 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
    fFileNodes = 0;
    fMaxPerfIdx = 1;
    fMaxSlaveCnt = 0;
+   fHeuristicPSiz = kFALSE;
+   fDefMaxWrkNode = kTRUE;
 
    if (!fProgressStatus) {
       Error("TPacketizerAdaptive", "No progress status");
@@ -297,23 +299,27 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
 
    Long_t maxSlaveCnt = 0;
    if (TProof::GetParameter(input, "PROOF_MaxSlavesPerNode", maxSlaveCnt) == 0) {
-      if (maxSlaveCnt < 1) {
-         Warning("TPacketizer", "PROOF_MaxSlavesPerNode must be grater than 0");
+      if (maxSlaveCnt < 0) {
+         Warning("TPacketizer", "PROOF_MaxSlavesPerNode must be positive");
          maxSlaveCnt = 0;
       }
+      if (maxSlaveCnt > 0) fDefMaxWrkNode = kFALSE;
    } else {
       // Try also with Int_t (recently supported in TProof::SetParameter)
       Int_t mxslcnt = -1;
       if (TProof::GetParameter(input, "PROOF_MaxSlavesPerNode", mxslcnt) == 0) {
-         if (mxslcnt < 1) {
-            Warning("TPacketizer", "PROOF_MaxSlavesPerNode must be grater than 0");
+         if (mxslcnt < 0) {
+            Warning("TPacketizer", "PROOF_MaxSlavesPerNode must be positive");
             mxslcnt = 0;
          }
          maxSlaveCnt = (Long_t) mxslcnt;
+         if (maxSlaveCnt > 0) fDefMaxWrkNode = kFALSE;
       }
    }
-   if (!maxSlaveCnt)
-      maxSlaveCnt = gEnv->GetValue("Packetizer.MaxWorkersPerNode", 4);
+   if (!maxSlaveCnt) {
+      maxSlaveCnt = gEnv->GetValue("Packetizer.MaxWorkersPerNode", slaves->GetSize());
+      if (maxSlaveCnt != slaves->GetSize()) fDefMaxWrkNode = kFALSE;
+   }
    if (maxSlaveCnt > 0) {
       fMaxSlaveCnt = maxSlaveCnt;
       PDB(kPacketizer,1)
@@ -376,13 +382,9 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
    fSlaveStats = new TMap;
    fSlaveStats->SetOwner(kFALSE);
 
-   TSlave *slave;
-   TIter si(slaves);
-   while ((slave = (TSlave*) si.Next())) {
-      fSlaveStats->Add( slave, new TSlaveStat(slave) );
-      fMaxPerfIdx = slave->GetPerfIdx() > fMaxPerfIdx ?
-         slave->GetPerfIdx() : fMaxPerfIdx;
-   }
+   // Record initial available workers
+   Int_t nwrks = AddWorkers(slaves);
+   Info("TPacketizer", "Initial number of workers: %d", nwrks);
 
    // Setup file & filenode structure
    Reset();
@@ -560,6 +562,7 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
       Info("Process","using alternate packet size: %lld", fPacketSize);
    } else {
       // Heuristic for starting packet size
+      fHeuristicPSiz = kTRUE;
       Int_t nslaves = fSlaveStats->GetSize();
       if (nslaves > 0) {
          fPacketSize = fTotalEntries / (fPacketAsAFraction * nslaves);
@@ -593,6 +596,44 @@ TPacketizer::~TPacketizer()
    SafeDelete(fFileNodes);
 }
 
+//______________________________________________________________________________
+Int_t TPacketizer::AddWorkers(TList *workers)
+{
+   // Adds new workers. Returns the number of workers added, or -1 on failure.
+
+   if (!workers) {
+      Error("AddWorkers", "Null list of new workers!");
+      return -1;
+   }
+
+   Int_t curNumOfWrks = fSlaveStats->GetEntries();
+
+   TSlave *sl;
+   TIter next(workers);
+   while (( sl = dynamic_cast<TSlave*>(next()) ))
+      if (!fSlaveStats->FindObject(sl)) {
+         fSlaveStats->Add(sl, new TSlaveStat(sl));
+         fMaxPerfIdx = sl->GetPerfIdx() > fMaxPerfIdx ? sl->GetPerfIdx() : fMaxPerfIdx;
+      }
+
+   // If heuristic (and new workers) set the packet size
+   Int_t nwrks = fSlaveStats->GetSize();
+   if (fHeuristicPSiz && nwrks > curNumOfWrks) {
+      if (nwrks > 0) {
+         fPacketSize = fTotalEntries / (fPacketAsAFraction * nwrks);
+         if (fPacketSize < 1) fPacketSize = 1;
+      } else {
+         fPacketSize = 1;
+      }
+   }
+
+   // Update the max number that can access one file node if the default is used
+   if (fDefMaxWrkNode && nwrks > fMaxSlaveCnt) fMaxSlaveCnt = nwrks;
+
+   // Done
+   return nwrks;
+}
+
 //______________________________________________________________________________
 TPacketizer::TFileStat *TPacketizer::GetNextUnAlloc(TFileNode *node)
 {
@@ -672,13 +713,14 @@ TPacketizer::TFileNode *TPacketizer::NextActiveNode()
 
    fActive->Sort();
    PDB(kPacketizer,2) {
-      std::cout << "TPacketizer::NextActiveNode()" << std::endl;
+      Printf("TPacketizer::NextActiveNode : ----------------------");
       fActive->Print();
    }
 
    TFileNode *fn = (TFileNode*) fActive->First();
    if (fn != 0 && fMaxSlaveCnt > 0 && fn->GetSlaveCnt() >= fMaxSlaveCnt) {
-      PDB(kPacketizer,1) Info("NextActiveNode", "reached workers per node limit (%ld)", fMaxSlaveCnt);
+      PDB(kPacketizer,1)
+         Info("NextActiveNode", "reached workers per node limit (%ld)", fMaxSlaveCnt);
       fn = 0;
    }
 
@@ -1106,12 +1148,14 @@ TDSetElement *TPacketizer::GetNextPacket(TSlave *sl, TMessage *r)
       return 0;
    }
 
-   // find slave
+   // Find worker
 
    TSlaveStat *slstat = (TSlaveStat*) fSlaveStats->GetValue( sl );
 
    R__ASSERT( slstat != 0 );
 
+   PDB(kPacketizer,1)
+      Info("GetNextPacket","worker-%s (%s)", sl->GetOrdinal(), sl->GetName());
    // update stats & free old element
 
    Bool_t firstPacket = kFALSE;
diff --git a/proof/proofplayer/src/TVirtualPacketizer.cxx b/proof/proofplayer/src/TVirtualPacketizer.cxx
index f85b9001da12d..b4718221b681d 100644
--- a/proof/proofplayer/src/TVirtualPacketizer.cxx
+++ b/proof/proofplayer/src/TVirtualPacketizer.cxx
@@ -66,6 +66,7 @@ TVirtualPacketizer::TVirtualPacketizer(TList *input, TProofProgressStatus *st)
 {
    // Constructor.
 
+   fInput =  input;
    // General configuration parameters
    fMinPacketTime = 3;
    Double_t minPacketTime = 0;

From 4f22f0f93e0fdf866dab06293b5bb6e736f273f3 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Fri, 20 Feb 2015 14:07:16 +0100
Subject: [PATCH 011/200] Proof-PerfStat: adapt to dynamic startup

Add possibility to force setting the number of workers. This is useful when only a maximum is known,
as in  the case of dynamic startup. The TParameter<Int_t> is called 'PROOF_DynamicStartup' and the value
is the maximum number of workers (wmax). It is assumed that the ordinals are 0.0 ... 0.'wmax-1' .
---
 proof/proofplayer/src/TPerfStats.cxx | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/proof/proofplayer/src/TPerfStats.cxx b/proof/proofplayer/src/TPerfStats.cxx
index a3a7d92c8a5f7..94895ae979e96 100644
--- a/proof/proofplayer/src/TPerfStats.cxx
+++ b/proof/proofplayer/src/TPerfStats.cxx
@@ -135,11 +135,32 @@ TPerfStats::TPerfStats(TList *input, TList *output)
    Bool_t isEndMaster = ((gProofServ && gProofServ->IsEndMaster()) ||
                          (proof && proof->IsLite())) ? kTRUE : kFALSE;
 
-   TList *l = proof ? proof->GetListOfSlaveInfos() : 0 ;
+   TList *l = 0;
+   Bool_t deletel = kFALSE;
+   TParameter<Int_t> *dyns = (TParameter<Int_t> *) input->FindObject("PROOF_DynamicStartup");
+   if (dyns) {
+      // When starring up dynamically the number of slots needs to be guessed from the 
+      // maximum workers request. There is no way to change this later on.
+      Int_t nwrks = dyns->GetVal();
+      if (nwrks > 0) {
+         l = new TList;
+         for (Int_t i = 0; i < nwrks; i++) {
+            TSlaveInfo *wi = new TSlaveInfo(TString::Format("0.%d", i));
+            wi->SetStatus(TSlaveInfo::kActive);
+            l->Add(wi);
+         }
+         l->SetOwner(kTRUE);
+         deletel = kTRUE;
+      }
+   }
+   if (!l) l = proof ? proof->GetListOfSlaveInfos() : 0 ;
+
    TIter nextslaveinfo(l);
    while (TSlaveInfo *si = dynamic_cast<TSlaveInfo*>(nextslaveinfo()))
       if (si->fStatus == TSlaveInfo::kActive) fSlaves++;
 
+   fSlaves = 8;
+
    PDB(kMonitoring,1) Info("TPerfStats", "Statistics for %d slave(s)", fSlaves);
 
    fDoHist = (input->FindObject("PROOF_StatsHist") != 0);
@@ -297,6 +318,8 @@ TPerfStats::TPerfStats(TList *input, TList *output)
          }
       }
    }
+   // Cleanup
+   if (deletel) delete(l);
 
    if (isMaster) {
 

From 20d89783fbe904c2997b92095a67598fafe45593 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Fri, 20 Feb 2015 14:19:06 +0100
Subject: [PATCH 012/200] Proof-Serv: fix call flow for
 AddDynanicPath/AddIncludePath

Add missing possibility to control if after a request for changing a library or include path,
a log file is sent back.
---
 proof/proof/inc/TProofServ.h   |  2 +-
 proof/proof/src/TProofServ.cxx | 16 ++++++++++------
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/proof/proof/inc/TProofServ.h b/proof/proof/inc/TProofServ.h
index 1f2868181c272..866156c1b9749 100644
--- a/proof/proof/inc/TProofServ.h
+++ b/proof/proof/inc/TProofServ.h
@@ -219,7 +219,7 @@ friend class TXProofServ;
    virtual Int_t HandleDataSets(TMessage *mess, TString *slb = 0);
    virtual void  HandleSubmerger(TMessage *mess);
    virtual void  HandleFork(TMessage *mess);
-   virtual void  HandleLibIncPath(TMessage *mess);
+   virtual Int_t HandleLibIncPath(TMessage *mess);
    virtual void  HandleProcess(TMessage *mess, TString *slb = 0);
    virtual void  HandleQueryList(TMessage *mess);
    virtual void  HandleRemove(TMessage *mess, TString *slb = 0);
diff --git a/proof/proof/src/TProofServ.cxx b/proof/proof/src/TProofServ.cxx
index 6ecc457642644..3c6fc70db9be5 100644
--- a/proof/proof/src/TProofServ.cxx
+++ b/proof/proof/src/TProofServ.cxx
@@ -1485,7 +1485,7 @@ Int_t TProofServ::HandleSocketInput(TMessage *mess, Bool_t all)
 
    timer.Start();
 
-   Int_t rc = 0;
+   Int_t rc = 0, lirc = 0;
    TString slb;
    TString *pslb = (fgLogToSysLog > 0) ? &slb : (TString *)0;
 
@@ -2044,12 +2044,12 @@ Int_t TProofServ::HandleSocketInput(TMessage *mess, Bool_t all)
 
       case kPROOF_LIB_INC_PATH:
          if (all) {
-            HandleLibIncPath(mess);
+            lirc = HandleLibIncPath(mess);
          } else {
             rc = -1;
          }
          // Notify the client
-         SendLogFile();
+         if (lirc > 0) SendLogFile();
          break;
 
       case kPROOF_REALTIMELOG:
@@ -5058,19 +5058,21 @@ void TProofServ::HandleRetrieve(TMessage *mess, TString *slb)
 }
 
 //______________________________________________________________________________
-void TProofServ::HandleLibIncPath(TMessage *mess)
+Int_t TProofServ::HandleLibIncPath(TMessage *mess)
 {
    // Handle lib, inc search paths modification request
 
    TString type;
    Bool_t add;
    TString path;
+   Int_t rc = 1;
    (*mess) >> type >> add >> path;
+   if (mess->BufferSize() > mess->Length()) (*mess) >> rc;
 
    // Check type of action
    if ((type != "lib") && (type != "inc")) {
       Error("HandleLibIncPath","unknown action type: %s", type.Data());
-      return;
+      return rc;
    }
 
    // Separators can be either commas or blanks
@@ -5081,7 +5083,7 @@ void TProofServ::HandleLibIncPath(TMessage *mess)
    if (path.Length() > 0 && path != "-") {
       if (!(op = path.Tokenize(" "))) {
          Error("HandleLibIncPath","decomposing path %s", path.Data());
-         return;
+         return rc;
       }
    }
 
@@ -5181,6 +5183,8 @@ void TProofServ::HandleLibIncPath(TMessage *mess)
             fProof->RemoveIncludePath(path);
       }
    }
+   // Done
+   return rc;
 }
 
 //______________________________________________________________________________

From e3f2c1aa5c140c6c68788abf7e3f9a3cfaba1875 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Fri, 20 Feb 2015 14:32:28 +0100
Subject: [PATCH 013/200] Proof-Lite: add simulator for dynamic worker startup

The patch makes TProof::PollForNewWorkers virtual and adds an implementation of the same in TProofLite,
so that we can simulate dynamic startup, for packetizer testign purposes. The all thing is triggered
by the ROOT-rc

              'Proof.SimulateDynamicStartup'

which accepts a string value in the form "increase-step:max-num-workers", where 'increase-step' is the number
of new workers created at each call, and 'max-num-workers' is the maximum number of workers to start.
Once this is set, if a PROOF-Lite session with less workers than 'max-num-workers', during processing the
numbers of workers will be gradually increased to reach 'max-num-workers'.

The patch also re-organize the TProof code for dynamic startup to minimize duplications. In particular, the
part setting up the new workers environment has been separated into a new method SetupWorkersEnv, so that
it can used by TProofLite too.
Several bugs have been fixed in this code as a results of tests with examples requiring packages and loaded
macros, which were not used in the simple example used to develop this code.
---
 proof/proof/inc/TProof.h                   |   9 +-
 proof/proof/inc/TProofLite.h               |   9 +-
 proof/proof/src/TProof.cxx                 | 232 +++++++++++++-------
 proof/proof/src/TProofLite.cxx             | 238 ++++++++++++++++++++-
 proof/proofplayer/src/TProofPlayer.cxx     |   8 +-
 proof/proofplayer/src/TProofPlayerLite.cxx |   6 +-
 6 files changed, 414 insertions(+), 88 deletions(-)

diff --git a/proof/proof/inc/TProof.h b/proof/proof/inc/TProof.h
index 05ff5cecd0378..33ae7b1223181 100644
--- a/proof/proof/inc/TProof.h
+++ b/proof/proof/inc/TProof.h
@@ -564,6 +564,7 @@ friend class TXProofServ;     // to access EUrgent
    THashList      *fGlobalPackageDirList;//list of directories containing global packages libs
    TProofLockPath *fPackageLock;     //package lock
    TList          *fEnabledPackagesOnClient; //list of packages enabled on client
+   TList          *fEnabledPackagesOnCluster;  //list of enabled packages
 
    TList          *fInputData;       //Input data objects sent over via file
    TString         fInputDataFile;   //File with input data objects
@@ -634,6 +635,7 @@ friend class TXProofServ;     // to access EUrgent
    Int_t    Exec(const char *cmd, ESlaves list, Bool_t plusMaster);
    Int_t    SendCommand(const char *cmd, ESlaves list = kActive);
    Int_t    SendCurrentState(ESlaves list = kActive);
+   Int_t    SendCurrentState(TList *list);
    Bool_t   CheckFile(const char *file, TSlave *sl, Long_t modtime, Int_t cpopt = (kCp | kCpBin));
    Int_t    SendObject(const TObject *obj, ESlaves list = kActive);
    Int_t    SendGroupView();
@@ -648,7 +650,7 @@ friend class TXProofServ;     // to access EUrgent
    Int_t    SetParallelSilent(Int_t nodes, Bool_t random = kFALSE);
    void     RecvLogFile(TSocket *s, Int_t size);
    void     NotifyLogMsg(const char *msg, const char *sfx = "\n");
-   Int_t    BuildPackage(const char *package, EBuildPackageOpt opt = kBuildAll, Int_t chkveropt = kCheckROOT);
+   Int_t    BuildPackage(const char *package, EBuildPackageOpt opt = kBuildAll, Int_t chkveropt = kCheckROOT, TList *workers = 0);
    Int_t    BuildPackageOnClient(const char *package, Int_t opt = 0, TString *path = 0, Int_t chkveropt = kCheckROOT);
    Int_t    LoadPackage(const char *package, Bool_t notOnClient = kFALSE, TList *loadopts = 0, TList *workers = 0);
    Int_t    LoadPackageOnClient(const char *package, TList *loadopts = 0);
@@ -681,7 +683,6 @@ friend class TXProofServ;     // to access EUrgent
    Int_t    HandleInputMessage(TSlave *wrk, TMessage *m, Bool_t deactonfail = kFALSE);
    void     HandleSubmerger(TMessage *mess, TSlave *sl);
    void     SetMonitor(TMonitor *mon = 0, Bool_t on = kTRUE);
-   Int_t    PollForNewWorkers();
 
    void     ReleaseMonitor(TMonitor *mon);
 
@@ -746,6 +747,7 @@ friend class TXProofServ;     // to access EUrgent
    virtual Bool_t  StartSlaves(Bool_t attach = kFALSE);
    Int_t AddWorkers(TList *wrks);
    Int_t RemoveWorkers(TList *wrks);
+   void  SetupWorkersEnv(TList *wrks, Bool_t increasingpool = kFALSE);
 
    void                         SetPlayer(TVirtualProofPlayer *player);
    TVirtualProofPlayer         *GetPlayer() const { return fPlayer; }
@@ -761,11 +763,14 @@ friend class TXProofServ;     // to access EUrgent
    TSlave *CreateSubmaster(const char *url, const char *ord,
                            const char *image, const char *msd, Int_t nwk = 1);
 
+   virtual Int_t PollForNewWorkers();
    virtual void SaveWorkerInfo();
 
    Int_t    Collect(ESlaves list = kActive, Long_t timeout = -1, Int_t endtype = -1, Bool_t deactonfail = kFALSE);
    Int_t    Collect(TList *slaves, Long_t timeout = -1, Int_t endtype = -1, Bool_t deactonfail = kFALSE);
 
+   TList   *GetEnabledPackages() const { return fEnabledPackagesOnCluster; }
+
    void         SetDSet(TDSet *dset) { fDSet = dset; }
    virtual void ValidateDSet(TDSet *dset);
 
diff --git a/proof/proof/inc/TProofLite.h b/proof/proof/inc/TProofLite.h
index 897074f235c13..bf5ece9a72d40 100644
--- a/proof/proof/inc/TProofLite.h
+++ b/proof/proof/inc/TProofLite.h
@@ -53,6 +53,9 @@ friend class TProofPlayerLite;
    TServerSocket *fServSock; // Server socket to accept call backs
    Bool_t   fForkStartup; // Startup N-1 workers forking the first worker
 
+   Int_t    fDynamicStartupStep;  // Dyn Startup simulation: increment at each call
+   Int_t    fDynamicStartupNMax;  // Dyn Startup simulation: max number of workers
+
    TString  fVarExp;      // Internal variable to pass drawing options
    TString  fSelection;   // Internal variable to pass drawing options
 
@@ -85,7 +88,7 @@ friend class TProofPlayerLite;
 protected:
    TProofLite() : TProof() { } // For derived classes to use
 
-   Int_t CreateSymLinks(TList *files);
+   Int_t CreateSymLinks(TList *files, TList *wrks = 0);
    Int_t Init(const char *masterurl, const char *conffile,
                const char *confdir, Int_t loglevel,
                const char *alias = 0);
@@ -95,7 +98,9 @@ friend class TProofPlayerLite;
    void SetQueryRunning(TProofQueryResult *pq);
    Int_t SetupWorkers(Int_t opt = 0, TList *wrks = 0);
    Int_t CopyMacroToCache(const char *macro, Int_t headerRequired = 0,
-                          TSelector **selector = 0, Int_t opt = 0);
+                          TSelector **selector = 0, Int_t opt = 0, TList *wrks = 0);
+
+   Int_t PollForNewWorkers();
 
 public:
    TProofLite(const char *masterurl, const char *conffile = kPROOF_ConfFile,
diff --git a/proof/proof/src/TProof.cxx b/proof/proof/src/TProof.cxx
index 93da047d359cd..708fe51007739 100644
--- a/proof/proof/src/TProof.cxx
+++ b/proof/proof/src/TProof.cxx
@@ -562,6 +562,7 @@ void TProof::InitMembers()
    fGlobalPackageDirList = 0;
    fPackageLock = 0;
    fEnabledPackagesOnClient = 0;
+   fEnabledPackagesOnCluster = 0;
 
    fInputData = 0;
 
@@ -791,6 +792,9 @@ Int_t TProof::Init(const char *, const char *conffile,
    ResetBit(TProof::kNewInputData);
    fPrintProgress  = 0;
 
+   fEnabledPackagesOnCluster = new TList;
+   fEnabledPackagesOnCluster->SetOwner();
+
    // Timeout for some collect actions
    fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
 
@@ -1342,10 +1346,11 @@ Int_t TProof::AddWorkers(TList *workerList)
    UInt_t nSlavesDone = 0;
    Int_t ord = 0;
 
-   // Loop over all new workers and start them
-   Bool_t goMoreParallel = (fSlaves->GetEntries() > 0);
+   // Loop over all new workers and start them (if we had already workers it means we are
+   // increasing parallelism or that is not the first time we are called)
+   Bool_t goMoreParallel = (fSlaves->GetEntries() > 0) ? kTRUE : kFALSE;
 
-   // a list of TSlave objects for workers that are being added
+   // A list of TSlave objects for workers that are being added
    TList *addedWorkers = new TList();
    if (!addedWorkers) {
       // This is needed to silence Coverity ...
@@ -1478,7 +1483,7 @@ Int_t TProof::AddWorkers(TList *workerList)
    if (fDynamicStartup && goMoreParallel) {
 
       PDB(kGlobal, 3)
-         Info("AddWorkers", "Will invoke GoMoreParallel()");
+         Info("AddWorkers", "will invoke GoMoreParallel()");
       Int_t nw = GoMoreParallel(nwrk);
       PDB(kGlobal, 3)
          Info("AddWorkers", "GoMoreParallel()=%d", nw);
@@ -1491,79 +1496,95 @@ Int_t TProof::AddWorkers(TList *workerList)
       GoParallel(nwrk, kFALSE, 0);
    }
 
-   if (gProofServ && gProofServ->GetEnabledPackages() &&
-       gProofServ->GetEnabledPackages()->GetSize() > 0) {
-      TIter nxp(gProofServ->GetEnabledPackages());
+   // Set worker processing environment
+   SetupWorkersEnv(addedWorkers, goMoreParallel);
+
+   // Update list of current workers
+   PDB(kGlobal, 3)
+      Info("AddWorkers", "Will invoke SaveWorkerInfo()");
+   SaveWorkerInfo();
+
+   // Inform the client that the number of workers has changed
+   if (fDynamicStartup && gProofServ) {
+      PDB(kGlobal, 3)
+         Info("AddWorkers", "Will invoke SendParallel()");
+      gProofServ->SendParallel(kTRUE);
+
+      if (goMoreParallel && fPlayer) {
+         // In case we are adding workers dynamically to an existing process, we
+         // should invoke a special player's Process() to set only added workers
+         // to the proper state
+         PDB(kGlobal, 3)
+            Info("AddWorkers", "Will send the PROCESS message to selected workers");
+         fPlayer->JoinProcess(addedWorkers);
+      }
+   }
+
+   // Cleanup
+   delete addedWorkers;
+
+   return 0;
+}
+
+//______________________________________________________________________________
+void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
+{
+   // Set up packages, loaded macros, include and lib paths ...
+
+   // Packages
+   TList *packs = gProofServ ? gProofServ->GetEnabledPackages() : GetEnabledPackages();
+   if (packs->GetSize() > 0) {
+      TIter nxp(packs);      
       TPair *pck = 0;
       while ((pck = (TPair *) nxp())) {
          // Upload and Enable methods are intelligent and avoid
          // re-uploading or re-enabling of a package to a node that has it.
-         if (fDynamicStartup && goMoreParallel) {
+         if (fDynamicStartup && increasingWorkers) {
             // Upload only on added workers
             PDB(kGlobal, 3)
-               Info("AddWorkers", "Will invoke UploadPackage() and EnablePackage() on added workers");
+               Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on added workers");
             if (UploadPackage(pck->GetName(), kUntar, addedWorkers) >= 0)
                EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE, addedWorkers);
-         }
-         else {
+         } else {
             PDB(kGlobal, 3)
-               Info("AddWorkers", "Will invoke UploadPackage() and EnablePackage() on all workers");
+               Info("SetupWorkersEnv", "will invoke UploadPackage() and EnablePackage() on all workers");
             if (UploadPackage(pck->GetName()) >= 0)
                EnablePackage(pck->GetName(), (TList *) pck->Value(), kTRUE);
          }
       }
    }
 
+   // Loaded macros
    if (fLoadedMacros) {
       TIter nxp(fLoadedMacros);
       TObjString *os = 0;
       while ((os = (TObjString *) nxp())) {
-         PDB(kGlobal, 3)
-            Info("AddWorkers", "Will invoke Load() on selected workers");
-         Printf("Loading a macro : %s", os->GetName());
+         PDB(kGlobal, 3) {
+            Info("SetupWorkersEnv", "will invoke Load() on selected workers");
+            Printf("Loading a macro : %s", os->GetName());
+         }
          Load(os->GetName(), kTRUE, kTRUE, addedWorkers);
       }
    }
 
+   // Dynamic path
    TString dyn = gSystem->GetDynamicPath();
    dyn.ReplaceAll(":", " ");
    dyn.ReplaceAll("\"", " ");
    PDB(kGlobal, 3)
-      Info("AddWorkers", "Will invoke AddDynamicPath() on selected workers");
-   AddDynamicPath(dyn, kFALSE, addedWorkers, fDynamicStartup);
+      Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
+   AddDynamicPath(dyn, kFALSE, addedWorkers, !fDynamicStartup); // Do not Collect
 
+   // Include path
    TString inc = gSystem->GetIncludePath();
    inc.ReplaceAll("-I", " ");
    inc.ReplaceAll("\"", " ");
    PDB(kGlobal, 3)
-      Info("AddWorkers", "Will invoke AddIncludePath() on selected workers");
-   AddIncludePath(inc, kFALSE, addedWorkers, fDynamicStartup);
-
-   // Update list of current workers
-   PDB(kGlobal, 3)
-      Info("AddWorkers", "Will invoke SaveWorkerInfo()");
-   SaveWorkerInfo();
-
-   // Inform the client that the number of workers has changed
-   if (fDynamicStartup && gProofServ) {
-      PDB(kGlobal, 3)
-         Info("AddWorkers", "Will invoke SendParallel()");
-      gProofServ->SendParallel(kTRUE);
-
-      if (goMoreParallel && fPlayer) {
-         // In case we are adding workers dynamically to an existing process, we
-         // should invoke a special player's Process() to set only added workers
-         // to the proper state
-         PDB(kGlobal, 3)
-            Info("AddWorkers", "Will send the PROCESS message to selected workers");
-         fPlayer->JoinProcess(addedWorkers);
-      }
-   }
+      Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
+   AddIncludePath(inc, kFALSE, addedWorkers, !fDynamicStartup);  // Do not Collect
 
-   // Cleanup
-   delete addedWorkers;
-
-   return 0;
+   // Done
+   return;
 }
 
 //______________________________________________________________________________
@@ -2771,7 +2792,7 @@ Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deact
    // Timeout counter
    Long_t nto = timeout;
    PDB(kCollect, 2)
-      Info("Collect","active: %d", mon->GetActive());
+      Info("Collect","#%04d: active: %d", collectId, mon->GetActive());
 
    // On clients, handle Ctrl-C during collection
    if (fIntHandler)
@@ -2809,9 +2830,11 @@ Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deact
       if (TestBit(TProof::kIsMaster) && !IsIdle() && fDynamicStartup && !fIsPollingWorkers &&
          ((fLastPollWorkers_s == -1) || (time(0)-fLastPollWorkers_s >= kPROOF_DynWrkPollInt_s))) {
          fIsPollingWorkers = kTRUE;
-         PollForNewWorkers();
+         if (PollForNewWorkers() > 0) DeActivateAsyncInput();
          fLastPollWorkers_s = time(0);
          fIsPollingWorkers = kFALSE;
+         PDB(kCollect, 1)
+            Info("Collect","#%04d: now active: %d", collectId, mon->GetActive());
       }
 
       // Wait for a ready socket
@@ -2826,7 +2849,7 @@ Int_t TProof::Collect(TMonitor *mon, Long_t timeout, Int_t endtype, Bool_t deact
             // Deactivate it if we are done with it
             mon->DeActivate(s);
             PDB(kCollect, 2)
-               Info("Collect","deactivating %p (active: %d, %p)",
+               Info("Collect","#%04d: deactivating %p (active: %d, %p)", collectId,
                               s, mon->GetActive(),
                               mon->GetListOfActives()->First());
          } else if (rc == 2) {
@@ -3155,6 +3178,8 @@ Int_t TProof::HandleInputMessage(TSlave *sl, TMessage *mess, Bool_t deactonfail)
 
       case kPROOF_GETPACKET:
          {
+            PDB(kGlobal,2)
+               Info("HandleInputMessage","%s: kPROOF_GETPACKET", sl->GetOrdinal());
             TDSetElement *elem = 0;
             elem = fPlayer ? fPlayer->GetNextPacket(sl, mess) : 0;
 
@@ -3224,6 +3249,8 @@ Int_t TProof::HandleInputMessage(TSlave *sl, TMessage *mess, Bool_t deactonfail)
          {
             (*mess) >> sl->fBytesRead >> sl->fRealTime >> sl->fCpuTime
                   >> sl->fWorkDir >> sl->fProofWorkDir;
+            PDB(kCollect,2)
+               Info("HandleInputMessage", "kPROOF_GETSTATS: %s", sl->fWorkDir.Data());
             TString img;
             if ((mess->BufferSize() > mess->Length()))
                (*mess) >> img;
@@ -3625,7 +3652,7 @@ Int_t TProof::HandleInputMessage(TSlave *sl, TMessage *mess, Bool_t deactonfail)
       case kPROOF_SETIDLE:
          {
             PDB(kGlobal,2)
-               Info("HandleInputMessage","kPROOF_SETIDLE: enter");
+               Info("HandleInputMessage","kPROOF_SETIDLE from '%s': enter (%d)", sl->GetOrdinal(), fNotIdle);
 
             // The session is idle
             if (IsLite()) {
@@ -6659,6 +6686,22 @@ Int_t TProof::GetRC(const char *rcenv, TString &env, const char *ord)
    return rc;
 }
 
+//______________________________________________________________________________
+Int_t TProof::SendCurrentState(TList *list)
+{
+   // Transfer the current state of the master to the active slave servers.
+   // The current state includes: the current working directory, etc.
+   // Returns the number of active slaves. Returns -1 in case of error.
+
+   if (!IsValid()) return -1;
+
+   // Go to the new directory, reset the interpreter environment and
+   // tell slave to delete all objects from its new current directory.
+   Broadcast(gDirectory->GetPath(), kPROOF_RESET, list);
+
+   return GetParallel();
+}
+
 //______________________________________________________________________________
 Int_t TProof::SendCurrentState(ESlaves list)
 {
@@ -7079,11 +7122,11 @@ Int_t TProof::GoMoreParallel(Int_t nWorkersToAdd)
    // Returns -1 on error, number of total (not added!) workers on success.
 
    if (!IsValid() || !IsMaster() || IsIdle()) {
-      Error("GoMoreParallel", "Can't invoke here -- should not happen!");
+      Error("GoMoreParallel", "can't invoke here -- should not happen!");
       return -1;
    }
-   if (!gProofServ) {
-      Error("GoMoreParallel", "No ProofServ available -- should not happen!");
+   if (!gProofServ && !IsLite()) {
+      Error("GoMoreParallel", "no ProofServ available nor Lite -- should not happen!");
       return -1;
    }
 
@@ -7165,7 +7208,7 @@ Int_t TProof::GoMoreParallel(Int_t nWorkersToAdd)
    s.Form("PROOF just went more parallel (%d additional worker%s, %d worker%s total)",
       nAddedWorkers, (nAddedWorkers == 1) ? "" : "s",
       nTotalWorkers, (nTotalWorkers == 1) ? "" : "s");
-   gProofServ->SendAsynMessage(s);
+   if (gProofServ) gProofServ->SendAsynMessage(s);   
    Info("GoMoreParallel", "%s", s.Data());
 
    return nTotalWorkers;
@@ -7943,7 +7986,8 @@ Int_t TProof::DisablePackages()
 }
 
 //______________________________________________________________________________
-Int_t TProof::BuildPackage(const char *package, EBuildPackageOpt opt, Int_t chkveropt)
+Int_t TProof::BuildPackage(const char *package,
+                           EBuildPackageOpt opt, Int_t chkveropt, TList *workers)
 {
    // Build specified package. Executes the PROOF-INF/BUILD.sh
    // script if it exists on all unique nodes. If opt is kBuildOnSlavesNoWait
@@ -7984,13 +8028,20 @@ Int_t TProof::BuildPackage(const char *package, EBuildPackageOpt opt, Int_t chkv
    }
 
    if (opt <= kBuildAll && (!IsLite() || !buildOnClient)) {
-      TMessage mess(kPROOF_CACHE);
-      mess << Int_t(kBuildPackage) << pac << chkveropt;
-      Broadcast(mess, kUnique);
+      if (workers) {
+         TMessage mess(kPROOF_CACHE);
+         mess << Int_t(kBuildPackage) << pac << chkveropt;
+         Broadcast(mess, workers);
 
-      TMessage mess2(kPROOF_CACHE);
-      mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
-      Broadcast(mess2, fNonUniqueMasters);
+      } else {
+         TMessage mess(kPROOF_CACHE);
+         mess << Int_t(kBuildPackage) << pac << chkveropt;
+         Broadcast(mess, kUnique);
+
+         TMessage mess2(kPROOF_CACHE);
+         mess2 << Int_t(kBuildSubPackage) << pac << chkveropt;
+         Broadcast(mess2, fNonUniqueMasters);
+      }
    }
 
    if (opt >= kBuildAll) {
@@ -8001,9 +8052,19 @@ Int_t TProof::BuildPackage(const char *package, EBuildPackageOpt opt, Int_t chkv
          if (TestBit(TProof::kIsClient) && fPackageLock) fPackageLock->Unlock();
       }
 
+
       fStatus = 0;
-      if (!IsLite() || !buildOnClient)
-         Collect(kAllUnique);
+      if (!IsLite() || !buildOnClient) {
+
+        // On the master, workers that fail are deactivated
+        // Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
+         if (workers) {
+//            Collect(workers, -1, -1, deactivateOnFailure);
+            Collect(workers);
+         } else {
+            Collect(kAllUnique);
+         }
+      }
 
       if (fStatus < 0 || st < 0)
          return -1;
@@ -8246,13 +8307,14 @@ Int_t TProof::LoadPackage(const char *package, Bool_t notOnClient,
    // On the master, workers that fail are deactivated
    Bool_t deactivateOnFailure = (IsMaster()) ? kTRUE : kFALSE;
 
+   Bool_t doCollect = (fDynamicStartup && !IsIdle()) ? kFALSE : kTRUE;
+
    if (workers) {
       PDB(kPackage, 3)
          Info("LoadPackage", "Sending load message to selected workers only");
       Broadcast(mess, workers);
-      Collect(workers, -1, -1, deactivateOnFailure);
-   }
-   else {
+      if (doCollect) Collect(workers, -1, -1, deactivateOnFailure);
+   } else {
       Broadcast(mess);
       Collect(kActive, -1, -1, deactivateOnFailure);
    }
@@ -8663,8 +8725,8 @@ Int_t TProof::EnablePackage(const char *package, TList *loadopts,
    }
   if (gDebug > 0)
       Info("EnablePackage", "using check version option: %d", chkveropt);
-
-   if (BuildPackage(pac, opt, chkveropt) == -1)
+   
+   if (BuildPackage(pac, opt, chkveropt, workers) == -1)
       return -1;
 
    TList *optls = (loadopts && loadopts->GetSize() > 0) ? loadopts : 0;
@@ -8676,6 +8738,13 @@ Int_t TProof::EnablePackage(const char *package, TList *loadopts,
    if (LoadPackage(pac, notOnClient, optls, workers) == -1)
       return -1;
 
+   // Record the information for later usage (simulation of dynamic start on PROOF-Lite)
+   if (!fEnabledPackagesOnCluster->FindObject(pac)) {
+      TPair *pck = (optls && optls->GetSize() > 0) ? new TPair(new TObjString(pac), optls->Clone())
+                                                   : new TPair(new TObjString(pac), 0);
+      fEnabledPackagesOnCluster->Add(pck);
+   }
+
    return 0;
 }
 
@@ -9104,11 +9173,7 @@ Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
       return -1;
    }
 
-   if (TestBit(TProof::kIsClient)) {
-      if (wrks) {
-         Error("Load", "the 'wrks' arg can be used only on the master");
-         return -1;
-      }
+   if (TestBit(TProof::kIsClient) && !wrks) {
 
       // Extract the file implementation name first
       TString addsname, implname = macro;
@@ -9239,6 +9304,16 @@ Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
       // Wait for master and workers to be done
       Collect(kActive);
 
+      if (IsLite()) {
+         PDB(kGlobal, 1) Info("Load", "adding loaded macro: %s", macro);
+         if (!fLoadedMacros) {
+            fLoadedMacros = new TList();
+            fLoadedMacros->SetOwner();
+         }
+         // if wrks is specified the macro should already be loaded on the master.
+         fLoadedMacros->Add(new TObjString(macro));
+      }
+
    } else {
       // On master
 
@@ -9249,10 +9324,12 @@ Int_t TProof::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueWorkers,
 
       if (uniqueWorkers) {
          mess << Int_t(kLoadMacro) << basemacro;
-         if (wrks)
+         if (wrks) {
             Broadcast(mess, wrks);
-         else
+            Collect(wrks);
+         } else {
             Broadcast(mess, kUnique);
+         }
       } else {
          // Wait for the result of the previous sending
          Collect(kUnique);
@@ -9320,6 +9397,9 @@ Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
    else
       m << TString("-");
 
+   // Tell the server to send back or not
+   m << (Int_t)doCollect;
+
    // Forward the request
    if (wrks) {
       Broadcast(m, wrks);
@@ -9362,6 +9442,9 @@ Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
    else
       m << TString("-");
 
+   // Tell the server to send back or not
+   m << (Int_t)doCollect;
+
    // Forward the request
    if (wrks) {
       Broadcast(m, wrks);
@@ -11880,10 +11963,11 @@ Int_t TProof::ModifyWorkerLists(const char *ord, Bool_t add, Bool_t save)
       THashList *ords = 0;
       if (!allord) {
          ords = new THashList();
+         const char *masterord = (gProofServ) ? gProofServ->GetOrdinal() : "0";
          TString oo(ord), o;
          Int_t from = 0;
          while(oo.Tokenize(o, from, ","))
-            if (o.BeginsWith(gProofServ->GetOrdinal())) ords->Add(new TObjString(o));
+            if (o.BeginsWith(masterord)) ords->Add(new TObjString(o));
       }
       // We do not need to send forward
       fw = kFALSE;
diff --git a/proof/proof/src/TProofLite.cxx b/proof/proof/src/TProofLite.cxx
index 98f5a87050918..854605cb7dcc7 100644
--- a/proof/proof/src/TProofLite.cxx
+++ b/proof/proof/src/TProofLite.cxx
@@ -208,9 +208,30 @@ Int_t TProofLite::Init(const char *, const char *conffile,
    fInputData      = 0;
    ResetBit(TProof::kNewInputData);
 
+   fEnabledPackagesOnCluster = new TList;
+   fEnabledPackagesOnCluster->SetOwner();
+
    // Timeout for some collect actions
    fCollectTimeout = gEnv->GetValue("Proof.CollectTimeout", -1);
 
+   // Should the workers be started dynamically; default: no
+   fDynamicStartup = kFALSE;
+   fDynamicStartupStep = -1;
+   fDynamicStartupNMax = -1;
+   TString dynconf = gEnv->GetValue("Proof.SimulateDynamicStartup", "");
+   if (dynconf.Length() > 0) {
+      fDynamicStartup = kTRUE;
+      fLastPollWorkers_s = time(0);
+      // Extract parameters
+      Int_t from = 0;
+      TString p;
+      if (dynconf.Tokenize(p, from, ":"))
+         if (p.IsDigit()) fDynamicStartupStep = p.Atoi();
+      if (dynconf.Tokenize(p, from, ":"))
+         if (p.IsDigit()) fDynamicStartupNMax = p.Atoi();
+   }
+
+
    fProgressDialog        = 0;
    fProgressDialogStarted = kFALSE;
 
@@ -1149,7 +1170,7 @@ Long64_t TProofLite::Process(TDSet *dset, const char *selector, Option_t *option
    // Make sure that all enabled workers get some work, unless stated
    // differently
    if (!fPlayer->GetInputList()->FindObject("PROOF_MaxSlavesPerNode"))
-      SetParameter("PROOF_MaxSlavesPerNode", (Long_t)fNWorkers);
+      SetParameter("PROOF_MaxSlavesPerNode", (Long_t)0);
 
    Bool_t hasNoData = (!dset || (dset && dset->TestBit(TDSet::kEmpty))) ? kTRUE : kFALSE;
 
@@ -1423,13 +1444,14 @@ Long64_t TProofLite::Process(TDSet *dset, const char *selector, Option_t *option
 }
 
 //______________________________________________________________________________
-Int_t TProofLite::CreateSymLinks(TList *files)
+Int_t TProofLite::CreateSymLinks(TList *files, TList *wrks)
 {
    // Create in each worker sandbox symlinks to the files in the list
    // Used to make the cache information available to workers.
 
    Int_t rc = 0;
    if (files) {
+      TList *wls = (wrks) ? wrks : fActiveSlaves;
       TIter nxf(files);
       TObjString *os = 0;
       while ((os = (TObjString *) nxf())) {
@@ -1437,7 +1459,7 @@ Int_t TProofLite::CreateSymLinks(TList *files)
          TString tgt(os->GetName());
          gSystem->ExpandPathName(tgt);
          // Loop over active workers
-         TIter nxw(fActiveSlaves);
+         TIter nxw(wls);
          TSlave *wrk = 0;
          while ((wrk = (TSlave *) nxw())) {
             // Link name
@@ -1446,6 +1468,9 @@ Int_t TProofLite::CreateSymLinks(TList *files)
             if (gSystem->Symlink(tgt, lnk) != 0) {
                rc++;
                Warning("CreateSymLinks", "problems creating sym link: %s", lnk.Data());
+            } else {
+               PDB(kGlobal,1)
+                  Info("CreateSymLinks", "created sym link: %s", lnk.Data());
             }
          }
       }
@@ -1600,7 +1625,30 @@ Int_t TProofLite::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueOnly,
    TString macs(macro), mac;
    Int_t from = 0;
    while (macs.Tokenize(mac, from, ",")) {
-      if (CopyMacroToCache(mac) < 0) return -1;
+      if (IsIdle()) {
+         if (CopyMacroToCache(mac) < 0) return -1;
+      } else {
+         // The name
+         TString macn = gSystem->BaseName(mac);
+         macn.Remove(macn.Last('.'));
+         // Relevant pointers
+         TList cachedFiles;
+         TString cacheDir = fCacheDir;
+         gSystem->ExpandPathName(cacheDir);
+         void * dirp = gSystem->OpenDirectory(cacheDir);
+         if (dirp) {
+            const char *e = 0;
+            while ((e = gSystem->GetDirEntry(dirp))) {
+               if (!strncmp(e, macn.Data(), macn.Length())) {
+                  TString fncache = Form("%s/%s", cacheDir.Data(), e);
+                  cachedFiles.Add(new TObjString(fncache.Data()));
+               }
+            }
+            gSystem->FreeDirectory(dirp);
+         }
+         // Create the relevant symlinks
+         CreateSymLinks(&cachedFiles, wrks);
+      }
    }
 
    return TProof::Load(macro, notOnClient, uniqueOnly, wrks);
@@ -1608,7 +1656,7 @@ Int_t TProofLite::Load(const char *macro, Bool_t notOnClient, Bool_t uniqueOnly,
 
 //______________________________________________________________________________
 Int_t TProofLite::CopyMacroToCache(const char *macro, Int_t headerRequired,
-                                   TSelector **selector, Int_t opt)
+                                   TSelector **selector, Int_t opt, TList *wrks)
 {
    // Copy a macro, and its possible associated .h[h] file,
    // to the cache directory, from where the workers can get the file.
@@ -1651,7 +1699,7 @@ Int_t TProofLite::CopyMacroToCache(const char *macro, Int_t headerRequired,
          Int_t ip = (mp.BeginsWith(".:")) ? 2 : 0;
          mp.Insert(ip, np);
          TROOT::SetMacroPath(mp);
-         if (gDebug > 0)
+         PDB(kGlobal,1)
             Info("CopyMacroToCache", "macro path set to '%s'", TROOT::GetMacroPath());
       }
    }
@@ -1838,7 +1886,7 @@ Int_t TProofLite::CopyMacroToCache(const char *macro, Int_t headerRequired,
 
    // Create symlinks
    if (opt & (kCp | kCpBin))
-      CreateSymLinks(cachedFiles);
+      CreateSymLinks(cachedFiles, wrks);
 
    cachedFiles->SetOwner();
    delete cachedFiles;
@@ -2548,3 +2596,179 @@ void TProofLite::ShowDataDir(const char *dirname)
    // Done
    return;
 }
+
+//______________________________________________________________________________
+Int_t TProofLite::PollForNewWorkers()
+{
+   // Simulate dynamic addition, for test purposes.
+   // Here we decide how many workers to add, we create them and set the
+   // environment.
+   // This call is called regularly by Collect if the opton is enabled.
+   // Returns the number of new workers added, or <0 on errors.
+
+   // Max workers
+   if (fDynamicStartupNMax <= 0) {
+      SysInfo_t si;
+      if (gSystem->GetSysInfo(&si) == 0 && si.fCpus > 2) {
+         fDynamicStartupNMax = si.fCpus;
+      } else {
+         fDynamicStartupNMax = 2;
+      }
+   }
+   if (fNWorkers >= fDynamicStartupNMax) {
+      // Max reached: disable
+      Info("PollForNewWorkers", "max reached: %d workers started", fNWorkers);
+      fDynamicStartup =  kFALSE;
+      return 0;
+   }
+
+   // Number of new workers
+   Int_t nAdd = (fDynamicStartupStep > 0) ? fDynamicStartupStep : 1;
+
+   // Create a monitor and add the socket to it
+   TMonitor *mon = new TMonitor;
+   mon->Add(fServSock);
+
+   TList started;
+   TSlave *wrk = 0;
+   Int_t nWrksDone = 0, nWrksTot = -1;
+   TString fullord;
+
+   nWrksTot = fNWorkers + nAdd;
+   // Now we create the worker applications which will call us back to finalize
+   // the setup
+   Int_t ord = fNWorkers;
+   for (; ord < nWrksTot; ord++) {
+
+      // Ordinal for this worker server
+      fullord = Form("0.%d", ord);
+
+      // Create environment files
+      SetProofServEnv(fullord);
+
+      // Create worker server and add to the list
+      if ((wrk = CreateSlave("lite", fullord, 100, fImage, fWorkDir)))
+         started.Add(wrk);
+
+      PDB(kGlobal, 3)
+         Info("PollForNewWorkers", "additional worker '%s' started", fullord.Data());
+
+      // Notify
+      NotifyStartUp("Opening connections to workers", ++nWrksDone, nWrksTot);
+
+   } //end of worker loop
+   fNWorkers = nWrksTot;
+
+   // A list of TSlave objects for workers that are being added
+   TList *addedWorkers = new TList();
+   addedWorkers->SetOwner(kFALSE);
+
+   // Wait for call backs
+   nWrksDone = 0;
+   nWrksTot = started.GetSize();
+   Int_t nSelects = 0;
+   Int_t to = gEnv->GetValue("ProofLite.StartupTimeOut", 5) * 1000;
+   while (started.GetSize() > 0 && nSelects < nWrksTot) {
+
+      // Wait for activity on the socket for max 5 secs
+      TSocket *xs = mon->Select(to);
+
+      // Count attempts and check
+      nSelects++;
+      if (xs == (TSocket *) -1) continue;
+
+      // Get the connection
+      TSocket *s = fServSock->Accept();
+      if (s && s->IsValid()) {
+         // Receive ordinal
+         TMessage *msg = 0;
+         if (s->Recv(msg) < 0) {
+            Warning("PollForNewWorkers", "problems receiving message from accepted socket!");
+         } else {
+            if (msg) {
+               *msg >> fullord;
+               // Find who is calling back
+               if ((wrk = (TSlave *) started.FindObject(fullord))) {
+                  // Remove it from the started list
+                  started.Remove(wrk);
+
+                  // Assign tis socket the selected worker
+                  wrk->SetSocket(s);
+                  // Remove socket from global TROOT socket list. Only the TProof object,
+                  // representing all worker sockets, will be added to this list. This will
+                  // ensure the correct termination of all proof servers in case the
+                  // root session terminates.
+                  {  R__LOCKGUARD2(gROOTMutex);
+                     gROOT->GetListOfSockets()->Remove(s);
+                  }
+                  if (wrk->IsValid()) {
+                     // Set the input handler
+                     wrk->SetInputHandler(new TProofInputHandler(this, wrk->GetSocket()));
+                     // Set fParallel to 1 for workers since they do not
+                     // report their fParallel with a LOG_DONE message
+                     wrk->fParallel = 1;
+                     // Finalize setup of the server
+                     wrk->SetupServ(TSlave::kSlave, 0);
+                  }
+
+                  // Monitor good workers
+                  fSlaves->Add(wrk);
+                  if (wrk->IsValid()) {
+                     fActiveSlaves->Add(wrk);             // Is this required? Check!
+                     fAllMonitor->Add(wrk->GetSocket());
+                     // Record also in the list for termination
+                     if (addedWorkers) addedWorkers->Add(wrk);
+                     // Notify startup operations
+                     NotifyStartUp("Setting up added worker servers", ++nWrksDone, nWrksTot);
+                  } else {
+                     // Flag as bad
+                     fBadSlaves->Add(wrk);
+                  }
+               }
+            } else {
+               Warning("PollForNewWorkers", "received empty message from accepted socket!");
+            }
+         }
+      }
+   }
+
+   // Cleanup the monitor and the server socket
+   mon->DeActivateAll();
+   delete mon;
+
+   Broadcast(kPROOF_GETSTATS, addedWorkers);
+   Collect(addedWorkers, fCollectTimeout);
+
+   // Update group view
+   // SendGroupView();
+
+   // By default go into parallel mode
+   // SetParallel(-1, 0);
+   SendCurrentState(addedWorkers);
+
+   // Set worker processing environment
+   SetupWorkersEnv(addedWorkers, kTRUE);
+
+   // We are adding workers dynamically to an existing process, we
+   // should invoke a special player's Process() to set only added workers
+   // to the proper state
+   if (fPlayer) {
+      PDB(kGlobal, 3)
+         Info("PollForNewWorkers", "Will send the PROCESS message to selected workers");
+      fPlayer->JoinProcess(addedWorkers);
+   }
+
+   // Cleanup fwhat remained from startup
+   Collect(addedWorkers);
+
+   // Activate
+   TIter naw(addedWorkers);
+   while ((wrk = (TSlave *)naw())) {
+      fActiveMonitor->Add(wrk->GetSocket());
+   }
+   // Cleanup
+   delete addedWorkers;
+
+   // Done
+   return nWrksDone;
+}
diff --git a/proof/proofplayer/src/TProofPlayer.cxx b/proof/proofplayer/src/TProofPlayer.cxx
index 2322531bd83de..88d45533c817c 100644
--- a/proof/proofplayer/src/TProofPlayer.cxx
+++ b/proof/proofplayer/src/TProofPlayer.cxx
@@ -2540,6 +2540,8 @@ Bool_t TProofPlayerRemote::JoinProcess(TList *workers)
       }
    }
 
+   if (fProof->IsLite()) fProof->fNotIdle += workers->GetSize();
+
    PDB(kGlobal, 2)
       Info("Process", "Adding new workers to the packetizer");
    if (fPacketizer->AddWorkers(workers) == -1) {
@@ -4167,9 +4169,11 @@ TDSetElement *TProofPlayerRemote::GetNextPacket(TSlave *slave, TMessage *r)
    TDSetElement *e = fPacketizer->GetNextPacket( slave, r );
 
    if (e == 0) {
-      PDB(kPacketizer,2) Info("GetNextPacket","%s: done!", slave->GetOrdinal());
+      PDB(kPacketizer,2) 
+         Info("GetNextPacket","%s: done!", slave->GetOrdinal());
    } else if (e == (TDSetElement*) -1) {
-      PDB(kPacketizer,2) Info("GetNextPacket","%s: waiting ...", slave->GetOrdinal());
+      PDB(kPacketizer,2)
+         Info("GetNextPacket","%s: waiting ...", slave->GetOrdinal());
    } else {
       PDB(kPacketizer,2)
          Info("GetNextPacket","%s (%s): '%s' '%s' '%s' %lld %lld",
diff --git a/proof/proofplayer/src/TProofPlayerLite.cxx b/proof/proofplayer/src/TProofPlayerLite.cxx
index 2118cbc84878f..af53d92128989 100644
--- a/proof/proofplayer/src/TProofPlayerLite.cxx
+++ b/proof/proofplayer/src/TProofPlayerLite.cxx
@@ -208,7 +208,7 @@ Long64_t TProofPlayerLite::Process(TDSet *dset, const char *selector_file,
                                dset->GetDirectory());
    if (dset->TestBit(TDSet::kEmpty))
       set->SetBit(TDSet::kEmpty);
-   fProof->SetParameter("PROOF_MaxSlavesPerNode", (Long_t) ((TProofLite *)fProof)->fNWorkers);
+   fProof->SetParameter("PROOF_MaxSlavesPerNode", (Long_t) 0);
    if (InitPacketizer(dset, nentries, first, "TPacketizerUnit", "TPacketizer") != 0) {
       Error("Process", "cannot init the packetizer");
       fExitStatus = kAborted;
@@ -260,7 +260,11 @@ Long64_t TProofPlayerLite::Process(TDSet *dset, const char *selector_file,
    fProof->ResetMergePrg();
 
    // Broadcast main message
+   PDB(kGlobal,1) Info("Process","Calling Broadcast");
+   if (fProcessMessage) delete fProcessMessage;
+   fProcessMessage = new TMessage(kPROOF_PROCESS);
    mesg << set << fn << fInput << opt << num << fst << evl << sync << enl;
+   (*fProcessMessage) << set << fn << fInput << opt << num << fst << evl << sync << enl;
    Int_t nb = fProof->Broadcast(mesg);
    PDB(kGlobal,1) Info("Process", "Broadcast called: %d workers notified", nb);
    fProof->fNotIdle += nb;

From 192c8c94afbc84a12408e9aa5502574b90a9efb3 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Fri, 20 Feb 2015 14:32:55 +0100
Subject: [PATCH 014/200] Proof-Packetizer: Fine tune warning messages

---
 proof/proofplayer/src/TPacketizerAdaptive.cxx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/proof/proofplayer/src/TPacketizerAdaptive.cxx b/proof/proofplayer/src/TPacketizerAdaptive.cxx
index 3ba99236c3e69..c859f77fbe9b5 100644
--- a/proof/proofplayer/src/TPacketizerAdaptive.cxx
+++ b/proof/proofplayer/src/TPacketizerAdaptive.cxx
@@ -503,18 +503,18 @@ TPacketizerAdaptive::TPacketizerAdaptive(TDSet *dset, TList *slaves,
 
    Long_t maxSlaveCnt = 0;
    if (TProof::GetParameter(input, "PROOF_MaxSlavesPerNode", maxSlaveCnt) == 0) {
-      if (maxSlaveCnt < 1) {
+      if (maxSlaveCnt < 0) {
          Info("TPacketizerAdaptive",
-              "The value of PROOF_MaxSlavesPerNode must be grater than 0");
+              "The value of PROOF_MaxSlavesPerNode must be positive");
          maxSlaveCnt = 0;
       }
    } else {
       // Try also with Int_t (recently supported in TProof::SetParameter)
       Int_t mxslcnt = -1;
       if (TProof::GetParameter(input, "PROOF_MaxSlavesPerNode", mxslcnt) == 0) {
-         if (mxslcnt < 1) {
+         if (mxslcnt < 0) {
             Info("TPacketizerAdaptive",
-                 "The value of PROOF_MaxSlavesPerNode must be grater than 0");
+                 "The value of PROOF_MaxSlavesPerNode must be positive");
             mxslcnt = 0;
          }
          maxSlaveCnt = (Long_t) mxslcnt;

From 12e5436e0970d0001de6d20eefbab39804ee7fa5 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Fri, 20 Feb 2015 14:40:25 +0100
Subject: [PATCH 015/200] Proof-Tutorials: support for passing input objects to
 runProof

It is now possible to pass as 4th argument a list of objects to be added to the input list to further control
the PROOF behaviour:

   root [] TList *ins = new TList
   root [] ins->Add(new TParameter<Int_t>("MyParm", 3))
   root [] runProof("simple",0,4,ins)

the content of 'ins' will then be copied to the input list before processing.
---
 tutorials/proof/runProof.C | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/tutorials/proof/runProof.C b/tutorials/proof/runProof.C
index 659de680137ca..5c92149efcd9e 100644
--- a/tutorials/proof/runProof.C
+++ b/tutorials/proof/runProof.C
@@ -311,6 +311,15 @@
 //
 //   will disable 2 workers and use the other 2.
 //
+//   Finally, it is possible to pass as 4th argument a list of objects to be added
+//   to the input list to further control the PROOF behaviour:
+//
+//   root [] TList *ins = new TList
+//   root [] ins->Add(new TParameter<Int_t>("MyParm", 3))
+//   root [] runProof("simple",0,4,ins)
+//
+//   the content of 'ins' will then be copied to the input list before processing.
+//
 
 
 #include "TCanvas.h"
@@ -339,7 +348,7 @@ const char *pythia8data = 0;
 
 void runProof(const char *what = "simple",
               const char *masterurl = "proof://localhost:40000",
-              Int_t nwrks = -1)
+              Int_t nwrks = -1, TList *ins = 0)
 {
 #ifdef __CINT__
    Printf("runProof: this script can only be executed via ACliC:");
@@ -695,6 +704,15 @@ void runProof(const char *what = "simple",
       proof->SetParameter("PROOF_StatsTrace", "");
       proof->SetParameter("PROOF_SlaveStatsTrace", "");
    }
+
+   // Additional inputs from the argument 'ins'
+   if (ins && ins->GetSize() > 0) {
+      TObject *oin = 0;
+      TIter nxo(ins);
+      while ((oin = nxo())) { proof->AddInput(oin); }
+   }
+
+   // Full lits of inputs so far
    proof->GetInputList()->Print();
 
    // Action

From 4e3c71608614b1eeb365c9dd1a1b74ef2e5a869c Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sat, 21 Feb 2015 09:36:37 +0100
Subject: [PATCH 016/200] Implement loading of MachO universal bins (e.g.
 Frameworks).

---
 interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp b/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
index c8415384f4bbb..124a8e81bb91b 100644
--- a/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
+++ b/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
@@ -165,7 +165,8 @@ namespace cling {
 #ifdef __APPLE__
       (Magic == file_magic::macho_fixed_virtual_memory_shared_lib
        || Magic == file_magic::macho_dynamically_linked_shared_lib
-       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub)
+       || Magic == file_magic::macho_dynamically_linked_shared_lib_stub
+       || Magic == file_magic::macho_universal_binary)
 #elif defined(LLVM_ON_UNIX)
 #ifdef __CYGWIN__
       (Magic == file_magic::pecoff_executable)

From eef877766ac84361fa86e11e5a1dcf24e41d69b6 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sat, 21 Feb 2015 22:19:30 +0100
Subject: [PATCH 017/200] Fix nullptr value printing (ROOT-7092).

---
 .../cling/lib/Interpreter/ValueExtractionSynthesizer.cpp     | 5 +++++
 interpreter/cling/test/Prompt/ValuePrinter/Regression.C      | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp
index 2bc649f9f3756..734365869602c 100644
--- a/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp
+++ b/interpreter/cling/lib/Interpreter/ValueExtractionSynthesizer.cpp
@@ -318,6 +318,7 @@ namespace {
     else if (desugaredTy->isIntegralOrEnumerationType()
              || desugaredTy->isReferenceType()
              || desugaredTy->isPointerType()
+             || desugaredTy->isNullPtrType()
              || desugaredTy->isFloatingType()) {
       if (desugaredTy->isIntegralOrEnumerationType()) {
         // 1)  enum, integral, float, double, referece, pointer types :
@@ -349,6 +350,10 @@ namespace {
           = m_Sema->BuildCStyleCastExpr(noLoc, TSI, noLoc, E).get();
         CallArgs.push_back(castedE);
       }
+      else if (desugaredTy->isNullPtrType()) {
+        // nullptr should decay to void* just fine.
+        CallArgs.push_back(E);
+      }
       else if (desugaredTy->isFloatingType()) {
         // floats and double will fall naturally in the correct
         // case, because of the overload resolution.
diff --git a/interpreter/cling/test/Prompt/ValuePrinter/Regression.C b/interpreter/cling/test/Prompt/ValuePrinter/Regression.C
index adcb6a06ebdab..d325400beacdd 100644
--- a/interpreter/cling/test/Prompt/ValuePrinter/Regression.C
+++ b/interpreter/cling/test/Prompt/ValuePrinter/Regression.C
@@ -46,3 +46,5 @@ q // CHECK: (const int *) 0x123
 
 // PR ROOT-5467
 &A::someFunc // CHECK: (int (class A::*)(float)) @0x{{[0-9a-f]+}}
+
+nullptr // CHECK: (nullptr_t) @0x0

From c393dae4b4799dd0c1eff68b8738427cc021cd86 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sat, 21 Feb 2015 22:37:50 +0100
Subject: [PATCH 018/200] No #include <new> in C mode; add basic C mode test
 (ROOT-7090).

---
 .../cling/lib/Interpreter/IncrementalParser.cpp  | 13 ++++++++-----
 interpreter/cling/test/Driver/C.c                | 16 ++++++++++++++++
 2 files changed, 24 insertions(+), 5 deletions(-)
 create mode 100644 interpreter/cling/test/Driver/C.c

diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
index 5077dd061fb30..c47eeb6f59818 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp
@@ -235,11 +235,14 @@ namespace cling {
     if (External)
       External->StartTranslationUnit(m_Consumer);
 
-    // <new> is needed by the ValuePrinter so it's a good thing to include it.
-    // We need to include it to determine the version number of the standard
-    // library implementation.
-    ParseInternal("#include <new>");
-    CheckABICompatibility(m_CI.get());
+    if (m_CI->getLangOpts().CPlusPlus) {
+      // <new> is needed by the ValuePrinter so it's a good thing to include it.
+      // We need to include it to determine the version number of the standard
+      // library implementation.
+      ParseInternal("#include <new>");
+      // That's really C++ ABI compatibility. C has other problems ;-)
+      CheckABICompatibility(m_CI.get());
+    }
 
     // DO NOT commit the transactions here: static initialization in these
     // transactions requires gCling through local_cxa_atexit(), but that has not
diff --git a/interpreter/cling/test/Driver/C.c b/interpreter/cling/test/Driver/C.c
new file mode 100644
index 0000000000000..f389331f234df
--- /dev/null
+++ b/interpreter/cling/test/Driver/C.c
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+// CLING - the C++ LLVM-based InterpreterG :)
+//
+// This file is dual-licensed: you can choose to license it under the University
+// of Illinois Open Source License or the GNU Lesser General Public License. See
+// LICENSE.TXT for details.
+//------------------------------------------------------------------------------
+
+// RUN: cat %s | %cling -x c | FileCheck %s
+
+// Validate cling C mode.
+
+int printf(const char*,...);
+printf("CHECK 123\n"); // CHECK: CHECK 123
+
+// fix value printing!

From b93eff6645bdac2b8564ecc9d52bc29bd313e2f3 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sat, 21 Feb 2015 23:09:18 +0100
Subject: [PATCH 019/200] Tell which language is enabled (ROOT-7090).

---
 .../cling/lib/Interpreter/Interpreter.cpp     | 17 ++++++---
 .../cling/lib/UserInterface/UserInterface.cpp | 36 ++++++++++++++++---
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index d39bc6a92c837..7138ec2acc559 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -64,6 +64,10 @@ namespace {
     }
     return cling::Interpreter::kExeSuccess;
   }
+
+  static bool isPracticallyEmptyModule(const llvm::Module* M) {
+    return M->empty() && M->global_empty() && M->alias_empty();
+  }
 } // unnamed namespace
 
 namespace cling {
@@ -1134,12 +1138,15 @@ namespace cling {
     assert(!isInSyntaxOnlyMode() && "Running on what?");
     assert(T.getState() == Transaction::kCommitted && "Must be committed");
 
-    T.setExeUnloadHandle(m_Executor.get(), m_Executor->emitToJIT());
-
-    // Forward to IncrementalExecutor; should not be called by
-    // anyone except for IncrementalParser.
     IncrementalExecutor::ExecutionResult ExeRes
-       = m_Executor->runStaticInitializersOnce(T);
+       = IncrementalExecutor::kExeSuccess;
+    if (!isPracticallyEmptyModule(T.getModule())) {
+      T.setExeUnloadHandle(m_Executor.get(), m_Executor->emitToJIT());
+
+      // Forward to IncrementalExecutor; should not be called by
+      // anyone except for IncrementalParser.
+      ExeRes = m_Executor->runStaticInitializersOnce(T);
+    }
 
     // Reset the module builder to clean up global initializers, c'tors, d'tors
     ASTContext& C = getCI()->getASTContext();
diff --git a/interpreter/cling/lib/UserInterface/UserInterface.cpp b/interpreter/cling/lib/UserInterface/UserInterface.cpp
index 33ec86a1b4571..ea042d9861e53 100644
--- a/interpreter/cling/lib/UserInterface/UserInterface.cpp
+++ b/interpreter/cling/lib/UserInterface/UserInterface.cpp
@@ -22,6 +22,9 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Config/config.h"
 
+#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/CompilerInstance.h"
+
 // Fragment copied from LLVM's raw_ostream.cpp
 #if defined(HAVE_UNISTD_H)
 # include <unistd.h>
@@ -173,10 +176,33 @@ namespace cling {
 
   void UserInterface::PrintLogo() {
     llvm::raw_ostream& outs = m_MetaProcessor->getOuts();
-    outs << "\n";
-    outs << "****************** CLING ******************" << "\n";
-    outs << "* Type C++ code and press enter to run it *" << "\n";
-    outs << "*             Type .q to exit             *" << "\n";
-    outs << "*******************************************" << "\n";
+    const clang::LangOptions& LangOpts
+      = m_MetaProcessor->getInterpreter().getCI()->getLangOpts();
+    if (LangOpts.CPlusPlus) {
+      outs << "\n"
+        "****************** CLING ******************\n"
+        "* Type C++ code and press enter to run it *\n"
+        "*             Type .q to exit             *\n"
+        "*******************************************\n";
+    } else {
+      outs << "\n"
+        "***************** CLING *****************\n"
+        "* Type C code and press enter to run it *\n"
+        "*            Type .q to exit            *\n"
+        "*****************************************\n";
+    }
   }
 } // end namespace cling
+
+
+
+
+
+
+
+
+
+
+
+
+

From 9fda07cc75cd6d10cde8dd8322745547f72744f0 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sun, 22 Feb 2015 00:03:15 +0100
Subject: [PATCH 020/200] Add test for ROOT-6531.

---
 interpreter/cling/test/Prompt/cppmacros.C | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/interpreter/cling/test/Prompt/cppmacros.C b/interpreter/cling/test/Prompt/cppmacros.C
index c0e3d6ef92d48..670b2ab0a6c11 100644
--- a/interpreter/cling/test/Prompt/cppmacros.C
+++ b/interpreter/cling/test/Prompt/cppmacros.C
@@ -16,3 +16,5 @@ extern "C" int printf(const char* fmt, ...);
 void cppmacros() {
    MYMACRO("PARAM"); // CHECK: string:PARAM
 }
+
+#pragma clang diagnostic ignored "-Wkeyword-compat" // ROOT-6531

From 9232811954ce4e13462096318316293a6c4476da Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Sun, 22 Feb 2015 23:58:09 +0100
Subject: [PATCH 021/200] Check that the pointer is valid before printing
 (ROOT-7095).

---
 interpreter/cling/lib/Interpreter/Value.cpp | 44 +++++++++++++++++++--
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/Value.cpp b/interpreter/cling/lib/Interpreter/Value.cpp
index 760ae3e4737d8..3cf2315c1fd06 100644
--- a/interpreter/cling/lib/Interpreter/Value.cpp
+++ b/interpreter/cling/lib/Interpreter/Value.cpp
@@ -30,7 +30,42 @@
 #include <iostream>
 #include <sstream>
 
+// For address validation
+#ifdef LLVM_ON_WIN32
+#include <Windows.h>
+#else
+#include <unistd.h>
+#endif
+
 namespace {
+  static bool isAddressValid(void* P) {
+    if (!P || P == (void*)-1)
+      return false;
+
+#ifdef LLVM_ON_WIN32
+    MEMORY_BASIC_INFORMATION MBI;
+    if (!VirtualQuery(P, &MBI, sizeof(MBI)))
+      return false;
+    if (MBI.State != MEM_COMMIT)
+      return false;
+    return true;
+#else
+    // There is a POSIX way of finding whether an address can be accessed for
+    // reading: write() will return EFAULT if not.
+    int FD[2];
+    if (pipe(FD))
+      return false; // error in pipe()? Be conservative...
+    int NBytes = write(FD[1], P, 1/*byte*/);
+    close(FD[0]);
+    close(FD[1]);
+    if (NBytes != 1) {
+      assert(errno == EFAULT && "unexpected pipe write error");
+      return false;
+    }
+    return true;
+#endif
+  }
+
   ///\brief The allocation starts with this layout; it is followed by the
   ///  value's object at m_Payload. This class does not inherit from
   ///  llvm::RefCountedBase because deallocation cannot use this type but must
@@ -345,16 +380,19 @@ namespace cling {
       // will be needed by evaluate.
     }
     QualType ValueTy = this->getType().getNonReferenceType();
+    bool ValidAddress = true;
     if (!ValueTy->isPointerType())
       ValueTy = C.getPointerType(ValueTy);
+    else
+       ValidAddress = isAddressValid(this->getPtr());
     ValueTy = utils::TypeName::GetFullyQualifiedType(ValueTy, getASTContext());
     PrintingPolicy Policy(m_Interpreter->getCI()->getLangOpts());
     std::string ValueTyStr = ValueTy.getAsString(Policy);
     std::string typeStr;
     std::string valueStr;
 
-    if (hasViableCandidateToCall(R, *this)) {
-      // There is such a routine call it:
+    if (ValidAddress && hasViableCandidateToCall(R, *this)) {
+      // There is such a routine call, it:
       std::stringstream printTypeSS;
       printTypeSS << "cling::printType(";
       printTypeSS << '(' << ValueTyStr << ')' << this->getPtr() << ',';
@@ -407,7 +445,7 @@ namespace cling {
       // will be needed by evaluate.
     }
 
-    if (hasViableCandidateToCall(R, *this)) {
+    if (ValidAddress && hasViableCandidateToCall(R, *this)) {
       // There is such a routine call it:
       std::stringstream printValueSS;
       printValueSS << "cling::printValue(";

From dfb3ff07ebd63784a64f9ef46160a923daadbb03 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Mon, 23 Feb 2015 00:15:01 +0100
Subject: [PATCH 022/200] Use LLVM_ON_WIN32 instead of WIN32 CPP macro.

---
 interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp b/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
index 124a8e81bb91b..c023f4263a2c8 100644
--- a/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
+++ b/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp
@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 
-#ifdef WIN32
+#ifdef LLVM_ON_WIN32
 #include <Windows.h>
 #include <shlobj.h>
 #else

From 761601fc4ac3cdb93cfa04845d3c1bb295ee7673 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Mon, 23 Feb 2015 00:21:18 +0100
Subject: [PATCH 023/200] From martell: the proper spelling is _WIN32.

---
 core/textinput/src/textinput/SignalHandler.cpp       | 2 +-
 core/textinput/src/textinput/StreamReader.cpp        | 4 ++--
 core/textinput/src/textinput/StreamReaderUnix.cpp    | 4 ++--
 core/textinput/src/textinput/StreamReaderWin.cpp     | 4 ++--
 core/textinput/src/textinput/TerminalConfigUnix.cpp  | 4 ++--
 core/textinput/src/textinput/TerminalDisplay.cpp     | 4 ++--
 core/textinput/src/textinput/TerminalDisplayUnix.cpp | 4 ++--
 core/textinput/src/textinput/TerminalDisplayWin.cpp  | 4 ++--
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/core/textinput/src/textinput/SignalHandler.cpp b/core/textinput/src/textinput/SignalHandler.cpp
index 9c02dee4d6c5b..6a3cd5b7bcaae 100644
--- a/core/textinput/src/textinput/SignalHandler.cpp
+++ b/core/textinput/src/textinput/SignalHandler.cpp
@@ -26,7 +26,7 @@ namespace textinput {
 
   void
   SignalHandler::EmitCtrlZ() {
-#ifndef WIN32
+#ifndef _WIN32
     raise(SIGTSTP);
 #endif
   }
diff --git a/core/textinput/src/textinput/StreamReader.cpp b/core/textinput/src/textinput/StreamReader.cpp
index e8e65b612e64b..9ddfa0fdf9245 100644
--- a/core/textinput/src/textinput/StreamReader.cpp
+++ b/core/textinput/src/textinput/StreamReader.cpp
@@ -14,7 +14,7 @@
 
 #include "textinput/StreamReader.h"
 
-#ifdef WIN32
+#ifdef _WIN32
 # include "textinput/StreamReaderWin.h"
 #else
 # include "textinput/StreamReaderUnix.h"
@@ -25,7 +25,7 @@ namespace textinput {
 
   StreamReader*
   StreamReader::Create() {
-#ifdef WIN32
+#ifdef _WIN32
      return new StreamReaderWin();
 #else
      return new StreamReaderUnix();
diff --git a/core/textinput/src/textinput/StreamReaderUnix.cpp b/core/textinput/src/textinput/StreamReaderUnix.cpp
index 74e66c61aab50..72e9367487d20 100644
--- a/core/textinput/src/textinput/StreamReaderUnix.cpp
+++ b/core/textinput/src/textinput/StreamReaderUnix.cpp
@@ -13,7 +13,7 @@
 //  Axel Naumann <axel@cern.ch>, 2011-05-12
 //===----------------------------------------------------------------------===//
 
-#ifndef WIN32
+#ifndef _WIN32
 
 #include "textinput/StreamReaderUnix.h"
 
@@ -274,4 +274,4 @@ namespace textinput {
   }
 }
 
-#endif // ifndef WIN32
+#endif // ifndef _WIN32
diff --git a/core/textinput/src/textinput/StreamReaderWin.cpp b/core/textinput/src/textinput/StreamReaderWin.cpp
index 1615e465e6a31..bf59ebc57d48d 100644
--- a/core/textinput/src/textinput/StreamReaderWin.cpp
+++ b/core/textinput/src/textinput/StreamReaderWin.cpp
@@ -12,7 +12,7 @@
 //  Axel Naumann <axel@cern.ch>, 2011-05-12
 //===----------------------------------------------------------------------===//
 
-#ifdef WIN32
+#ifdef _WIN32
 
 #include "textinput/StreamReaderWin.h"
 
@@ -211,4 +211,4 @@ namespace textinput {
     }
   }
 }
-#endif // WIN32
+#endif // _WIN32
diff --git a/core/textinput/src/textinput/TerminalConfigUnix.cpp b/core/textinput/src/textinput/TerminalConfigUnix.cpp
index 113e7c90137ab..6f00c5e6872e9 100644
--- a/core/textinput/src/textinput/TerminalConfigUnix.cpp
+++ b/core/textinput/src/textinput/TerminalConfigUnix.cpp
@@ -1,4 +1,4 @@
-#ifndef WIN32
+#ifndef _WIN32
 
 //===--- TerminalConfigUnix.cpp - termios storage -------------*- C++ -*-===//
 //
@@ -143,4 +143,4 @@ bool TerminalConfigUnix::IsInteractive() const {
 
 
 
-#endif // ndef WIN32
+#endif // ifndef _WIN32
diff --git a/core/textinput/src/textinput/TerminalDisplay.cpp b/core/textinput/src/textinput/TerminalDisplay.cpp
index a54529ccb46c6..f2c2416a18e4d 100644
--- a/core/textinput/src/textinput/TerminalDisplay.cpp
+++ b/core/textinput/src/textinput/TerminalDisplay.cpp
@@ -14,7 +14,7 @@
 
 #include "textinput/TerminalDisplay.h"
 
-#ifdef WIN32
+#ifdef _WIN32
 #include "textinput/TerminalDisplayWin.h"
 #else
 #include "textinput/TerminalDisplayUnix.h"
@@ -30,7 +30,7 @@ namespace textinput {
 
   TerminalDisplay*
   TerminalDisplay::Create() {
-#ifdef WIN32
+#ifdef _WIN32
     return new TerminalDisplayWin();
 #else
     return new TerminalDisplayUnix();
diff --git a/core/textinput/src/textinput/TerminalDisplayUnix.cpp b/core/textinput/src/textinput/TerminalDisplayUnix.cpp
index 17aef56e3ccb2..2b45168a41a90 100644
--- a/core/textinput/src/textinput/TerminalDisplayUnix.cpp
+++ b/core/textinput/src/textinput/TerminalDisplayUnix.cpp
@@ -1,4 +1,4 @@
-#ifndef WIN32
+#ifndef _WIN32
 
 //===--- TerminalDisplayUnix.cpp - Output To UNIX Terminal ------*- C++ -*-===//
 //
@@ -326,4 +326,4 @@ namespace textinput {
 
 }
 
-#endif // #ifndef WIN32
+#endif // #ifndef _WIN32
diff --git a/core/textinput/src/textinput/TerminalDisplayWin.cpp b/core/textinput/src/textinput/TerminalDisplayWin.cpp
index 8a0ff9e8130db..f14f84d820fdf 100644
--- a/core/textinput/src/textinput/TerminalDisplayWin.cpp
+++ b/core/textinput/src/textinput/TerminalDisplayWin.cpp
@@ -13,7 +13,7 @@
 //  Axel Naumann <axel@cern.ch>, 2011-05-12
 //===----------------------------------------------------------------------===//
 
-#ifdef WIN32
+#ifdef _WIN32
 #include "textinput/TerminalDisplayWin.h"
 
 #include "textinput/Color.h"
@@ -218,4 +218,4 @@ namespace textinput {
 
 }
 
-#endif // WIN32
+#endif // ifdef _WIN32

From 2e618321f13ca2e22c213e31459ba9d2d885080e Mon Sep 17 00:00:00 2001
From: martell <martellmalone@gmail.com>
Date: Mon, 8 Dec 2014 18:11:37 +0000
Subject: [PATCH 024/200] use size_t for void pointer cast

---
 interpreter/cling/include/cling/Interpreter/Value.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/interpreter/cling/include/cling/Interpreter/Value.h b/interpreter/cling/include/cling/Interpreter/Value.h
index 4ebc32aec4cdf..22b28fda85510 100644
--- a/interpreter/cling/include/cling/Interpreter/Value.h
+++ b/interpreter/cling/include/cling/Interpreter/Value.h
@@ -10,6 +10,8 @@
 #ifndef CLING_VALUE_H
 #define CLING_VALUE_H
 
+#include <stddef.h>
+
 namespace llvm {
   class raw_ostream;
 }
@@ -101,7 +103,7 @@ namespace cling {
         case kLongDoubleType:
           return (T) V.getAs<long double>();
         case kPointerType:
-          return (T) (unsigned long) V.getAs<void*>();
+          return (T) (size_t) V.getAs<void*>();
         case kUnsupportedType:
           V.AssertOnUnsupportedTypeCast();
         }
@@ -115,7 +117,7 @@ namespace cling {
         EStorageType storageType = V.getStorageType();
         switch (storageType) {
         case kPointerType:
-          return (T*) (unsigned long) V.getAs<void*>();
+          return (T*) (size_t) V.getAs<void*>();
         default:
           V.AssertOnUnsupportedTypeCast(); break;
         }

From 7928499bb68346d001b32924c9e10f3668696b1c Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Sun, 22 Feb 2015 20:17:51 +0100
Subject: [PATCH 025/200] Fix for ROOT-7070 - ROOT does not compile with latest
 Pythia 8 version > 8.2

---
 montecarlo/pythia8/src/TPythia8.cxx | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/montecarlo/pythia8/src/TPythia8.cxx b/montecarlo/pythia8/src/TPythia8.cxx
index e9beb344f8230..4509ba8787059 100644
--- a/montecarlo/pythia8/src/TPythia8.cxx
+++ b/montecarlo/pythia8/src/TPythia8.cxx
@@ -139,7 +139,16 @@ Bool_t TPythia8::Initialize(Int_t idAin, Int_t idBin, Double_t ecms)
 {
    // Initialization
    AddParticlesToPdgDataBase();
-   return fPythia->init(idAin, idBin, ecms);
+
+   // Set arguments in Settings database.
+   fPythia->settings.mode("Beams:idA",  idAin);
+   fPythia->settings.mode("Beams:idB",  idBin);
+   fPythia->settings.mode("Beams:frameType",  1);
+   fPythia->settings.parm("Beams:eCM", ecms);
+
+   return fPythia->init();
+
+   //return fPythia->init(idAin, idBin, ecms);
 }
 
 //___________________________________________________________________________
@@ -147,7 +156,18 @@ Bool_t TPythia8::Initialize(Int_t idAin, Int_t idBin, Double_t eAin, Double_t eB
 {
    // Initialization
    AddParticlesToPdgDataBase();
-   return fPythia->init(idAin, idBin, eAin, eBin);
+
+   // Set arguments in Settings database.
+   fPythia->settings.mode("Beams:idA",  idAin);
+   fPythia->settings.mode("Beams:idB",  idBin);
+   fPythia->settings.mode("Beams:frameType",  2);
+   fPythia->settings.parm("Beams:eA",      eAin);
+   fPythia->settings.parm("Beams:eB",      eBin);
+
+   // Send on to common initialization.
+   return fPythia->init();
+
+   //return fPythia->init(idAin, idBin, eAin, eBin);
 }
 
 //___________________________________________________________________________
@@ -314,7 +334,7 @@ void TPythia8::PlistChanged() const
 void TPythia8::PrintStatistics() const
 {
    // Print end of run statistics
-   fPythia->statistics();
+   fPythia->stat();
 }
 
 //___________________________________________________________________________

From c9bfeea920d3bd548c5e71d7da2b12a341d867d1 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Mon, 23 Feb 2015 15:04:25 +0100
Subject: [PATCH 026/200] Minimal Python is 2.7 due to llvm.

---
 configure | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/configure b/configure
index 10f93fefe8464..ad851ddc67992 100755
--- a/configure
+++ b/configure
@@ -1669,7 +1669,7 @@ enable/disable options, prefix with either --enable- or --disable-
   pgsql              PostgreSQL support, requires libpq
   pythia6            Pythia6 EG support, requires libPythia6
   pythia8            Pythia8 EG support, requires libPythia8 >= 8180
-  python             Python ROOT bindings, requires python >= 2.5
+  python             Python ROOT bindings, requires python >= 2.7
   qt                 Qt graphics backend, requires libqt >= 4.8
   qtgsi              GSI's Qt integration, requires libqt >= 4.8
   rfio               RFIO support, requires libshift from CASTOR >= 1.5.2
@@ -2712,7 +2712,7 @@ fi
 #
 ### echo %%% Check for Python version (required by LLVM/Clang)
 #
-message "Checking for Python version >= 2.5"
+message "Checking for Python version >= 2.7"
 
 if test "x$pythonexe" = "x"; then
   pythonexe=`$cwhich python 2> /dev/null`
@@ -2729,11 +2729,11 @@ pythonvers_minor=`echo $pythonvers | cut -d'.' -f2`
 
 if test  "$pythonvers_major" -gt "2" || \
    (test "$pythonvers_major" -eq "2" && \
-   test "$pythonvers_minor" -ge "5") ; then
+   test "$pythonvers_minor" -ge "7") ; then
   result yes
 else
   result "no"
-  result "`basename $0`: Python >= 2.5 MUST be installed"
+  result "`basename $0`: Python >= 2.7 MUST be installed"
   result "See http://root.cern.ch/drupal/content/build-prerequisites"
   exit 1
 fi

From 1ec7f2c7c39c752586888a87c2a7b608f8130d4b Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Mon, 23 Feb 2015 17:31:29 +0100
Subject: [PATCH 027/200] Add TFormulaTests in CDash

---
 test/CMakeLists.txt    |  4 ++++
 test/TFormulaTests.cxx | 20 ++++++++++++--------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index bdba8a702822e..a8666a7d27f92 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -268,3 +268,7 @@ endif()
 if(ROOT_davix_FOUND)
   ROOT_ADD_TEST(test-stressIOPlugins-http COMMAND stressIOPlugins http FAILREGEX "FAILED|Error in")
 endif()
+
+#--TestTformula------------------------------------------------------------------------------------
+ROOT_EXECUTABLE(TFormulaTests TFormulaTests.cxx LIBRARIES Hist RIO)
+ROOT_ADD_TEST(test-TFormulaTests COMMAND TFormulaTests FAILREGEX "FAILED|Error in")
diff --git a/test/TFormulaTests.cxx b/test/TFormulaTests.cxx
index a05811dfe7b15..51711d7fb45a8 100644
--- a/test/TFormulaTests.cxx
+++ b/test/TFormulaTests.cxx
@@ -79,7 +79,7 @@ Bool_t TFormulaTests::GetParVal()
    for(Int_t i = 0 ; i < Nparams; ++i)
    {
       SDpair param = testParams[i];
-      if(param.second != GetParameter(param.first) || param.second != fParams[param.first].fValue)
+      if(param.second != GetParameter(param.first) )//|| param.second != fParams[param.first].fValue)
       {
          printf("fail:%s\t%lf\n",param.first.Data(), param.second);
          successful = false;
@@ -232,7 +232,7 @@ Bool_t TFormulaTests::SetPars2()
    Bool_t successful = true;
    TFormula *test = new TFormula("SetParsTest2","[0] + [1]+[2]");
    Double_t params[] = { 123,456,789};
-   test->SetParameters(params,3);
+   test->SetParameters(params);
    for(Int_t i = 0; i < 3; ++i)
    {
       if(test->GetParameter(i) != params[i])
@@ -251,7 +251,8 @@ Bool_t TFormulaTests::SetPars1()
    SDpair *params = new SDpair[2];
    params[0] = SDpair("0",1);
    params[1] = SDpair("te_st",2);
-   test->SetParameters(params,2);
+   test->SetParameter(params[0].first,params[0].second);
+   test->SetParameter(params[1].first,params[1].second);
    for(Int_t i = 0 ; i < 2; ++i)
    {
       SDpair p = params[i];
@@ -340,7 +341,7 @@ Bool_t TFormulaTests::Parser()
    for(Int_t i = 0; i < 4; ++i)
    {
       TString param = params[i];
-      if(fParams.find(param) == fVars.end())
+      if(fParams.find(param) == fParams.end())
       {   
          printf("fail:%s\n",param.Data());
          successful = false;
@@ -412,10 +413,11 @@ Bool_t TFormulaTests::Stress(Int_t n)
    // test->AddVariables(vars,n);
    // gBenchmark->Show(TString::Format("Adding %d variables\n",n));
    gBenchmark->Start(TString::Format("Setting %d parameters\n",n*5));
-   test->SetParameters(params,n*5);
+   for (int i = 0; i < n*5; ++i) 
+      test->SetParameter(params[i].first, params[i].second);
    gBenchmark->Show(TString::Format("Setting %d parameters\n",n*5));
 
-   int neval = n*10000;
+   int neval = n*1000;
    gBenchmark->Start(TString::Format("%d Evaluations\n",neval));
    double xx[4] = {3,3,3,3};
    TRandom rndm;
@@ -439,6 +441,7 @@ Bool_t TFormulaTests::Stress(Int_t n)
 
    std::cout << "\n\n Testing old TFormula \n" << endl;
 
+   TFormulaOld::SetMaxima(5000,5000,5000);
 
    gBenchmark->Start(TString::Format("TFormulaOld Initialization with %d variables and %d parameters\n",n,n*5));
    TFormulaOld *testOld = new TFormulaOld("TFStressTestOld",formula);
@@ -487,7 +490,8 @@ int main(int argc, char **argv)
 
 
 
-   testFormula = "x_1- [test]^(TMath::Sin(pi*var*TMath::DegToRad())) - var1pol2(0) + gausn(0)*ylandau(0)+zexpo(10)";
+   //testFormula = "x_1- [test]^(TMath::Sin(pi*var*TMath::DegToRad())) - var1pol2(0) + gausn(0)*ylandau(0)+zexpo(10)";
+   testFormula = "x - [test]^(TMath::Sin(pi*var*TMath::DegToRad())) - var1pol2(0) + gausn(0)*landau(0)+expo(10)";
    TFormulaTests * test = new TFormulaTests("TFtests",testFormula);
 
 #ifdef LATER
@@ -512,7 +516,7 @@ int main(int argc, char **argv)
 
    
    test->AddVariables(testVars,Nvars);
-   test->SetParameters(testParams,Nparams);
+   test->SetParameters(testParams);
 
    printf("Parser test:%s\n",(test->Parser() ? "PASSED" : "FAILED"));
    printf("GetVariableValue test:%s\n",(test->GetVarVal() ? "PASSED" : "FAILED")); 

From fc29cf9afb024b9eb267e3e46940930a82ec9a0a Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Tue, 24 Feb 2015 08:17:41 +0100
Subject: [PATCH 028/200] From T.Hauth: Do not flag as global methods which are
 scoped

---
 core/base/src/TPluginManager.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/base/src/TPluginManager.cxx b/core/base/src/TPluginManager.cxx
index 1738177f27368..bf9236893873b 100644
--- a/core/base/src/TPluginManager.cxx
+++ b/core/base/src/TPluginManager.cxx
@@ -141,7 +141,7 @@ TPluginHandler::TPluginHandler(const char *base, const char *regexp,
    if (validMacro && gROOT->LoadMacro(fPlugin, 0, kTRUE) == 0)
       fIsMacro = kTRUE;
 
-   if (fCtor.Contains("::")) {
+   if (fCtor.BeginsWith("::")) {
       fIsGlobal = kTRUE;
       fCtor = fCtor.Strip(TString::kLeading, ':');
    }

From 8818e72bb7547e2a51ce874346bf302d78300c1a Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Tue, 24 Feb 2015 11:27:52 +0100
Subject: [PATCH 029/200] Proof: fix protocol issue introduced by the last
 patch

Affects standard startups
---
 proof/proof/src/TProof.cxx | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/proof/proof/src/TProof.cxx b/proof/proof/src/TProof.cxx
index 708fe51007739..4f408eff4a42a 100644
--- a/proof/proof/src/TProof.cxx
+++ b/proof/proof/src/TProof.cxx
@@ -1573,7 +1573,7 @@ void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
    dyn.ReplaceAll("\"", " ");
    PDB(kGlobal, 3)
       Info("SetupWorkersEnv", "will invoke AddDynamicPath() on selected workers");
-   AddDynamicPath(dyn, kFALSE, addedWorkers, !fDynamicStartup); // Do not Collect
+   AddDynamicPath(dyn, kFALSE, addedWorkers, kFALSE); // Do not Collect
 
    // Include path
    TString inc = gSystem->GetIncludePath();
@@ -1581,7 +1581,7 @@ void TProof::SetupWorkersEnv(TList *addedWorkers, Bool_t increasingWorkers)
    inc.ReplaceAll("\"", " ");
    PDB(kGlobal, 3)
       Info("SetupWorkersEnv", "will invoke AddIncludePath() on selected workers");
-   AddIncludePath(inc, kFALSE, addedWorkers, !fDynamicStartup);  // Do not Collect
+   AddIncludePath(inc, kFALSE, addedWorkers, kFALSE);  // Do not Collect
 
    // Done
    return;
@@ -9392,10 +9392,11 @@ Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
    m << TString("lib") << (Bool_t)kTRUE;
 
    // Add paths
-   if (libpath && strlen(libpath))
+   if (libpath && strlen(libpath)) {
       m << TString(libpath);
-   else
+   } else {
       m << TString("-");
+   }
 
    // Tell the server to send back or not
    m << (Int_t)doCollect;
@@ -9405,8 +9406,7 @@ Int_t TProof::AddDynamicPath(const char *libpath, Bool_t onClient, TList *wrks,
       Broadcast(m, wrks);
       if (doCollect)
          Collect(wrks, fCollectTimeout);
-   }
-   else {
+   } else {
       Broadcast(m);
       Collect(kActive, fCollectTimeout);
    }
@@ -9437,10 +9437,11 @@ Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
    m << TString("inc") << (Bool_t)kTRUE;
 
    // Add paths
-   if (incpath && strlen(incpath))
+   if (incpath && strlen(incpath)) {
       m << TString(incpath);
-   else
+   } else {
       m << TString("-");
+   }
 
    // Tell the server to send back or not
    m << (Int_t)doCollect;
@@ -9450,8 +9451,7 @@ Int_t TProof::AddIncludePath(const char *incpath, Bool_t onClient, TList *wrks,
       Broadcast(m, wrks);
       if (doCollect)
          Collect(wrks, fCollectTimeout);
-   }
-   else {
+   } else {
       Broadcast(m);
       Collect(kActive, fCollectTimeout);
    }

From cada74fc121f2b42952632c2e4963d9fef0955c9 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Tue, 24 Feb 2015 12:41:19 +0100
Subject: [PATCH 030/200] Avoid useless naming creations if no function
 selection rule is available

or if the function decl represents a class method.
---
 core/metautils/src/SelectionRules.cxx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/core/metautils/src/SelectionRules.cxx b/core/metautils/src/SelectionRules.cxx
index 86efb15583dd5..f08e9d756cba4 100644
--- a/core/metautils/src/SelectionRules.cxx
+++ b/core/metautils/src/SelectionRules.cxx
@@ -480,7 +480,6 @@ bool SelectionRules::GetFunctionPrototype(clang::FunctionDecl* F, std::string& p
       if (prototype != "")
          prototype += ",";
 
-      //type = P->getType().getAsString();
       ROOT::TMetaUtils::GetNormalizedName(type,P->getType(),fInterp,fNormCtxt);
 
       // We need to get rid of the "class " string if present
@@ -867,6 +866,9 @@ const BaseSelectionRule *SelectionRules::IsVarSelected(clang::VarDecl* D, const
 
 const BaseSelectionRule *SelectionRules::IsFunSelected(clang::FunctionDecl *D, const std::string &qual_name) const
 {
+   if (fFunctionSelectionRules.size() == 0 ||
+       llvm::isa<clang::CXXMethodDecl>(D)) return nullptr;
+
    std::string prototype;
    GetFunctionPrototype(D, prototype);
    prototype = qual_name + prototype;
@@ -971,6 +973,9 @@ const BaseSelectionRule *SelectionRules::IsLinkdefVarSelected(clang::VarDecl* D,
 const BaseSelectionRule *SelectionRules::IsLinkdefFunSelected(clang::FunctionDecl* D, const std::string& qual_name) const
 {
 
+   if (fFunctionSelectionRules.size() == 0 ||
+       llvm::isa<clang::CXXMethodDecl>(D)) return nullptr;
+
    std::string prototype;
 
    GetFunctionPrototype(D, prototype);

From 9219906cae4cccdf602c5452cff8a90072077ac6 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Tue, 24 Feb 2015 13:36:34 +0100
Subject: [PATCH 031/200] From V.Innocente: offsets are calculated at
 compiletime

thanks to constexpr functions.
---
 .../inc/Math/MatrixRepresentationsStatic.h    | 181 +++++++-----------
 1 file changed, 70 insertions(+), 111 deletions(-)

diff --git a/math/smatrix/inc/Math/MatrixRepresentationsStatic.h b/math/smatrix/inc/Math/MatrixRepresentationsStatic.h
index d1ec1c5065c28..b84fcf405d581 100644
--- a/math/smatrix/inc/Math/MatrixRepresentationsStatic.h
+++ b/math/smatrix/inc/Math/MatrixRepresentationsStatic.h
@@ -23,6 +23,11 @@
 #include "Math/StaticCheck.h"
 #endif
 
+#include <cstddef>
+#include <utility>
+#include <type_traits>
+#include <array>
+
 namespace ROOT {
 
 namespace Math {
@@ -142,96 +147,49 @@ namespace Math {
       int fOff[D*D];
    };
 
-// Make the lookup tables available at compile time:
-// Add them to a namespace?
-static const int fOff1x1[] = {0};
-static const int fOff2x2[] = {0, 1, 1, 2};
-static const int fOff3x3[] = {0, 1, 3, 1, 2, 4, 3, 4, 5};
-static const int fOff4x4[] = {0, 1, 3, 6, 1, 2, 4, 7, 3, 4, 5, 8, 6, 7, 8, 9};
-static const int fOff5x5[] = {0, 1, 3, 6, 10, 1, 2, 4, 7, 11, 3, 4, 5, 8, 12, 6, 7, 8, 9, 13, 10, 11, 12, 13, 14};
-static const int fOff6x6[] = {0, 1, 3, 6, 10, 15, 1, 2, 4, 7, 11, 16, 3, 4, 5, 8, 12, 17, 6, 7, 8, 9, 13, 18, 10, 11, 12, 13, 14, 19, 15, 16, 17, 18, 19, 20};
+  namespace rowOffsetsUtils {
 
-static const int fOff7x7[] = {0, 1, 3, 6, 10, 15, 21, 1, 2, 4, 7, 11, 16, 22, 3, 4, 5, 8, 12, 17, 23, 6, 7, 8, 9, 13, 18, 24, 10, 11, 12, 13, 14, 19, 25, 15, 16, 17, 18, 19, 20, 26, 21, 22, 23, 24, 25, 26, 27};
+    ///////////
+    // Some meta template stuff
+    template<int...> struct indices{};
 
-static const int fOff8x8[] = {0, 1, 3, 6, 10, 15, 21, 28, 1, 2, 4, 7, 11, 16, 22, 29, 3, 4, 5, 8, 12, 17, 23, 30, 6, 7, 8, 9, 13, 18, 24, 31, 10, 11, 12, 13, 14, 19, 25, 32, 15, 16, 17, 18, 19, 20, 26, 33, 21, 22, 23, 24, 25, 26, 27, 34, 28, 29, 30, 31, 32, 33, 34, 35};
+    template<int I, class IndexTuple, int N>
+    struct make_indices_impl;
 
-static const int fOff9x9[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 1, 2, 4, 7, 11, 16, 22, 29, 37, 3, 4, 5, 8, 12, 17, 23, 30, 38, 6, 7, 8, 9, 13, 18, 24, 31, 39, 10, 11, 12, 13, 14, 19, 25, 32, 40, 15, 16, 17, 18, 19, 20, 26, 33, 41, 21, 22, 23, 24, 25, 26, 27, 34, 42, 28, 29, 30, 31, 32, 33, 34, 35, 43, 36, 37, 38, 39, 40, 41, 42, 43, 44};
+    template<int I, int... Indices, int N>
+    struct make_indices_impl<I, indices<Indices...>, N>
+    {
+      typedef typename make_indices_impl<I + 1, indices<Indices..., I>,
+					 N>::type type;
+    };
 
-static const int fOff10x10[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 3, 4, 5, 8, 12, 17, 23, 30, 38, 47, 6, 7, 8, 9, 13, 18, 24, 31, 39, 48, 10, 11, 12, 13, 14, 19, 25, 32, 40, 49, 15, 16, 17, 18, 19, 20, 26, 33, 41, 50, 21, 22, 23, 24, 25, 26, 27, 34, 42, 51, 28, 29, 30, 31, 32, 33, 34, 35, 43, 52, 36, 37, 38, 39, 40, 41, 42, 43, 44, 53, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54};
+    template<int N, int... Indices>
+    struct make_indices_impl<N, indices<Indices...>, N> {
+      typedef indices<Indices...> type;
+    };
 
-template<>
-   struct RowOffsets<1> {
-      RowOffsets() {}
-      int operator()(unsigned int , unsigned int ) const { return 0; } // Just one element
-      int apply(unsigned int ) const { return 0; }
-   };
+    template<int N>
+    struct make_indices : make_indices_impl<0, indices<>, N> {};
+    // end of stuff
 
-template<>
-   struct RowOffsets<2> {
-      RowOffsets() {}
-      int operator()(unsigned int i, unsigned int j) const { return i+j; /*fOff2x2[i*2+j];*/ }
-      int apply(unsigned int i) const { return fOff2x2[i]; }
-   };
 
-template<>
-   struct RowOffsets<3> {
-      RowOffsets() {}
-      int operator()(unsigned int i, unsigned int j) const { return fOff3x3[i*3+j]; }
-      int apply(unsigned int i) const { return fOff3x3[i]; }
-   };
 
-template<>
-   struct RowOffsets<4> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff4x4[i*4+j]; }
-     int apply(unsigned int i) const { return fOff4x4[i]; }
-   };
+    template<int I0, class F, int... I>
+    constexpr std::array<decltype(std::declval<F>()(std::declval<int>())), sizeof...(I)>
+    do_make(F f, indices<I...>)
+    {
+      return  std::array<decltype(std::declval<F>()(std::declval<int>())),
+			 sizeof...(I)>{{ f(I0 + I)... }};
+    }
 
-   template<>
-   struct RowOffsets<5> {
-     inline RowOffsets() {}
-     inline int operator()(unsigned int i, unsigned int j) const { return fOff5x5[i*5+j]; }
-//   int operator()(unsigned int i, unsigned int j) const {
-//     if(j <= i) return (i * (i + 1)) / 2 + j;
-//      else return (j * (j + 1)) / 2 + i;
-//     }
-   inline int apply(unsigned int i) const { return fOff5x5[i]; }
-   };
+    template<int N, int I0 = 0, class F>
+    constexpr std::array<decltype(std::declval<F>()(std::declval<int>())), N>
+    make(F f) {
+      return do_make<I0>(f, typename make_indices<N>::type());
+    }
 
-template<>
-   struct RowOffsets<6> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff6x6[i*6+j]; }
-     int apply(unsigned int i) const { return fOff6x6[i]; }
-   };
+  } // namespace rowOffsetsUtils
 
-template<>
-   struct RowOffsets<7> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff7x7[i*7+j]; }
-     int apply(unsigned int i) const { return fOff7x7[i]; }
-   };
-
-template<>
-   struct RowOffsets<8> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff8x8[i*8+j]; }
-     int apply(unsigned int i) const { return fOff8x8[i]; }
-   };
-
-template<>
-   struct RowOffsets<9> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff9x9[i*9+j]; }
-     int apply(unsigned int i) const { return fOff9x9[i]; }
-   };
-
-template<>
-   struct RowOffsets<10> {
-     RowOffsets() {}
-     int operator()(unsigned int i, unsigned int j) const { return fOff10x10[i*10+j]; }
-     int apply(unsigned int i) const { return fOff10x10[i]; }
-   };
 
 //_________________________________________________________________________________
    /**
@@ -257,35 +215,32 @@ template<>
 
    public:
 
-      MatRepSym() :fOff(0) { CreateOffsets(); }
+    /* constexpr */ inline MatRepSym(){}
 
-      typedef T  value_type;
+    typedef T  value_type;
 
-      inline const T& operator()(unsigned int i, unsigned int j) const {
-         return fArray[Offsets()(i,j)];
-      }
-      inline T& operator()(unsigned int i, unsigned int j) {
-         return fArray[Offsets()(i,j)];
-      }
 
-      inline T& operator[](unsigned int i) {
-         return fArray[Offsets().apply(i) ];
-//return fArray[Offsets()(i/D, i%D)];
-      }
+    inline T & operator()(unsigned int i, unsigned int j)
+     { return fArray[offset(i, j)]; }
 
-      inline const T& operator[](unsigned int i) const {
-         return fArray[Offsets().apply(i) ];
-//return fArray[Offsets()(i/D, i%D)];
-      }
+     inline /* constexpr */ T const & operator()(unsigned int i, unsigned int j) const
+     { return fArray[offset(i, j)]; }
 
-      inline T apply(unsigned int i) const {
-         return fArray[Offsets().apply(i) ];
-         //return operator()(i/D, i%D);
-      }
+     inline T& operator[](unsigned int i) {
+       return fArray[off(i)];
+     }
 
-      inline T* Array() { return fArray; }
+     inline /* constexpr */ T const & operator[](unsigned int i) const {
+       return fArray[off(i)];
+     }
 
-      inline const T* Array() const { return fArray; }
+     inline /* constexpr */ T apply(unsigned int i) const {
+       return fArray[off(i)];
+     }
+
+     inline T* Array() { return fArray; }
+
+     inline const T* Array() const { return fArray; }
 
       /**
          assignment : only symmetric to symmetric allowed
@@ -346,22 +301,26 @@ template<>
          kSize = D*(D+1)/2
       };
 
+     static constexpr int off0(int i) { return i==0 ? 0 : off0(i-1)+i;}
+     static constexpr int off2(int i, int j) { return j<i ? off0(i)+j : off0(j)+i; }
+     static constexpr int off1(int i) { return off2(i/D, i%D);}
 
-      void CreateOffsets() {
-         const static RowOffsets<D> off;
-         fOff = &off;
-      }
+     static int off(int i) {
+       static constexpr auto v = rowOffsetsUtils::make<D*D>(off1);
+       return v[i];
+     }
 
-      inline const RowOffsets<D> & Offsets() const {
-         return *fOff;
-      }
+     static inline constexpr unsigned int
+     offset(unsigned int i, unsigned int j)
+     {
+       //if (j > i) std::swap(i, j);
+       return off(i*D+j);
+       // return (i>j) ? (i * (i+1) / 2) + j :  (j * (j+1) / 2) + i;
+     }
 
    private:
       //T __attribute__ ((aligned (16))) fArray[kSize];
       T fArray[kSize];
-
-      const RowOffsets<D> * fOff;   //! transient
-
    };
 
 

From 84cd21426c17700955a0bd764f7db0919ae76948 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Tue, 24 Feb 2015 13:39:54 +0100
Subject: [PATCH 032/200] From V.Innocente: Allow to construct SMatrices w/o
 initialisation

of the matrix elements. This is a performance optimisation.
---
 math/smatrix/inc/Math/SMatrix.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/math/smatrix/inc/Math/SMatrix.h b/math/smatrix/inc/Math/SMatrix.h
index 25ad7550185d4..4ad35f2c8c187 100644
--- a/math/smatrix/inc/Math/SMatrix.h
+++ b/math/smatrix/inc/Math/SMatrix.h
@@ -97,6 +97,7 @@ namespace Math {
 template <class T, unsigned int D> class SVector;
 
 struct SMatrixIdentity { };
+struct SMatrixNoInit { };
 
 //__________________________________________________________________________
 /**
@@ -149,6 +150,11 @@ class SMatrix {
    */
    SMatrix();
    ///
+  /**
+       construct from without initialization
+   */
+   inline SMatrix( SMatrixNoInit ){}
+
    /**
        construct from an identity matrix
    */

From 5180beaf0be05bd0183e612be6c445513761ee5f Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Tue, 24 Feb 2015 14:29:28 +0100
Subject: [PATCH 033/200] Fix parsing the cut name in TH2::ProjectionX/Y and
 TH2::ProfileX/Y (Fix ROOT-7097)

---
 hist/hist/src/TH2.cxx | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/hist/hist/src/TH2.cxx b/hist/hist/src/TH2.cxx
index e5d002c358953..f11a6da89e5dc 100644
--- a/hist/hist/src/TH2.cxx
+++ b/hist/hist/src/TH2.cxx
@@ -519,7 +519,7 @@ void TH2::FillN(Int_t ntimes, const Double_t *x, const Double_t *y, const Double
    Int_t binx, biny, bin, i;
    ntimes *= stride;
    Int_t ifirst = 0;
-   
+
    //If a buffer is activated, fill buffer
    // (note that this function must not be called from TH2::BufferEmpty)
    if (fBuffer) {
@@ -528,13 +528,13 @@ void TH2::FillN(Int_t ntimes, const Double_t *x, const Double_t *y, const Double
          if (w) BufferFill(x[i],y[i],w[i]);
          else BufferFill(x[i], y[i], 1.);
       }
-      // fill the remaining entries if the buffer has been deleted 
-      if (i < ntimes && fBuffer==0) 
+      // fill the remaining entries if the buffer has been deleted
+      if (i < ntimes && fBuffer==0)
          ifirst = i;
       else
          return;
    }
-   
+
    Double_t ww = 1;
    for (i=ifirst;i<ntimes;i+=stride) {
       fEntries++;
@@ -1956,6 +1956,13 @@ TH2 *TH2::Rebin2D(Int_t nxgroup, Int_t nygroup, const char *newname)
 TProfile *TH2::DoProfile(bool onX, const char *name, Int_t firstbin, Int_t lastbin, Option_t *option) const
 {
    TString opt = option;
+   // extract cut infor
+   TString cut;
+   Int_t i1 = opt.Index("[");
+   if (i1>=0) {
+      Int_t i2 = opt.Index("]");
+      cut = opt(i1,i2-i1+1);
+   }
    opt.ToLower();
    bool originalRange = opt.Contains("o");
 
@@ -2026,9 +2033,8 @@ TProfile *TH2::DoProfile(bool onX, const char *name, Int_t firstbin, Int_t lastb
    Int_t ncuts = 0;
    if (opt.Contains("[")) {
       ((TH2 *)this)->GetPainter();
-      if (fPainter) ncuts = fPainter->MakeCuts((char*)opt.Data());
+      if (fPainter) ncuts = fPainter->MakeCuts((char*)cut.Data());
    }
-   opt.ToLower();  //must be called after MakeCuts
 
    if (!h1) {
       const TArrayD *bins = outAxis.GetXbins();
@@ -2227,9 +2233,14 @@ TH1D *TH2::DoProjection(bool onX, const char *name, Int_t firstbin, Int_t lastbi
    const TAxis* outAxis;
    const TAxis* inAxis;
 
-
    TString opt = option;
-   opt.ToLower();  //must be called after MakeCuts
+   TString cut;
+   Int_t i1 = opt.Index("[");
+   if (i1>=0) {
+      Int_t i2 = opt.Index("]");
+      cut = opt(i1,i2-i1+1);
+   }
+   opt.ToLower();  //must be called after having parsed the cut name
    bool originalRange = opt.Contains("o");
 
    if ( onX )
@@ -2253,7 +2264,6 @@ TH1D *TH2::DoProjection(bool onX, const char *name, Int_t firstbin, Int_t lastbi
       firstOutBin = 1; lastOutBin = outAxis->GetNbins();
    }
 
-
    if ( lastbin < firstbin && inAxis->TestBit(TAxis::kAxisRange) ) {
       firstbin = inAxis->GetFirst();
       lastbin = inAxis->GetLast();
@@ -2310,7 +2320,7 @@ TH1D *TH2::DoProjection(bool onX, const char *name, Int_t firstbin, Int_t lastbi
    Int_t ncuts = 0;
    if (opt.Contains("[")) {
       ((TH2 *)this)->GetPainter();
-      if (fPainter) ncuts = fPainter->MakeCuts((char*)opt.Data());
+      if (fPainter) ncuts = fPainter->MakeCuts((char*)cut.Data());
    }
 
    if (!h1) {

From beb7a93080cf2615085147b6630f4e18923dba23 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 11:14:36 +0100
Subject: [PATCH 034/200] Enable asm parser in cling

Use PROJECT_SOURCE_DIR (full path to the root of the project source directory) instead of CMAKE_SOURCE_DIR (the directory from which cmake was started) in order to properly find AsmParser/CMakeLists.txt and call llvm::InitializeNativeTargetAsmParser();
---
 interpreter/cling/lib/Interpreter/CIFactory.cpp | 1 +
 interpreter/llvm/src/cmake/config-ix.cmake      | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp
index 4b5b6fa8c848d..b3b896c978ee5 100644
--- a/interpreter/cling/lib/Interpreter/CIFactory.cpp
+++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp
@@ -496,6 +496,7 @@ namespace {
 
     //  Initialize the llvm library.
     llvm::InitializeNativeTarget();
+    llvm::InitializeNativeTargetAsmParser();
     llvm::InitializeNativeTargetAsmPrinter();
     llvm::SmallString<512> resource_path;
     if (llvmdir) {
diff --git a/interpreter/llvm/src/cmake/config-ix.cmake b/interpreter/llvm/src/cmake/config-ix.cmake
index c845c070ecd0e..035dd676f7387 100755
--- a/interpreter/llvm/src/cmake/config-ix.cmake
+++ b/interpreter/llvm/src/cmake/config-ix.cmake
@@ -396,12 +396,12 @@ else ()
   set(LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter)
 
   # We don't have an ASM parser for all architectures yet.
-  if (EXISTS ${CMAKE_SOURCE_DIR}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/CMakeLists.txt)
+  if (EXISTS ${PROJECT_SOURCE_DIR}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/CMakeLists.txt)
     set(LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser)
   endif ()
 
   # We don't have an disassembler for all architectures yet.
-  if (EXISTS ${CMAKE_SOURCE_DIR}/lib/Target/${LLVM_NATIVE_ARCH}/Disassembler/CMakeLists.txt)
+  if (EXISTS ${PROJECT_SOURCE_DIR}/lib/Target/${LLVM_NATIVE_ARCH}/Disassembler/CMakeLists.txt)
     set(LLVM_NATIVE_DISASSEMBLER LLVMInitialize${LLVM_NATIVE_ARCH}Disassembler)
   endif ()
 endif ()
@@ -511,7 +511,7 @@ else()
   if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
     message(STATUS "Go bindings disabled.")
   else()
-    execute_process(COMMAND ${GO_EXECUTABLE} run ${CMAKE_SOURCE_DIR}/bindings/go/conftest.go
+    execute_process(COMMAND ${GO_EXECUTABLE} run ${PROJECT_SOURCE_DIR}/bindings/go/conftest.go
                     RESULT_VARIABLE GO_CONFTEST)
     if(GO_CONFTEST STREQUAL "0")
       set(LLVM_BINDINGS "${LLVM_BINDINGS} go")

From be7a097501918788ffcb5e37d55b2cbd9b1c27e3 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 11:33:22 +0100
Subject: [PATCH 035/200] Re-introduce the definition of "struct timespec" for
 Windows

---
 core/base/inc/TTimeStamp.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/core/base/inc/TTimeStamp.h b/core/base/inc/TTimeStamp.h
index 17737b395306a..7c84db3d61fcd 100644
--- a/core/base/inc/TTimeStamp.h
+++ b/core/base/inc/TTimeStamp.h
@@ -48,6 +48,13 @@
 
 #include <ctime>
 
+#ifdef R__WIN32
+struct timespec {
+   time_t   tv_sec;  // seconds
+   long     tv_nsec; // nanoseconds
+};
+#endif
+
 // For backward compatibility
 typedef struct timespec timespec_t;
 typedef struct tm       tm_t;

From d5f8555a1be03edab412bb87a0cdbf83bbe8df84 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 11:52:28 +0100
Subject: [PATCH 036/200] Add flag to prevent #error: The C++ Standard Library
 forbids macroizing keywords.

---
 cmake/modules/SearchInstalledSoftware.cmake | 2 +-
 cmake/modules/SetUpWindows.cmake            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmake/modules/SearchInstalledSoftware.cmake b/cmake/modules/SearchInstalledSoftware.cmake
index 0a6f1a73d8322..b9ca1793e2892 100644
--- a/cmake/modules/SearchInstalledSoftware.cmake
+++ b/cmake/modules/SearchInstalledSoftware.cmake
@@ -656,7 +656,7 @@ if(cling)
 
   set(CLING_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/interpreter/cling/include)
   if(MSVC)
-    set(CLING_CXXFLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DNOMINMAX")
+    set(CLING_CXXFLAGS "-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DNOMINMAX -D_XKEYCHECK_H")
   else()
     set(CLING_CXXFLAGS "-fvisibility-inlines-hidden -fno-strict-aliasing -Wno-unused-parameter -Wwrite-strings -Wno-long-long -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS")
   endif()
diff --git a/cmake/modules/SetUpWindows.cmake b/cmake/modules/SetUpWindows.cmake
index 8adc20131ff08..c2509eaea5944 100644
--- a/cmake/modules/SetUpWindows.cmake
+++ b/cmake/modules/SetUpWindows.cmake
@@ -63,7 +63,7 @@ elseif(MSVC)
   endif()
 
   if(CMAKE_PROJECT_NAME STREQUAL ROOT)
-    set(CMAKE_CXX_FLAGS "-nologo -I${CMAKE_SOURCE_DIR}/build/win -FIw32pragma.h -FIsehmap.h ${BLDCXXFLAGS} -EHsc- -W3 -wd4244 -D_WIN32")
+    set(CMAKE_CXX_FLAGS "-nologo -I${CMAKE_SOURCE_DIR}/build/win -FIw32pragma.h -FIsehmap.h ${BLDCXXFLAGS} -EHsc- -W3 -wd4244 -D_WIN32 -D_XKEYCHECK_H")
     set(CMAKE_C_FLAGS   "-nologo -I${CMAKE_SOURCE_DIR}/build/win -FIw32pragma.h -FIsehmap.h ${BLDCFLAGS} -EHsc- -W3 -D_WIN32")
     install(FILES ${CMAKE_SOURCE_DIR}/build/win/w32pragma.h  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT headers)
     install(FILES ${CMAKE_SOURCE_DIR}/build/win/sehmap.h  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT headers)

From d87a2457306c8d2567861e805e925282c434f30b Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 12:09:58 +0100
Subject: [PATCH 037/200] Prevent oaidl.h:473:31: error: cannot combine with
 previous 'type-name' declaration specifier ( _VARIANT_BOOL bool; )

---
 core/base/inc/Windows4Root.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/core/base/inc/Windows4Root.h b/core/base/inc/Windows4Root.h
index 658836f38cd90..2bdedeb67b081 100644
--- a/core/base/inc/Windows4Root.h
+++ b/core/base/inc/Windows4Root.h
@@ -29,9 +29,11 @@
 
 #ifndef __CINT__
 
+#ifdef __CLING__
+#define WIN32_LEAN_AND_MEAN
+#endif
 #include <windows.h>
 
-
 #undef OpenSemaphore
 
 #undef RemoveDirectory

From 91c4628ccaef5079d9eff8e6d5345dc1045c87d4 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:26:48 +0100
Subject: [PATCH 038/200] Add missing #define R__NULLPTR

---
 core/base/inc/RConfig.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/base/inc/RConfig.h b/core/base/inc/RConfig.h
index 7ec4a575b4930..c7556f0209355 100644
--- a/core/base/inc/RConfig.h
+++ b/core/base/inc/RConfig.h
@@ -371,6 +371,7 @@
 #   define R__VECNEWDELETE    /* supports overloading of new[] and delete[] */
 #   define R__PLACEMENTDELETE /* supports overloading placement delete */
 #   define R__PLACEMENTINLINE /* placement new/delete is inline in <new> */
+#   define R__NULLPTR
 #   if _MSC_VER >= 1400
 #     define DONTNEED_VSNPRINTF
 #   endif

From 672dd0cb84e8a431ba72474ac15a2e0d7641e8cf Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:37:14 +0100
Subject: [PATCH 039/200] Fix compilation error C2483: 'buf' : object with
 constructor or destructor cannot be declared 'thread'

---
 core/meta/src/TClingClassInfo.cxx | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/core/meta/src/TClingClassInfo.cxx b/core/meta/src/TClingClassInfo.cxx
index 5878ff458f1a6..5e3d5e342b579 100644
--- a/core/meta/src/TClingClassInfo.cxx
+++ b/core/meta/src/TClingClassInfo.cxx
@@ -1283,7 +1283,11 @@ const char *TClingClassInfo::Name() const
       return 0;
    }
    // Note: This *must* be static/thread_local because we are returning a pointer inside it!
+#ifdef R__WIN32
+   static std::string buf;
+#else
    thread_local std::string buf;
+#endif
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {
       PrintingPolicy Policy(fDecl->getASTContext().getPrintingPolicy());
@@ -1342,7 +1346,11 @@ const char *TClingClassInfo::TmpltName() const
    R__LOCKGUARD(gInterpreterMutex);
 
    // Note: This *must* be static/thread_local because we are returning a pointer inside it!
+#ifdef R__WIN32
+   static std::string buf;
+#else
    thread_local std::string buf;
+#endif
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {
       // Note: This does *not* include the template arguments!

From 4593bafbf0cf19029d4c248068cc2509c012601d Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:39:07 +0100
Subject: [PATCH 040/200] Prevent "error C++ template support is insufficient
 (member function template)" with rootcling on Windows

---
 io/io/inc/TStreamerInfo.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/io/io/inc/TStreamerInfo.h b/io/io/inc/TStreamerInfo.h
index 49f370483320b..087b1c29e0032 100644
--- a/io/io/inc/TStreamerInfo.h
+++ b/io/io/inc/TStreamerInfo.h
@@ -32,7 +32,7 @@
 
 #include "TVirtualCollectionProxy.h"
 
-#if (defined(_MSC_VER) && (_MSC_VER < 1300)) || defined(R__ALPHA) || \
+#if (defined(_MSC_VER) && (_MSC_VER < 1300) && !defined (__CLING__)) || defined(R__ALPHA) || \
     (defined(R__MACOSX) && defined(R__GNU) && __GNUC__==3 && __GNUC_MINOR__<=3) || \
     (defined(R__MACOSX) && defined(__xlC__))
 #error C++ template support is insufficient (member function template)

From 1299b859f86854e2cc79e414d37687de4969cfd0 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:43:57 +0100
Subject: [PATCH 041/200] Fix compilation error on Windows

---
 core/metautils/src/RConversionRuleParser.cxx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/metautils/src/RConversionRuleParser.cxx b/core/metautils/src/RConversionRuleParser.cxx
index 8419191b1fa3f..f6a34781265e8 100644
--- a/core/metautils/src/RConversionRuleParser.cxx
+++ b/core/metautils/src/RConversionRuleParser.cxx
@@ -15,9 +15,9 @@
 namespace {
    static void RemoveEscapeSequences(std::string& rawString)
    {
-      const std::vector<std::pair<const std::string, const std::string>> subPairs { {"\\\\","\\"},
-                                                                                    {"\\\"","\""},
-                                                                                    {"\\\'","\'"}};
+      const std::vector<std::pair<std::string, std::string>> subPairs { {"\\\\","\\"},
+                                                                        {"\\\"","\""},
+                                                                        {"\\\'","\'"}};
       size_t start_pos = 0;
       for (auto const & subPair : subPairs){
          start_pos = 0;

From bb6361aaaca88c697aead022a9b03a119bc69341 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:45:46 +0100
Subject: [PATCH 042/200] Add missing clang namespace (fix compilation error on
 Windows)

---
 core/metautils/src/TMetaUtils.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx
index 0d043a9471093..54e61407d8915 100644
--- a/core/metautils/src/TMetaUtils.cxx
+++ b/core/metautils/src/TMetaUtils.cxx
@@ -4325,7 +4325,7 @@ clang::QualType ROOT::TMetaUtils::ReSubstTemplateArg(clang::QualType input, cons
 
    // In case of Int_t* we need to strip the pointer first, ReSubst and attach
    // the pointer once again.
-   if (isa<PointerType>(QT.getTypePtr())) {
+   if (isa<clang::PointerType>(QT.getTypePtr())) {
       // Get the qualifiers.
       Qualifiers quals = QT.getQualifiers();
       QualType nQT;
@@ -4360,7 +4360,7 @@ clang::QualType ROOT::TMetaUtils::ReSubstTemplateArg(clang::QualType input, cons
 
    // In case of Int_t[2] we need to strip the array first, ReSubst and attach
    // the array once again.
-   if (isa<ArrayType>(QT.getTypePtr())) {
+   if (isa<clang::ArrayType>(QT.getTypePtr())) {
       // Get the qualifiers.
       Qualifiers quals = QT.getQualifiers();
 

From 5397cba2197733b26b7bb039ad684b0fde830db7 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:48:21 +0100
Subject: [PATCH 043/200] Use "copy /y" command instead of "ln -f" on Windows

---
 core/utils/CMakeLists.txt | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt
index 65e23ccb93991..2e592ab7a802e 100644
--- a/core/utils/CMakeLists.txt
+++ b/core/utils/CMakeLists.txt
@@ -34,10 +34,17 @@ ROOT_EXECUTABLE(rootcling src/LinkdefReader.cxx src/DictSelectionReader.cxx
 
 add_dependencies(rootcling CLING LLVMRES)
 
-add_custom_command(TARGET rootcling POST_BUILD
-                   COMMAND ln -f rootcling rootcint
-                   COMMAND ln -f rootcling genreflex
-                   WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+if(WIN32)
+  add_custom_command(TARGET rootcling POST_BUILD
+                     COMMAND ln -f rootcling rootcint
+                     COMMAND ln -f rootcling genreflex
+                     WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+else()
+  add_custom_command(TARGET rootcling POST_BUILD
+                     COMMAND copy /y rootcling rootcint
+                     COMMAND copy /y rootcling genreflex
+                     WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+endif()
 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
                          "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/rootcint;${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/genreflex")
 

From 425c5644875a200c78c6976e03351ef5e3bf099d Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 14:54:33 +0100
Subject: [PATCH 044/200] Exchange the Windows/Linux commands

---
 core/utils/CMakeLists.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt
index 2e592ab7a802e..8cef6fbe462ec 100644
--- a/core/utils/CMakeLists.txt
+++ b/core/utils/CMakeLists.txt
@@ -36,13 +36,13 @@ add_dependencies(rootcling CLING LLVMRES)
 
 if(WIN32)
   add_custom_command(TARGET rootcling POST_BUILD
-                     COMMAND ln -f rootcling rootcint
-                     COMMAND ln -f rootcling genreflex
+                     COMMAND copy /y rootcling rootcint
+                     COMMAND copy /y rootcling genreflex
                      WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
 else()
   add_custom_command(TARGET rootcling POST_BUILD
-                     COMMAND copy /y rootcling rootcint
-                     COMMAND copy /y rootcling genreflex
+                     COMMAND ln -f rootcling rootcint
+                     COMMAND ln -f rootcling genreflex
                      WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
 endif()
 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES

From 2e9fad3001517c5b123e648b99253fb068bc641d Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 15:46:40 +0100
Subject: [PATCH 045/200] Properly implement (and use) type_info (which is not
 part of the std namespace when _HAS_EXCEPTIONS=0) on Windows (thanks to Axel)

---
 core/base/inc/Rtypeinfo.h           | 8 ++++++++
 core/meta/inc/TEnum.h               | 5 +++--
 core/meta/inc/TInterpreter.h        | 5 ++++-
 core/meta/src/TCling.cxx            | 3 ++-
 core/meta/src/TCling.h              | 4 +++-
 io/io/inc/TCollectionProxyFactory.h | 5 ++++-
 io/io/inc/TGenCollectionProxy.h     | 5 ++++-
 7 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/core/base/inc/Rtypeinfo.h b/core/base/inc/Rtypeinfo.h
index 95227b0bf8859..98cb2840343a3 100644
--- a/core/base/inc/Rtypeinfo.h
+++ b/core/base/inc/Rtypeinfo.h
@@ -27,6 +27,14 @@ using std::type_info;
 
 #include <typeinfo>
 
+#elif defined(R__WIN32)
+
+// only has ::type_info without _HAS_EXCEPTIONS!
+#include <typeinfo>
+#if ! _HAS_EXCEPTIONS
+namespace std { using ::type_info; }
+#endif
+
 #else
 
 #include <typeinfo>
diff --git a/core/meta/inc/TEnum.h b/core/meta/inc/TEnum.h
index bc7f4cd201ce3..6a4797f89d3e8 100644
--- a/core/meta/inc/TEnum.h
+++ b/core/meta/inc/TEnum.h
@@ -32,8 +32,9 @@
 #ifndef ROOT_TDictionary
 #include "TDictionary.h"
 #endif
-
-#include <typeinfo>
+#ifndef ROOT_Rtypeinfo
+#include "Rtypeinfo.h"
+#endif
 
 class TClass;
 class TEnumConstant;
diff --git a/core/meta/inc/TInterpreter.h b/core/meta/inc/TInterpreter.h
index c676b32e9f69b..2050ed5e30a97 100644
--- a/core/meta/inc/TInterpreter.h
+++ b/core/meta/inc/TInterpreter.h
@@ -30,7 +30,10 @@
 #include "TVirtualMutex.h"
 #endif
 
-#include <typeinfo>
+#ifndef ROOT_Rtypeinfo
+#include "Rtypeinfo.h"
+#endif
+
 #include <vector>
 
 class TClass;
diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index 0990291e6127b..4313dce265cc2 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -178,6 +178,7 @@ char *dlerror() {
                  sizeof(Msg), NULL);
    return Msg;
 }
+#define thread_local static __declspec(thread)
 #endif
 #endif
 
@@ -4774,7 +4775,7 @@ TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
 }
 
 //______________________________________________________________________________
-Int_t TCling::AutoLoad(const type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
+Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
 {
    // Load library containing the specified class. Returns 0 in case of error
    // and 1 in case if success.
diff --git a/core/meta/src/TCling.h b/core/meta/src/TCling.h
index c2452527a2f7d..225e0d49dc111 100644
--- a/core/meta/src/TCling.h
+++ b/core/meta/src/TCling.h
@@ -27,10 +27,12 @@
 #ifndef ROOT_TInterpreter
 #include "TInterpreter.h"
 #endif
+#ifndef ROOT_Rtypeinfo
+#include "Rtypeinfo.h"
+#endif
 
 #include <set>
 #include <unordered_set>
-#include <typeinfo>
 #include <map>
 #include <vector>
 
diff --git a/io/io/inc/TCollectionProxyFactory.h b/io/io/inc/TCollectionProxyFactory.h
index 245cce9577675..1b76716fc6ed9 100644
--- a/io/io/inc/TCollectionProxyFactory.h
+++ b/io/io/inc/TCollectionProxyFactory.h
@@ -18,7 +18,10 @@
 //
 //////////////////////////////////////////////////////////////////////////
 
-#include <typeinfo>
+#ifndef ROOT_Rtypeinfo
+#include "Rtypeinfo.h"
+#endif
+
 #include <vector>
 
 #ifndef ROOT_TCollectionProxyInfo
diff --git a/io/io/inc/TGenCollectionProxy.h b/io/io/inc/TGenCollectionProxy.h
index b0d760ab96b62..31263123ab948 100644
--- a/io/io/inc/TGenCollectionProxy.h
+++ b/io/io/inc/TGenCollectionProxy.h
@@ -33,7 +33,10 @@
 #include "TCollectionProxyInfo.h"
 #endif
 
-#include <typeinfo>
+#ifndef ROOT_Rtypeinfo
+#include "Rtypeinfo.h"
+#endif
+
 #include <string>
 #include <map>
 #ifndef __CINT__

From 314b20bf3f304806ad73f56a1676000804465658 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Wed, 25 Feb 2015 15:55:29 +0100
Subject: [PATCH 046/200] Say where the .x function comes from.

---
 interpreter/cling/lib/MetaProcessor/MetaSema.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/interpreter/cling/lib/MetaProcessor/MetaSema.cpp b/interpreter/cling/lib/MetaProcessor/MetaSema.cpp
index 2932904c3f114..befc7626e81c6 100644
--- a/interpreter/cling/lib/MetaProcessor/MetaSema.cpp
+++ b/interpreter/cling/lib/MetaProcessor/MetaSema.cpp
@@ -102,6 +102,8 @@ namespace cling {
 
       StringRefPair pairFuncExt = pairPathFile.second.rsplit('.');
       std::string expression = pairFuncExt.first.str() + "(" + args.str() + ")";
+      // Give the user some context in case we have a problem in an invocation.
+      expression += " /* invoking function corresponding to '.x' */";
 
       assert(T);
 

From a977b08f7a512b684ef67c1b90b2054f8504410c Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 16:54:21 +0100
Subject: [PATCH 047/200] Make rootcling working on Windows, and let it produce
 dictionary files that compile with Visual C++

Use std::atomic load() method to access its content. I.e. (!fgIsA) is not a valid test on Windows, but (!fgIsA.load()) is.
---
 core/utils/src/rootcling.cxx | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/core/utils/src/rootcling.cxx b/core/utils/src/rootcling.cxx
index 22a4c1b8b90bb..3043342965961 100644
--- a/core/utils/src/rootcling.cxx
+++ b/core/utils/src/rootcling.cxx
@@ -379,6 +379,10 @@ static void GetCurrentDirectory(std::string &output)
 
    output = currWorkDir;
    output += '/';
+#ifdef WIN32
+   // convert backslashes into forward slashes
+   std::replace(output.begin(), output.end(), '\\', '/');
+#endif
 
    if (fixedLength != currWorkDir) {
       delete [] currWorkDir;
@@ -1423,7 +1427,7 @@ void WriteClassFunctions(const clang::CXXRecordDecl *cl, std::ostream &dictStrea
    if (autoLoad) {
       dictStream << "   Dictionary();\n";
    } else {
-      dictStream << "   if (!fgIsA) { R__LOCKGUARD2(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
+      dictStream << "   if (!fgIsA.load()) { R__LOCKGUARD2(gInterpreterMutex); fgIsA = ::ROOT::GenerateInitInstanceLocal((const ::";
       dictStream << fullname << "*)0x0)->GetClass(); }" << std::endl;
    }
    dictStream    << "   return fgIsA;" << std::endl
@@ -3288,11 +3292,23 @@ class tempFileNamesCatalog {
          std::ifstream ifile(tmpName);
          if (!ifile)
             ROOT::TMetaUtils::Error(0, "Cannot find %s!\n", tmpName);
-
+#ifdef WIN32
+         // Sometimes files cannot be renamed on Windows if they don't have
+         // been released by the system. So just copy them and try to delete
+         // the old one afterwards.
+         if (ifile.is_open())
+            ifile.close();
+         if (0 != std::rename(tmpName , name)) {
+            if (llvm::sys::fs::copy_file(tmpName , name)) {
+               llvm::sys::fs::remove(tmpName);
+            }
+         }
+#else
          if (0 != std::rename(tmpName , name)) {
-            ROOT::TMetaUtils::Error(0, "Renaming %s into %s!\n", tmpName , name);
+            ROOT::TMetaUtils::Error(0, "Renaming %s into %s!\n", tmpName, name);
             retval++;
          }
+#endif
       }
       return retval;
    }
@@ -4094,6 +4110,10 @@ int RootCling(int argc,
    // flags used only for the pragma parser:
    clingArgs.push_back("-D__CINT__");
    clingArgs.push_back("-D__MAKECINT__");
+#ifdef R__WIN32
+   // Prevent the following #error: The C++ Standard Library forbids macroizing keywords.
+   clingArgs.push_back("-D_XKEYCHECK_H");
+#endif
 
    AddPlatformDefines(clingArgs);
 

From c1a5edd948461c2855e836a3492aa6ec81e061ab Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Wed, 25 Feb 2015 17:57:44 +0100
Subject: [PATCH 048/200] Fix compilation errors on Windows

MSVC doesn't support fSpinLock=ATOMIC_FLAG_INIT; in the class definition, nor in the class constructor initializer list
---
 core/meta/inc/TClass.h                                    | 2 +-
 core/meta/src/TClass.cxx                                  | 8 +++++++-
 interpreter/cling/include/cling/Interpreter/Transaction.h | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index 01b45b8cb679a..9a8e679c975c9 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -153,7 +153,7 @@ friend class TProtoClass;
    private:
       Int_t fVerbLevel=0;
       std::unordered_set<std::string> fClassNamesSet;
-      mutable std::atomic_flag fSpinLock = ATOMIC_FLAG_INIT;
+      mutable std::atomic_flag fSpinLock; // MSVC doesn't support = ATOMIC_FLAG_INIT;
    };
 
    class InsertTClassInRegistryRAII {
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 13eef200b6501..63a9d5805efa2 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -108,7 +108,13 @@ std::atomic<Int_t> TClass::fgClassCount;
 // Implementation of the TDeclNameRegistry
 
 //______________________________________________________________________________
-TClass::TDeclNameRegistry::TDeclNameRegistry(Int_t verbLevel): fVerbLevel(verbLevel){}
+TClass::TDeclNameRegistry::TDeclNameRegistry(Int_t verbLevel): fVerbLevel(verbLevel)
+{
+   // TDeclNameRegistry class constructor.
+
+   // MSVC doesn't support fSpinLock=ATOMIC_FLAG_INIT; in the class definition
+   std::atomic_flag_clear( &fSpinLock );
+}
 
 //______________________________________________________________________________
 void TClass::TDeclNameRegistry::AddQualifiedName(const char *name)
diff --git a/interpreter/cling/include/cling/Interpreter/Transaction.h b/interpreter/cling/include/cling/Interpreter/Transaction.h
index 1a76d86ba303a..5b93e6fd7ccb7 100644
--- a/interpreter/cling/include/cling/Interpreter/Transaction.h
+++ b/interpreter/cling/include/cling/Interpreter/Transaction.h
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Module.h"
 
 #include <memory>
 
@@ -34,7 +35,6 @@ namespace clang {
 
 namespace llvm {
   class raw_ostream;
-  class Module;
 }
 
 namespace cling {

From 6276baa6cd46ff399b4068c484a773a781e01a53 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Wed, 25 Feb 2015 18:19:06 +0100
Subject: [PATCH 049/200] Skip for the moment the templated functions

---
 core/metautils/src/SelectionRules.cxx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/core/metautils/src/SelectionRules.cxx b/core/metautils/src/SelectionRules.cxx
index f08e9d756cba4..3e92471b22a1b 100644
--- a/core/metautils/src/SelectionRules.cxx
+++ b/core/metautils/src/SelectionRules.cxx
@@ -305,7 +305,7 @@ const ClassSelectionRule *SelectionRules::IsDeclSelected(clang::NamespaceDecl *D
 }
 
 const BaseSelectionRule *SelectionRules::IsDeclSelected(clang::EnumDecl *D) const
-{  
+{
    // Currently rootcling does not need any information on enums, except
    // for the PCM / proto classes that register them to build TEnums without
    // parsing. This can be removed once (real) PCMs are available.
@@ -866,7 +866,9 @@ const BaseSelectionRule *SelectionRules::IsVarSelected(clang::VarDecl* D, const
 
 const BaseSelectionRule *SelectionRules::IsFunSelected(clang::FunctionDecl *D, const std::string &qual_name) const
 {
+
    if (fFunctionSelectionRules.size() == 0 ||
+       D->getPrimaryTemplate() != nullptr ||
        llvm::isa<clang::CXXMethodDecl>(D)) return nullptr;
 
    std::string prototype;
@@ -974,6 +976,7 @@ const BaseSelectionRule *SelectionRules::IsLinkdefFunSelected(clang::FunctionDec
 {
 
    if (fFunctionSelectionRules.size() == 0 ||
+       D->getPrimaryTemplate() != nullptr ||
        llvm::isa<clang::CXXMethodDecl>(D)) return nullptr;
 
    std::string prototype;

From 7db871f76b21de52c22e98d32c1baaa0069321e8 Mon Sep 17 00:00:00 2001
From: Matevz Tadel <mtadel@ucsd.edu>
Date: Wed, 25 Feb 2015 09:44:03 -0800
Subject: [PATCH 050/200] Fixes for clang.

(cherry picked from 5.34-patches commit f73120af47efefa7f363e2ea35501af00b916e95)
---
 graf3d/eve/src/TEvePointSet.cxx | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/graf3d/eve/src/TEvePointSet.cxx b/graf3d/eve/src/TEvePointSet.cxx
index 055f55a6f40af..1618d8e078d55 100644
--- a/graf3d/eve/src/TEvePointSet.cxx
+++ b/graf3d/eve/src/TEvePointSet.cxx
@@ -47,7 +47,7 @@ ClassImp(TEvePointSet);
 
 //______________________________________________________________________________
 TEvePointSet::TEvePointSet(Int_t n_points, ETreeVarType_e tv_type) :
-   TEveElement(fMarkerColor),
+   TEveElement(),
    TPointSet3D(n_points),
    TEvePointSelectorConsumer(tv_type),
    TEveProjectable(),
@@ -60,6 +60,7 @@ TEvePointSet::TEvePointSet(Int_t n_points, ETreeVarType_e tv_type) :
    // Constructor.
 
    fMarkerStyle = 20;
+   SetMainColorPtr(&fMarkerColor);
 
    // Override from TEveElement.
    fPickable = kTRUE;
@@ -458,7 +459,7 @@ ClassImp(TEvePointSetArray);
 //______________________________________________________________________________
 TEvePointSetArray::TEvePointSetArray(const char* name,
                                      const char* title) :
-   TEveElement(fMarkerColor),
+   TEveElement(),
    TNamed(name, title),
 
    fBins(0), fDefPointSetCapacity(128), fNBins(0), fLastBin(-1),
@@ -467,6 +468,8 @@ TEvePointSetArray::TEvePointSetArray(const char* name,
    fQuantName()
 {
    // Constructor.
+
+   SetMainColorPtr(&fMarkerColor);
 }
 
 //______________________________________________________________________________

From ac03dcc15f7d0ee2084a84eaa03fc60d771febac Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Wed, 25 Feb 2015 20:31:05 +0100
Subject: [PATCH 051/200] Test inline asm at least on linux.

---
 interpreter/cling/test/SourceCall/decls.C | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/interpreter/cling/test/SourceCall/decls.C b/interpreter/cling/test/SourceCall/decls.C
index c3bc9b166cad6..8b47b4060ef98 100644
--- a/interpreter/cling/test/SourceCall/decls.C
+++ b/interpreter/cling/test/SourceCall/decls.C
@@ -24,5 +24,12 @@ float f = sin(12);
 int j = i;
 
 void decls() {
+#ifdef __linux__
+   int arg1 = 17, arg2 = 42, add = -1;
+   __asm__ ( "addl %%ebx, %%eax;" : "=a" (add) : "a" (arg1) , "b" (arg2) );
+#else
+   add = arg1 + arg2;
+#endif
+   printf("result=%d\n", add); // CHECK:result=59
    printf("j=%d\n",j); // CHECK:j=12
 }

From 126c52775303b82456a65c2a0c4be791315df5b3 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Wed, 25 Feb 2015 21:22:13 +0100
Subject: [PATCH 052/200] Fatal line mess - extract decl out of #if.

---
 interpreter/cling/test/SourceCall/decls.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/interpreter/cling/test/SourceCall/decls.C b/interpreter/cling/test/SourceCall/decls.C
index 8b47b4060ef98..b0d45e448bf63 100644
--- a/interpreter/cling/test/SourceCall/decls.C
+++ b/interpreter/cling/test/SourceCall/decls.C
@@ -24,8 +24,8 @@ float f = sin(12);
 int j = i;
 
 void decls() {
-#ifdef __linux__
    int arg1 = 17, arg2 = 42, add = -1;
+#ifdef __linux__
    __asm__ ( "addl %%ebx, %%eax;" : "=a" (add) : "a" (arg1) , "b" (arg2) );
 #else
    add = arg1 + arg2;

From b97b34bba890c712c529387b83faea0058776fbf Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 12 Feb 2015 15:49:31 -0600
Subject: [PATCH 053/200] Switch from bitfield to atomic for correct multi
 thread behavior.

We need to avoid the potential conflict between read and write of independent/distinct variables (if two bitfield variables are
stored in memory in the same byte, updates to either of them can/will affect (temporarily) the observable value of the other).
---
 core/meta/inc/TClass.h   |  9 +++++----
 core/meta/src/TClass.cxx | 25 +++++++++++++++++++++----
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index 9a8e679c975c9..d76666005850b 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -227,10 +227,11 @@ friend class TProtoClass;
    mutable std::atomic<Long_t> fProperty; //!Property
    mutable Long_t     fClassProperty;     //!C++ Property of the class (is abstract, has virtual table, etc.)
 
-           Bool_t     fHasRootPcmInfo : 1;      //!Whether info was loaded from a root pcm.
-   mutable Bool_t     fCanLoadClassInfo : 1;    //!Indicates whether the ClassInfo is supposed to be available.
-   mutable Bool_t     fIsOffsetStreamerSet : 1; //!saved remember if fOffsetStreamer has been set.
-   mutable std::atomic<Bool_t> fVersionUsed;     //!Indicates whether GetClassVersion has been called
+           // fHasRootPcmInfo needs to be atomic as long as GetListOfBases needs to modify it.
+           std::atomic<Bool_t> fHasRootPcmInfo;      //!Whether info was loaded from a root pcm.
+   mutable std::atomic<Bool_t> fCanLoadClassInfo;    //!Indicates whether the ClassInfo is supposed to be available.
+   mutable std::atomic<Bool_t> fIsOffsetStreamerSet; //!saved remember if fOffsetStreamer has been set.
+   mutable std::atomic<Bool_t> fVersionUsed;         //!Indicates whether GetClassVersion has been called
 
    mutable Long_t     fOffsetStreamer;  //!saved info to call Streamer
    Int_t              fStreamerType;    //!cached of the streaming method to use
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 63a9d5805efa2..dc6d45d017b16 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -2042,11 +2042,11 @@ void TClass::CalculateStreamerOffset() const
       // gets allocated on the heap and not in the mapped file.
 
       TMmallocDescTemp setreset;
-      fIsOffsetStreamerSet = kTRUE;
       fOffsetStreamer = const_cast<TClass*>(this)->GetBaseClassOffsetRecurse(TObject::Class());
       if (fStreamerType == kTObject) {
          fStreamerImpl = &TClass::StreamerTObjectInitialized;
       }
+      fIsOffsetStreamerSet = kTRUE;
    }
 }
 
@@ -3290,13 +3290,22 @@ TList *TClass::GetListOfBases()
    if (!fBase) {
       if (fCanLoadClassInfo) {
          if (fState == kHasTClassInit) {
+
+            R__LOCKGUARD(gInterpreterMutex);
+            // NOTE: Add test to prevent redo if another thread has already done the work.
+            // if (!fHasRootPcmInfo) {
+
             // The bases are in our ProtoClass; we don't need the class info.
             TProtoClass *proto = TClassTable::GetProtoNorm(GetName());
             if (proto && proto->FillTClass(this)) {
+               // Not sure this code is still needed
+               // R__ASSERT(kFALSE);
+
                fHasRootPcmInfo = kTRUE;
             }
          }
-         if (!fHasRootPcmInfo) {
+         // We test again on fCanLoadClassInfo has another thread may have executed it.
+         if (!fHasRootPcmInfo && !fCanLoadClassInfo) {
             LoadClassInfo();
          }
       }
@@ -3334,9 +3343,15 @@ TList *TClass::GetListOfDataMembers(Bool_t load /* = kTRUE */)
 
    if (!fData) {
       if (fCanLoadClassInfo && fState == kHasTClassInit) {
+         // NOTE: Add test to prevent redo if another thread has already done the work.
+         // if (!fHasRootPcmInfo) {
+
          // The members are in our ProtoClass; we don't need the class info.
          TProtoClass *proto = TClassTable::GetProtoNorm(GetName());
          if (proto && proto->FillTClass(this)) {
+            // Not sure this code is still needed
+            // R__ASSERT(kFALSE);
+
             fHasRootPcmInfo = kTRUE;
             return fData;
          }
@@ -5218,10 +5233,12 @@ void TClass::LoadClassInfo() const
    // Try to load the classInfo (it may require parsing the header file
    // and/or loading data from the clang pcm).
 
-   R__ASSERT(fCanLoadClassInfo);
-
    R__LOCKGUARD(gInterpreterMutex);
 
+   // If another thread executed LoadClassInfo at about the same time
+   // as this thread return early since the work was done.
+   if (!fCanLoadClassInfo) return;
+
    gInterpreter->AutoParse(GetName());
    if (!fClassInfo) gInterpreter->SetClassInfo(const_cast<TClass*>(this));   // sets fClassInfo pointer
    if (!gInterpreter->IsAutoParsingSuspended()) {

From 98fc7e158d0d4ef44e002ed38d45be3ddaa0e669 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Thu, 12 Feb 2015 21:32:47 +0100
Subject: [PATCH 054/200] Protect concurrent access to gROOT->GetListOfFiles()

Use the gROOTMutex to protect access to possible concurrent accesses
to gROOT->GetListOfFiles().

Note: this would be superseded by making the list itself thread-safe.
Signed-off-by: Philippe Canal <pcanal@fnal.gov>
---
 core/base/src/TROOT.cxx             |  2 ++
 io/sql/src/TSQLFile.cxx             |  6 +++++-
 io/xml/src/TXMLFile.cxx             |  6 +++++-
 tree/treeplayer/src/TTreePlayer.cxx | 22 ++++++++++++++--------
 4 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index ab7c84d89b805..8b94d8b27b144 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -1063,6 +1063,7 @@ TObject *TROOT::FindObjectAnyFile(const char *name) const
 {
    // Scan the memory lists of all files for an object with name
 
+   R__LOCKGUARD(gROOTMutex);
    TDirectory *d;
    TIter next(GetListOfFiles());
    while ((d = (TDirectory*)next())) {
@@ -1196,6 +1197,7 @@ TFile *TROOT::GetFile(const char *name) const
 {
    // Return pointer to file with name.
 
+   R__LOCKGUARD(gROOTMutex);
    return (TFile*)GetListOfFiles()->FindObject(name);
 }
 
diff --git a/io/sql/src/TSQLFile.cxx b/io/sql/src/TSQLFile.cxx
index 9e027c07628d0..7f694a21a5b7f 100644
--- a/io/sql/src/TSQLFile.cxx
+++ b/io/sql/src/TSQLFile.cxx
@@ -706,6 +706,7 @@ void TSQLFile::Close(Option_t *option)
    }
    pidDeleted.Delete();
 
+   R__LOCKGUARD(gROOTMutex);
    gROOT->GetListOfFiles()->Remove(this);
 }
 
@@ -1049,7 +1050,10 @@ void TSQLFile::InitSqlDatabase(Bool_t create)
       }
    }
 
-   gROOT->GetListOfFiles()->Add(this);
+   {
+      R__LOCKGUARD(gROOTMutex);
+      gROOT->GetListOfFiles()->Add(this);
+   }
    cd();
 
    fNProcessIDs = 0;
diff --git a/io/xml/src/TXMLFile.cxx b/io/xml/src/TXMLFile.cxx
index b353806d5fc85..78c788c7669d9 100644
--- a/io/xml/src/TXMLFile.cxx
+++ b/io/xml/src/TXMLFile.cxx
@@ -295,7 +295,10 @@ void TXMLFile::InitXmlFile(Bool_t create)
       ReadFromFile();
    }
 
-   gROOT->GetListOfFiles()->Add(this);
+   {
+      R__LOCKGUARD(gROOTMutex);
+      gROOT->GetListOfFiles()->Add(this);
+   }
    cd();
 
    fNProcessIDs = 0;
@@ -358,6 +361,7 @@ void TXMLFile::Close(Option_t *option)
    }
    pidDeleted.Delete();
 
+   R__LOCKGUARD(gROOTMutex);
    gROOT->GetListOfFiles()->Remove(this);
 }
 
diff --git a/tree/treeplayer/src/TTreePlayer.cxx b/tree/treeplayer/src/TTreePlayer.cxx
index c09770867cb4c..580ec5b229b61 100644
--- a/tree/treeplayer/src/TTreePlayer.cxx
+++ b/tree/treeplayer/src/TTreePlayer.cxx
@@ -1163,10 +1163,13 @@ Int_t TTreePlayer::MakeClass(const char *classname, const char *option)
          fprintf(fp,"      // of trees.\n");
          fprintf(fp,"      TChain * chain = new TChain(\"%s\",\"%s\");\n",
                  fTree->GetName(),fTree->GetTitle());
-         TIter next(((TChain*)fTree)->GetListOfFiles());
-         TChainElement *element;
-         while ((element = (TChainElement*)next())) {
-            fprintf(fp,"      chain->Add(\"%s/%s\");\n",element->GetTitle(),element->GetName());
+         {
+            R__LOCKGUARD(gROOTMutex);
+            TIter next(((TChain*)fTree)->GetListOfFiles());
+            TChainElement *element;
+            while ((element = (TChainElement*)next())) {
+               fprintf(fp,"      chain->Add(\"%s/%s\");\n",element->GetTitle(),element->GetName());
+            }
          }
          fprintf(fp,"      tree = chain;\n");
          fprintf(fp,"#endif // SINGLE_TREE\n\n");
@@ -1604,10 +1607,13 @@ Int_t TTreePlayer::MakeCode(const char *filename)
       fprintf(fp,"   // of trees.\n");
       fprintf(fp,"   TChain *%s = new TChain(\"%s\",\"%s\");\n",
                  fTree->GetName(),fTree->GetName(),fTree->GetTitle());
-      TIter next(((TChain*)fTree)->GetListOfFiles());
-      TChainElement *element;
-      while ((element = (TChainElement*)next())) {
-         fprintf(fp,"   %s->Add(\"%s/%s\");\n",fTree->GetName(),element->GetTitle(),element->GetName());
+      {
+         R__LOCKGUARD(gROOTMutex);
+         TIter next(((TChain*)fTree)->GetListOfFiles());
+         TChainElement *element;
+         while ((element = (TChainElement*)next())) {
+            fprintf(fp,"   %s->Add(\"%s/%s\");\n",fTree->GetName(),element->GetTitle(),element->GetName());
+         }
       }
       fprintf(fp,"#endif // SINGLE_TREE\n\n");
    }

From 6731b19641960356db6e036a5438def45692f5af Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 12 Feb 2015 16:37:22 -0600
Subject: [PATCH 055/200] Do not needelessly load all functions in GetMethodAny

---
 core/meta/src/TClass.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index dc6d45d017b16..c278c008c6315 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3899,7 +3899,7 @@ TMethod *TClass::GetMethodAny(const char *method)
    // of the class.
 
    if (!HasInterpreterInfo()) return 0;
-   return (TMethod*) GetListOfMethods()->FindObject(method);
+   return (TMethod*) GetMethodList()->FindObject(method);
 }
 
 //______________________________________________________________________________

From 349ebfbeed878bb85ed73e06b2b0263a1ec2ad5f Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 12 Feb 2015 16:37:28 -0600
Subject: [PATCH 056/200] Improve comments

---
 core/meta/inc/TClass.h   | 2 +-
 core/meta/src/TClass.cxx | 8 +++++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index d76666005850b..5adf0c73457d8 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -282,7 +282,7 @@ friend class TProtoClass;
    static TDeclNameRegistry fNoInfoOrEmuOrFwdDeclNameRegistry; // Store the decl names of the forwardd and no info instances
    static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char*);
 
-   // Internal status bits
+   // Internal status bits, set and reset only during initialization and thus under the protection of the global lock.
    enum { kLoading = BIT(14), kUnloading = BIT(14) };
    // Internal streamer type.
    enum EStreamerType {kDefault=0, kEmulatedStreamer=1, kTObject=2, kInstrumented=4, kForeign=8, kExternal=16};
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index c278c008c6315..40e9c65228f69 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -5481,10 +5481,10 @@ Long_t TClass::Property() const
          kl->fStreamerType  = kExternal;
          kl->fStreamerImpl  = &TClass::StreamerExternal;
       }
-      //must set this last since other threads may read fProperty
-      // and think all test bits have been properly set
-      kl->fProperty = gCling->ClassInfo_Property(fClassInfo);
       kl->fClassProperty = gCling->ClassInfo_ClassProperty(GetClassInfo());
+      // Must set this last since other threads may read fProperty
+      // and think all test bits have been properly set.
+      kl->fProperty = gCling->ClassInfo_Property(fClassInfo);
 
    } else {
 
@@ -5495,6 +5495,8 @@ Long_t TClass::Property() const
 
       kl->fStreamerType |= kEmulatedStreamer;
       kl->SetStreamerImpl();
+      // fProperty was *not* set so that it can be forced to be recalculated
+      // next time.
       return 0;
    }
 

From d300f6e6b462b36992ebe55c6ed0f34b49df88dc Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Sun, 15 Feb 2015 18:06:13 +0100
Subject: [PATCH 057/200] Made TClass::fMethod atomic

The pointer TClass::fMethod can be assigned and then read by different
threads and therefore we need to guarantee its thread safety.
---
 core/meta/inc/TClass.h   |  2 +-
 core/meta/src/TClass.cxx | 21 ++++++++++++++-------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index 5adf0c73457d8..cfe806e27916d 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -187,7 +187,7 @@ friend class TProtoClass;
    TListOfDataMembers*fData;            //linked list for data members
    TListOfEnums      *fEnums;           //linked list for the enums
    TListOfFunctionTemplates *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
-   TListOfFunctions  *fMethod;          //linked list for methods
+   std::atomic<TListOfFunctions*> fMethod;          //linked list for methods
    TViewPubDataMembers*fAllPubData;      //all public data members (including from base classes)
    TViewPubFunctions *fAllPubMethod;    //all public methods (including from base classes)
    mutable TList     *fClassMenuList;   //list of class menu items
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 40e9c65228f69..b7c57613bd55e 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -77,6 +77,7 @@
 #include <cmath>
 #include <assert.h>
 #include <vector>
+#include <memory>
 
 #include "TListOfDataMembers.h"
 #include "TListOfFunctions.h"
@@ -1557,7 +1558,7 @@ TClass::~TClass()
    delete fFuncTemplate; fFuncTemplate = 0;
 
    if (fMethod)
-      fMethod->Delete();
+      (*fMethod).Delete();
    delete fMethod;   fMethod=0;
 
    if (fRealData)
@@ -3390,10 +3391,10 @@ TList *TClass::GetListOfMethods(Bool_t load /* = kTRUE */)
 
    R__LOCKGUARD(gInterpreterMutex);
 
-   if (!fMethod) fMethod = new TListOfFunctions(this);
+   if (!fMethod) GetMethodList();
    if (load) {
       if (gDebug>0) Info("GetListOfMethods","Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
-      fMethod->Load();
+      (*fMethod).Load();
    }
    return fMethod;
 }
@@ -3402,7 +3403,7 @@ TList *TClass::GetListOfMethods(Bool_t load /* = kTRUE */)
 TCollection *TClass::GetListOfMethodOverloads(const char* name) const
 {
    // Return the collection of functions named "name".
-   return ((TListOfFunctions*)fMethod)->GetListForObject(name);
+   return const_cast<TClass*>(this)->GetMethodList()->GetListForObject(name);
 }
 
 
@@ -3756,7 +3757,7 @@ void TClass::ResetCaches()
    if (fEnums)
       fEnums->Unload();
    if (fMethod)
-      fMethod->Unload();
+      (*fMethod).Unload();
 
    delete fAllPubData; fAllPubData = 0;
 
@@ -3885,7 +3886,13 @@ TListOfFunctions *TClass::GetMethodList()
    // the internal type of fMethod and thus can not be made public.
    // It also never 'loads' the content of the list.
 
-   if (!fMethod) fMethod = new TListOfFunctions(this);
+   if (!fMethod) {
+      std::unique_ptr<TListOfFunctions> temp{ new TListOfFunctions(this) };
+      TListOfFunctions* expected = nullptr;
+      if(fMethod.compare_exchange_strong(expected, temp.get()) ) {
+         temp.release();
+      }
+   }
    return fMethod;
 }
 
@@ -5631,7 +5638,7 @@ void TClass::SetUnloaded()
    fTypeInfo     = 0;
 
    if (fMethod) {
-      fMethod->Unload();
+      (*fMethod).Unload();
    }
    if (fData) {
       fData->Unload();

From 0be6bc49bd80d7373e76841eeed2744deb8a5b36 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Sun, 15 Feb 2015 18:07:27 +0100
Subject: [PATCH 058/200] Made TListOfFunctions thread safe

TlistOfFunctions can update itself over time, even from calls to
const functions. Since the class instances are available globally
they need to be threads safe. This required that all 'const' functions
take the global lock. In addition, a new iterator was needed which
takes the global lock on the call to Next().
---
 core/meta/inc/LinkDef.h            |   1 +
 core/meta/inc/TListOfFunctions.h   |  38 ++++++++-
 core/meta/src/TListOfFunctions.cxx | 119 ++++++++++++++++++++++++++++-
 3 files changed, 155 insertions(+), 3 deletions(-)

diff --git a/core/meta/inc/LinkDef.h b/core/meta/inc/LinkDef.h
index 2d6f54b2c927e..24189698605e2 100644
--- a/core/meta/inc/LinkDef.h
+++ b/core/meta/inc/LinkDef.h
@@ -66,6 +66,7 @@
 #pragma link C++ class std::vector<std::pair<Int_t, Int_t> >+;
 #pragma link C++ class TFileMergeInfo;
 #pragma link C++ class TListOfFunctions+;
+#pragma link C++ class TListOfFunctionsIter;
 #pragma link C++ class TListOfFunctionTemplates+;
 #pragma link C++ class TListOfDataMembers-;
 #pragma link C++ class TListOfEnums+;
diff --git a/core/meta/inc/TListOfFunctions.h b/core/meta/inc/TListOfFunctions.h
index 5d9f35dc31659..8b67767409388 100644
--- a/core/meta/inc/TListOfFunctions.h
+++ b/core/meta/inc/TListOfFunctions.h
@@ -63,10 +63,26 @@ class TListOfFunctions : public THashList
    virtual void Clear(Option_t *option);
    virtual void Delete(Option_t *option="");
 
-   using THashList::FindObject;
+   virtual TObject   *FindObject(const TObject* obj) const;
    virtual TObject   *FindObject(const char *name) const;
    virtual TList     *GetListForObject(const char* name) const;
    virtual TList     *GetListForObject(const TObject* obj) const;
+   virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const;
+
+   virtual TObject  *At(Int_t idx) const;
+   virtual TObject  *After(const TObject *obj) const;
+   virtual TObject  *Before(const TObject *obj) const;
+   virtual TObject  *First() const;
+   virtual TObjLink *FirstLink() const;
+   virtual TObject **GetObjectRef(const TObject *obj) const;
+   virtual TObject  *Last() const;
+   virtual TObjLink *LastLink() const;
+
+   virtual Int_t     GetLast() const;
+   virtual Int_t     IndexOf(const TObject *obj) const;
+
+   virtual Int_t      GetSize() const;
+
 
    TFunction *Find(DeclId_t id) const;
    TFunction *Get(DeclId_t id);
@@ -92,4 +108,24 @@ class TListOfFunctions : public THashList
    ClassDef(TListOfFunctions,0);  // List of TFunctions for a class
 };
 
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfFunctionsIter                                                 //
+//                                                                      //
+// Iterator of TListOfFunctions.                                        //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+class TListOfFunctionsIter : public TListIter
+{
+ public:
+   TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir = kIterForward);
+
+   using TListIter::operator=;
+
+   TObject           *Next();
+
+   ClassDef(TListOfFunctionsIter,0)
+};
+
+
 #endif // ROOT_TListOfFunctions
diff --git a/core/meta/src/TListOfFunctions.cxx b/core/meta/src/TListOfFunctions.cxx
index 573f067a386b2..bf5bda4770b04 100644
--- a/core/meta/src/TListOfFunctions.cxx
+++ b/core/meta/src/TListOfFunctions.cxx
@@ -176,11 +176,10 @@ TObject *TListOfFunctions::FindObject(const char *name) const
    // Specialize FindObject to do search for the
    // a function just by name or create it if its not already in the list
 
+   R__LOCKGUARD(gInterpreterMutex);
    TObject *result = THashList::FindObject(name);
    if (!result) {
 
-      R__LOCKGUARD(gInterpreterMutex);
-
       TInterpreter::DeclId_t decl;
       if (fClass) decl = gInterpreter->GetFunction(fClass->GetClassInfo(),name);
       else        decl = gInterpreter->GetFunction(0,name);
@@ -254,6 +253,7 @@ TFunction *TListOfFunctions::Find(DeclId_t id) const
 
    if (!id) return 0;
 
+   R__LOCKGUARD(gInterpreterMutex);
    return (TFunction*)fIds->GetValue((Long64_t)id);
 }
 
@@ -268,6 +268,7 @@ TFunction *TListOfFunctions::Get(DeclId_t id)
    TFunction *f = Find(id);
    if (f) return f;
 
+   R__LOCKGUARD(gInterpreterMutex);
    if (fClass) {
       if (!gInterpreter->ClassInfo_Contains(fClass->GetClassInfo(),id)) return 0;
    } else {
@@ -438,3 +439,117 @@ void TListOfFunctions::Unload(TFunction *func)
       fUnloaded->Add(func);
    }
 }
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::FindObject(const TObject* obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::FindObject(obj);
+}
+
+//______________________________________________________________________________
+TIterator* TListOfFunctions::MakeIterator(Bool_t dir ) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return new TListOfFunctionsIter(this,dir);
+}
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::At(Int_t idx) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::At(idx);
+}
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::After(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::After(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::Before(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::Before(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::First() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::First();
+}
+
+//______________________________________________________________________________
+TObjLink* TListOfFunctions::FirstLink() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::FirstLink();
+}
+
+//______________________________________________________________________________
+TObject** TListOfFunctions::GetObjectRef(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::GetObjectRef(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfFunctions::Last() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::Last();
+}
+
+//______________________________________________________________________________
+TObjLink* TListOfFunctions::LastLink() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::LastLink();
+}
+
+
+//______________________________________________________________________________
+Int_t TListOfFunctions::GetLast() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::GetLast();
+}
+
+//______________________________________________________________________________
+Int_t TListOfFunctions::IndexOf(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::IndexOf(obj);
+}
+
+
+//______________________________________________________________________________
+Int_t TListOfFunctions::GetSize() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return THashList::GetSize();
+}
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfFunctionsIter                                                 //
+//                                                                      //
+// Iterator for TListOfFunctions.                                       //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+ClassImp(TListOfFunctionsIter)
+
+//______________________________________________________________________________
+TListOfFunctionsIter::TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir ):
+  TListIter(l,dir) {}
+
+//______________________________________________________________________________
+TObject *TListOfFunctionsIter::Next()
+{
+  R__LOCKGUARD(gInterpreterMutex);
+  return TListIter::Next();
+}

From 906a191aa52c1aefa4948d1056c14ce65a1ef5f5 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 14:20:28 -0600
Subject: [PATCH 059/200] White spaces

---
 core/meta/inc/TListOfFunctions.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/inc/TListOfFunctions.h b/core/meta/inc/TListOfFunctions.h
index 8b67767409388..3747dd0cd12b2 100644
--- a/core/meta/inc/TListOfFunctions.h
+++ b/core/meta/inc/TListOfFunctions.h
@@ -117,7 +117,7 @@ class TListOfFunctions : public THashList
 //////////////////////////////////////////////////////////////////////////
 class TListOfFunctionsIter : public TListIter
 {
- public:
+public:
    TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir = kIterForward);
 
    using TListIter::operator=;

From b70e56dfd7b49f28a48edf661dca834cf6995c4c Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 14:21:06 -0600
Subject: [PATCH 060/200] Avoid null pointer dereference

---
 core/cont/inc/TCollection.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/cont/inc/TCollection.h b/core/cont/inc/TCollection.h
index f3aa2279d5f76..138c203743244 100644
--- a/core/cont/inc/TCollection.h
+++ b/core/cont/inc/TCollection.h
@@ -170,7 +170,7 @@ class TIter {
    Bool_t             operator!=(const TIter &aIter) const {
       return !(*this == aIter);
    }
-   TObject           *operator*() const { return *(*fIterator); }
+   TObject           *operator*() const { return fIterator ? *(*fIterator): nullptr; }
    TIter             &Begin();
    static TIter       End();
 

From e2272a07edf895e727e77560eeb421478d4d792c Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 14:21:21 -0600
Subject: [PATCH 061/200] White spaces

---
 core/meta/src/TListOfFunctions.cxx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/core/meta/src/TListOfFunctions.cxx b/core/meta/src/TListOfFunctions.cxx
index bf5bda4770b04..27358d58960db 100644
--- a/core/meta/src/TListOfFunctions.cxx
+++ b/core/meta/src/TListOfFunctions.cxx
@@ -550,6 +550,7 @@ TListOfFunctionsIter::TListOfFunctionsIter(const TListOfFunctions *l, Bool_t dir
 //______________________________________________________________________________
 TObject *TListOfFunctionsIter::Next()
 {
-  R__LOCKGUARD(gInterpreterMutex);
-  return TListIter::Next();
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListIter::Next();
 }
+

From c9822bb388e16858359010f12a9b570ff39205b4 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 14:22:16 -0600
Subject: [PATCH 062/200] Allow inheriting from TListIter.

This was 'blocked' by requiring the type to be exactly TListIter in TListIter::operator= and TListIter::operator!=
---
 core/cont/src/TList.cxx | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/core/cont/src/TList.cxx b/core/cont/src/TList.cxx
index 17af25dea735e..611c5df3eebbe 100644
--- a/core/cont/src/TList.cxx
+++ b/core/cont/src/TList.cxx
@@ -904,13 +904,14 @@ TIterator &TListIter::operator=(const TIterator &rhs)
 {
    // Overridden assignment operator.
 
-   if (this != &rhs && rhs.IsA() == TListIter::Class()) {
-      const TListIter &rhs1 = (const TListIter &)rhs;
-      fList      = rhs1.fList;
-      fCurCursor = rhs1.fCurCursor;
-      fCursor    = rhs1.fCursor;
-      fDirection = rhs1.fDirection;
-      fStarted   = rhs1.fStarted;
+   const TListIter *rhs1 = dynamic_cast<const TListIter *>(&rhs);
+   if (this != &rhs && rhs1) {
+      TIterator::operator=(rhs);
+      fList      = rhs1->fList;
+      fCurCursor = rhs1->fCurCursor;
+      fCursor    = rhs1->fCursor;
+      fDirection = rhs1->fDirection;
+      fStarted   = rhs1->fStarted;
    }
    return *this;
 }
@@ -921,6 +922,7 @@ TListIter &TListIter::operator=(const TListIter &rhs)
    // Overloaded assignment operator.
 
    if (this != &rhs) {
+      TIterator::operator=(rhs);
       fList      = rhs.fList;
       fCurCursor = rhs.fCurCursor;
       fCursor    = rhs.fCursor;
@@ -987,7 +989,10 @@ Bool_t TListIter::operator!=(const TIterator &aIter) const
 {
    // This operator compares two TIterator objects.
 
-   if ((aIter.IsA() == TListIter::Class())) {
+   if (IsA() == aIter.IsA()) {
+      // We compared equal only two iterator of the same type.
+      // Since this is a function of TListIter, we consequently know that
+      // both this and aIter are of type inheriting from TListIter.
       const TListIter &iter(dynamic_cast<const TListIter &>(aIter));
       return (fCurCursor != iter.fCurCursor);
    }

From 91909e9284869120a8b4bf9b1136d8998dcfa05d Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Wed, 18 Feb 2015 19:55:40 +0100
Subject: [PATCH 063/200] Add locks to calls involving TCling interpreter
 classes

Need to take the interpreter lock for all cases where the cling
internals might be reached.
---
 core/meta/src/TCling.cxx           | 21 +++++++++++++++++++++
 core/meta/src/TClingCallFunc.cxx   | 27 +++++++++++++++++++++++----
 core/meta/src/TClingMethodInfo.cxx |  6 ++++++
 core/meta/src/TFunction.cxx        | 12 ++++++++++--
 4 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index 4313dce265cc2..e92e15117a3b1 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -6129,6 +6129,7 @@ Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
 //______________________________________________________________________________
 CallFunc_t* TCling::CallFunc_Factory() const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (CallFunc_t*) new TClingCallFunc(fInterpreter,*fNormalizedCtxt);
 }
 
@@ -6155,6 +6156,7 @@ void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
 //______________________________________________________________________________
 void TCling::CallFunc_Init(CallFunc_t* func) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingCallFunc* f = (TClingCallFunc*) func;
    f->Init();
 }
@@ -6372,6 +6374,7 @@ void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
 //______________________________________________________________________________
 ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (ClassInfo_t*) new TClingClassInfo(fInterpreter, all);
 }
 
@@ -6384,6 +6387,7 @@ ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
 //______________________________________________________________________________
 ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (ClassInfo_t*) new TClingClassInfo(fInterpreter, name);
 }
 
@@ -6411,6 +6415,7 @@ bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
 //______________________________________________________________________________
 void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
    TClinginfo->Init(name);
 }
@@ -6418,6 +6423,7 @@ void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
 //______________________________________________________________________________
 void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
    TClinginfo->Init(tagnum);
 }
@@ -6572,6 +6578,7 @@ void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
 //______________________________________________________________________________
 BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
    return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo);
 }
@@ -6580,6 +6587,7 @@ BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
 BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
    ClassInfo_t* base) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
    TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
    return (BaseClassInfo_t*) new TClingBaseClassInfo(fInterpreter, TClinginfo, TClinginfoBase);
@@ -6683,6 +6691,7 @@ void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
 //______________________________________________________________________________
 DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo /*= 0*/) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
    return (DataMemberInfo_t*) new TClingDataMemberInfo(fInterpreter, TClingclass_info);
 }
@@ -6690,6 +6699,7 @@ DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo /*= 0*/) co
 //______________________________________________________________________________
 DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
    const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
    return (DataMemberInfo_t*) new TClingDataMemberInfo(fInterpreter, vd, (TClingClassInfo*)clinfo);
@@ -7033,12 +7043,14 @@ void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature)
 //______________________________________________________________________________
 MethodInfo_t* TCling::MethodInfo_Factory() const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (MethodInfo_t*) new TClingMethodInfo(fInterpreter);
 }
 
 //______________________________________________________________________________
 MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (MethodInfo_t*) new TClingMethodInfo(fInterpreter, (TClingClassInfo*)clinfo);
 }
 
@@ -7046,6 +7058,7 @@ MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
 MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
 {
    const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
+   R__LOCKGUARD(gInterpreterMutex);
    const clang::FunctionDecl* fd = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl);
    return (MethodInfo_t*) new TClingMethodInfo(fInterpreter, fd);
 }
@@ -7230,12 +7243,14 @@ void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
 //______________________________________________________________________________
 MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (MethodArgInfo_t*) new TClingMethodArgInfo(fInterpreter);
 }
 
 //______________________________________________________________________________
 MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (MethodArgInfo_t*) new TClingMethodArgInfo(fInterpreter, (TClingMethodInfo*)minfo);
 }
 
@@ -7309,12 +7324,14 @@ void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
 //______________________________________________________________________________
 TypeInfo_t* TCling::TypeInfo_Factory() const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (TypeInfo_t*) new TClingTypeInfo(fInterpreter);
 }
 
 //______________________________________________________________________________
 TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (TypeInfo_t*) new TClingTypeInfo(fInterpreter, name);
 }
 
@@ -7327,6 +7344,7 @@ TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
 //______________________________________________________________________________
 void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
    TClinginfo->Init(name);
 }
@@ -7388,12 +7406,14 @@ void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
 //______________________________________________________________________________
 TypedefInfo_t* TCling::TypedefInfo_Factory() const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (TypedefInfo_t*) new TClingTypedefInfo(fInterpreter);
 }
 
 //______________________________________________________________________________
 TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    return (TypedefInfo_t*) new TClingTypedefInfo(fInterpreter, name);
 }
 
@@ -7407,6 +7427,7 @@ TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
 void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
                               const char* name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
    TClinginfo->Init(name);
 }
diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 4008483f3ba08..c60aa76ab396a 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -2116,6 +2116,7 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
 
 void TClingCallFunc::EvaluateArgList(const string &ArgList)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    SmallVector<Expr *, 4> exprs;
    fInterp->getLookupHelper().findArgList(ArgList, exprs,
                                           gDebug > 5 ? cling::LookupHelper::WithDiagnostics
@@ -2348,6 +2349,7 @@ void TClingCallFunc::ResetArg()
 
 void TClingCallFunc::SetArg(unsigned long param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.UnsignedLongTy, *fInterp));
    fArgVals.back().getLL() = param;
@@ -2355,6 +2357,7 @@ void TClingCallFunc::SetArg(unsigned long param)
 
 void TClingCallFunc::SetArg(long param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.LongTy, *fInterp));
    fArgVals.back().getLL() = param;
@@ -2362,6 +2365,7 @@ void TClingCallFunc::SetArg(long param)
 
 void TClingCallFunc::SetArg(float param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.FloatTy, *fInterp));
    fArgVals.back().getFloat() = param;
@@ -2369,6 +2373,7 @@ void TClingCallFunc::SetArg(float param)
 
 void TClingCallFunc::SetArg(double param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.DoubleTy, *fInterp));
    fArgVals.back().getDouble() = param;
@@ -2376,6 +2381,7 @@ void TClingCallFunc::SetArg(double param)
 
 void TClingCallFunc::SetArg(long long param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.LongLongTy, *fInterp));
    fArgVals.back().getLL() = param;
@@ -2383,6 +2389,7 @@ void TClingCallFunc::SetArg(long long param)
 
 void TClingCallFunc::SetArg(unsigned long long param)
 {
+   R__LOCKGUARD(gInterpreterMutex);
    ASTContext &C = fInterp->getCI()->getASTContext();
    fArgVals.push_back(cling::Value(C.UnsignedLongLongTy, *fInterp));
    fArgVals.back().getULL() = param;
@@ -2413,7 +2420,10 @@ void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, co
 {
    fWrapper = 0;
    delete fMethod;
-   fMethod = new TClingMethodInfo(fInterp);
+   {
+     R__LOCKGUARD(gInterpreterMutex);
+     fMethod = new TClingMethodInfo(fInterp);
+   }
    if (poffset) {
       *poffset = 0L;
    }
@@ -2442,7 +2452,10 @@ void TClingCallFunc::SetFunc(const TClingMethodInfo *info)
 {
    fWrapper = 0;
    delete fMethod;
-   fMethod = new TClingMethodInfo(*info);
+   {
+     R__LOCKGUARD(gInterpreterMutex);
+     fMethod = new TClingMethodInfo(*info);
+   }
    ResetArg();
    if (!fMethod->IsValid()) {
       return;
@@ -2462,7 +2475,10 @@ void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *metho
 {
    fWrapper = 0;
    delete fMethod;
-   fMethod = new TClingMethodInfo(fInterp);
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      fMethod = new TClingMethodInfo(fInterp);
+   }
    if (poffset) {
       *poffset = 0L;
    }
@@ -2492,7 +2508,10 @@ void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *metho
                                   EFunctionMatchMode mode/*=kConversionMatch*/)
 {
    delete fMethod;
-   fMethod = new TClingMethodInfo(fInterp);
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      fMethod = new TClingMethodInfo(fInterp);
+   }
    if (poffset) {
       *poffset = 0L;
    }
diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index df52a866658b1..eab99259015ea 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -163,7 +163,10 @@ void TClingMethodInfo::CreateSignature(TString &signature) const
       signature += ")";
       return;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
    TClingMethodArgInfo arg(fInterp, this);
+
    int idx = 0;
    while (arg.Next()) {
       if (idx) {
@@ -199,6 +202,7 @@ void *TClingMethodInfo::InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt
    if (!IsValid()) {
       return 0;
    }
+   R__LOCKGUARD(gInterpreterMutex);   
    TClingCallFunc cf(fInterp,normCtxt);
    cf.SetFunc(this);
    return cf.InterfaceMethod();
@@ -209,6 +213,7 @@ bool TClingMethodInfo::IsValid() const
    if (fSingleDecl) return fSingleDecl;
    else if (fTemplateSpecIter) {
       // Could trigger deserialization of decls.
+      R__LOCKGUARD(gInterpreterMutex);
       cling::Interpreter::PushTransactionRAII RAII(fInterp);
       return *(*fTemplateSpecIter);
    }
@@ -278,6 +283,7 @@ int TClingMethodInfo::InternalNext()
          }
          clang::DeclContext *dc = fContexts[fContextIdx];
          // Could trigger deserialization of decls.
+
          cling::Interpreter::PushTransactionRAII RAII(fInterp);
          fIter = dc->decls_begin();
          if (*fIter) {
diff --git a/core/meta/src/TFunction.cxx b/core/meta/src/TFunction.cxx
index 6540d768f891e..2e75c4c0351b9 100644
--- a/core/meta/src/TFunction.cxx
+++ b/core/meta/src/TFunction.cxx
@@ -279,7 +279,11 @@ Bool_t TFunction::Update(MethodInfo_t *info)
    // (info being the 'new' decl address).
 
    if (info == 0) {
-      if (fInfo) gCling->MethodInfo_Delete(fInfo);
+
+      if (fInfo) {
+         R__LOCKGUARD(gInterpreterMutex);
+         gCling->MethodInfo_Delete(fInfo);
+      }
       fInfo = 0;
       if (fMethodArgs) {
         for (Int_t i = 0; i < fMethodArgs->LastIndex() + 1; i ++) {
@@ -289,7 +293,10 @@ Bool_t TFunction::Update(MethodInfo_t *info)
       }
       return kTRUE;
    } else {
-      if (fInfo) gCling->MethodInfo_Delete(fInfo);
+      if (fInfo) {
+         R__LOCKGUARD(gInterpreterMutex);
+         gCling->MethodInfo_Delete(fInfo);
+      }
       fInfo = info;
       TString newMangledName = gCling->MethodInfo_GetMangledName(fInfo);
       if (newMangledName != fMangledName) {
@@ -302,6 +309,7 @@ Bool_t TFunction::Update(MethodInfo_t *info)
       if (fMethodArgs) {
          MethodArgInfo_t *arg = gCling->MethodArgInfo_Factory(fInfo);
          Int_t i = 0;
+         R__LOCKGUARD(gInterpreterMutex);
          while (gCling->MethodArgInfo_Next(arg)) {
             if (gCling->MethodArgInfo_IsValid(arg)) {
                MethodArgInfo_t *new_arg = gCling->MethodArgInfo_FactoryCopy(arg);

From 07cfc7f35620b4482444ad111c1aafb2cf190b04 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 14:37:57 -0600
Subject: [PATCH 064/200] White spaces

---
 core/meta/src/TClingMethodInfo.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index eab99259015ea..7cdca52cb29eb 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -202,7 +202,7 @@ void *TClingMethodInfo::InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt
    if (!IsValid()) {
       return 0;
    }
-   R__LOCKGUARD(gInterpreterMutex);   
+   R__LOCKGUARD(gInterpreterMutex);
    TClingCallFunc cf(fInterp,normCtxt);
    cf.SetFunc(this);
    return cf.InterfaceMethod();

From 98df1fbc3e0f4486fae395a6e9a2d30366a347e4 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 15:48:19 -0600
Subject: [PATCH 065/200] Assign directly to static variable to avoid race
 condition

---
 hist/hist/src/TFormulaOld.cxx | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hist/hist/src/TFormulaOld.cxx b/hist/hist/src/TFormulaOld.cxx
index 82cca8b9f9712..58d9ded650b74 100644
--- a/hist/hist/src/TFormulaOld.cxx
+++ b/hist/hist/src/TFormulaOld.cxx
@@ -420,10 +420,8 @@ Bool_t TFormulaOld::AnalyzeFunction(TString &chaine, Int_t &err, Int_t offset)
 
    // ROOT does yet have a complete TType class, but TCling does,
    // so let's use that for now.
-   static TypeInfo_t *doubletype = 0;
-   if (doubletype == 0) {
-      doubletype = gInterpreter->TypeInfo_Factory("double");
-   }
+   static TypeInfo_t *const doubletype { gInterpreter->TypeInfo_Factory("double") };
+
    std::vector<TypeInfo_t*> proto(nargs,doubletype);
 
    CallFunc_t *callfunc = gInterpreter->CallFunc_Factory();

From 27952225b04ea330df7ccf1976c43bf03881576f Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 19 Feb 2015 18:20:23 -0600
Subject: [PATCH 066/200] Fix deletion of atomic pointee (fix MacOS build)

---
 core/meta/src/TClass.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index b7c57613bd55e..9930e2600f44a 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -1559,7 +1559,7 @@ TClass::~TClass()
 
    if (fMethod)
       (*fMethod).Delete();
-   delete fMethod;   fMethod=0;
+   delete fMethod.load();   fMethod=0;
 
    if (fRealData)
       fRealData->Delete();

From ca8d4520277e020bd67e266a0106bc34ecb85ec0 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 26 Feb 2015 08:44:10 +0100
Subject: [PATCH 067/200] Remove "using namespace std" from header.

Found with SAS:
https://github.com/dpiparo/SAS
in particular wih this checker
https://github.com/dpiparo/SAS/blob/master/src/CodingConventions/General/UsingNamespace.h
---
 hist/hist/inc/TF1.h        |  86 +++---
 hist/hist/inc/TFormula.h   |  44 ++--
 hist/hist/src/TFormula.cxx | 518 +++++++++++++++++++------------------
 3 files changed, 324 insertions(+), 324 deletions(-)

diff --git a/hist/hist/inc/TF1.h b/hist/hist/inc/TF1.h
index 5fbd680c1f469..9024924e8ed8e 100644
--- a/hist/hist/inc/TF1.h
+++ b/hist/hist/inc/TF1.h
@@ -61,7 +61,7 @@ class TF1Parameters {
       fParNames(std::vector<std::string>(npar) )
    {
       for (int i = 0; i < npar; ++i ){
-         fParNames[i] = std::string(TString::Format("p%d",i).Data() ); 
+         fParNames[i] = std::string(TString::Format("p%d",i).Data() );
       }
    }
    // copy constructor
@@ -77,13 +77,13 @@ class TF1Parameters {
       return *this;
    }
    virtual ~TF1Parameters() {}
-   
+
    // getter methods
    Double_t GetParameter(Int_t iparam) const {
-      return (CheckIndex(iparam)) ? fParameters[iparam] : 0; 
+      return (CheckIndex(iparam)) ? fParameters[iparam] : 0;
    }
    Double_t GetParameter(const char * name) const {
-      return GetParameter(GetParNumber(name) ); 
+      return GetParameter(GetParNumber(name) );
    }
    const Double_t *GetParameters() const {
       return fParameters.data();
@@ -91,14 +91,14 @@ class TF1Parameters {
    Int_t GetParNumber(const char * name) const;
 
    const char *GetParName(Int_t iparam) const {
-      return (CheckIndex(iparam)) ? fParNames[iparam].c_str() : ""; 
+      return (CheckIndex(iparam)) ? fParNames[iparam].c_str() : "";
    }
-   
-   
-   // setter methods 
+
+
+   // setter methods
    void   SetParameter(Int_t iparam, Double_t value) {
       if (!CheckIndex(iparam)) return;
-      fParameters[iparam] = value; 
+      fParameters[iparam] = value;
    }
    void  SetParameters(const Double_t *params) {
       std::copy(params, params + fParameters.size(), fParameters.begin() );
@@ -106,30 +106,30 @@ class TF1Parameters {
    void  SetParameters(Double_t p0,Double_t p1,Double_t p2=0,Double_t p3=0,Double_t p4=0,
                                Double_t p5=0,Double_t p6=0,Double_t p7=0,Double_t p8=0,
                                Double_t p9=0,Double_t p10=0);
-   
+
    void   SetParameter(const char *name, Double_t value) {
       SetParameter(GetParNumber(name),value);
    }
    void   SetParName(Int_t iparam, const char * name) {
       if (!CheckIndex(iparam)) return;
-      fParNames[iparam] = std::string(name); 
-   } 
+      fParNames[iparam] = std::string(name);
+   }
    void   SetParNames(const char *name0="p0",const char *name1="p1",const char *name2="p2",
                       const char *name3="p3",const char*name4="p4", const char *name5="p5",
                       const char *name6="p6",const char *name7="p7",const char *name8="p8",
-                      const char *name9="p9",const char *name10="p10"); 
+                      const char *name9="p9",const char *name10="p10");
+
 
 
-   
-   ClassDef(TF1Parameters,1)   // The Parameters of a parameteric function   
+   ClassDef(TF1Parameters,1)   // The Parameters of a parameteric function
 private:
 
    bool CheckIndex(Int_t i) const {
       return (i >= 0 && i < int(fParameters.size()) );
    }
-   
+
    std::vector<Double_t> fParameters;    // parameter values
-   std::vector<std::string> fParNames;   // parameter names 
+   std::vector<std::string> fParNames;   // parameter names
 };
 
 
@@ -166,7 +166,7 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    static Bool_t fgRejectPoint;  //True if point must be rejected in a fit
    static Bool_t fgAddToGlobList; //True if we want to register the function in the global list
    static TF1   *fgCurrent;   //pointer to current function being processed
-   
+
 
    //void CreateFromFunctor(const char *name, Int_t npar, Int_t ndim = 1);
    void DoInitialize();
@@ -178,7 +178,7 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    enum {
        kNotGlobal   = BIT(10)  // don't register in global list of functions
    };
-   
+
 public:
     // TF1 status bits
     enum {
@@ -207,29 +207,29 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    template <typename Func>
    TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim = 1 ) :
       TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
-      fXmin(xmin), fXmax(xmax), 
+      fXmin(xmin), fXmax(xmax),
       fNpar(npar), fNdim(ndim),
       fNpx(100), fType(1),
-      fNpfits(0), fNDF(0), fChisquare(0),   
+      fNpfits(0), fNDF(0), fChisquare(0),
       fMinimum(-1111), fMaximum(-1111),
-      fParErrors(std::vector<Double_t>(npar)), 
-      fParMin(std::vector<Double_t>(npar)), 
-      fParMax(std::vector<Double_t>(npar)), 
+      fParErrors(std::vector<Double_t>(npar)),
+      fParMin(std::vector<Double_t>(npar)),
+      fParMax(std::vector<Double_t>(npar)),
       fParent(0), fHistogram(0),
       fMethodCall(0),
       fFunctor(ROOT::Math::ParamFunctor(f)),
       fFormula(0),
       fParams(new TF1Parameters(npar) )
    {
-      DoInitialize(); 
+      DoInitialize();
    }
    // backward compatible interface
    template <typename Func>
    TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar, const char *   ) {
       TF1 tmp(name,f,xmin,xmax,npar,1);
-      *this = tmp; 
+      *this = tmp;
    }
-   
+
 
    // Template constructors from a pointer to any C++ class of type PtrObj with a specific member function of type
    // MemFn.
@@ -242,37 +242,37 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    template <class PtrObj, typename MemFn>
    TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,Int_t ndim = 1) :
       TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
-      fXmin(xmin), fXmax(xmax), 
+      fXmin(xmin), fXmax(xmax),
       fNpar(npar), fNdim(ndim),
       fNpx(100), fType(1),
-      fNpfits(0), fNDF(0), fChisquare(0),   
+      fNpfits(0), fNDF(0), fChisquare(0),
       fMinimum(-1111), fMaximum(-1111),
-      fParErrors(std::vector<Double_t>(npar)), 
-      fParMin(std::vector<Double_t>(npar)), 
-      fParMax(std::vector<Double_t>(npar)), 
+      fParErrors(std::vector<Double_t>(npar)),
+      fParMin(std::vector<Double_t>(npar)),
+      fParMax(std::vector<Double_t>(npar)),
       fParent(0), fHistogram(0),
       fMethodCall(0),
-      fFunctor   ( ROOT::Math::ParamFunctor(p,memFn) ), 
+      fFunctor   ( ROOT::Math::ParamFunctor(p,memFn) ),
       fFormula(0),
       fParams(new TF1Parameters(npar) )
    {
-      DoInitialize(); 
+      DoInitialize();
    }
    // backward compatible interface
    template <class PtrObj, typename MemFn>
    TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,const char * , const char * ) {
       TF1 tmp(name,p, memFn,xmin,xmax,npar,1);
-      *this = tmp; 
+      *this = tmp;
    }
 
    TF1(const TF1 &f1);
    TF1& operator=(const TF1 &rhs);
    virtual   ~TF1();
    virtual void     AddParameter(const TString &name, Double_t value) { if (fFormula) fFormula->AddParameter(name,value); }
-   //virtual void     AddParameters(const pair<TString,Double_t> *pairs, Int_t size) { fFormula->AddParameters(pairs,size); } 
+   //virtual void     AddParameters(const pair<TString,Double_t> *pairs, Int_t size) { fFormula->AddParameters(pairs,size); }
    virtual void     AddVariable(const TString &name, Double_t value) { if (fFormula) fFormula->AddVariable(name,value); }
-   virtual void     AddVariables(const pair<TString,Double_t> *pairs, Int_t size) { if (fFormula) fFormula->AddVariables(pairs,size); }
-   virtual Bool_t   AddToGlobalList(Bool_t on = kTRUE); 
+   virtual void     AddVariables(const std::pair<TString,Double_t> *pairs, Int_t size) { if (fFormula) fFormula->AddVariables(pairs,size); }
+   virtual Bool_t   AddToGlobalList(Bool_t on = kTRUE);
    virtual void     Browse(TBrowser *b);
    virtual void     Copy(TObject &f1) const;
    virtual Double_t Derivative (Double_t x, Double_t *params=0, Double_t epsilon=0.001) const;
@@ -362,7 +362,7 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    }
    virtual Double_t IntegralMultiple(Int_t n, const Double_t *a, const Double_t *b, Double_t epsrel, Double_t &relerr);
    /// return kTRUE if the point is inside the function range
-   virtual Bool_t   IsInside(const Double_t *x) const { return !(  ( x[0] < fXmin) || ( x[0] > fXmax ) ); }  
+   virtual Bool_t   IsInside(const Double_t *x) const { return !(  ( x[0] < fXmin) || ( x[0] > fXmax ) ); }
    virtual Bool_t   IsLinear() const { return (fFormula) ? fFormula->IsLinear() : false;}
    virtual Bool_t   IsValid() const;
    virtual void     Print(Option_t *option="") const;
@@ -388,7 +388,7 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
       (fFormula) ? fFormula->SetParameter(name,value) : fParams->SetParameter(name,value);
    }
    virtual void     SetParameters(const Double_t *params) {
-      (fFormula) ? fFormula->SetParameters(params) : fParams->SetParameters(params); 
+      (fFormula) ? fFormula->SetParameters(params) : fParams->SetParameters(params);
    }
    virtual void     SetParameters(Double_t p0,Double_t p1,Double_t p2=0,Double_t p3=0,Double_t p4=0,
                                      Double_t p5=0,Double_t p6=0,Double_t p7=0,Double_t p8=0,
@@ -396,7 +396,7 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
       if (fFormula) fFormula->SetParameters(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
       else          fParams->SetParameters(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
    } // *MENU*
-   virtual void     SetParName(Int_t ipar, const char *name); 
+   virtual void     SetParName(Int_t ipar, const char *name);
    virtual void     SetParNames(const char *name0="p0",const char *name1="p1",const char *name2="p2",
                                 const char *name3="p3",const char *name4="p4", const char *name5="p5",
                                 const char *name6="p6",const char *name7="p7",const char *name8="p8",
@@ -435,10 +435,10 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
 inline Double_t TF1::operator()(Double_t x, Double_t y, Double_t z, Double_t t) const
    { return Eval(x,y,z,t); }
 inline Double_t TF1::operator()(const Double_t *x, const Double_t *params)
-   { 
+   {
 
       if (fMethodCall) InitArgs(x,params);
-      return EvalPar(x,params);  
+      return EvalPar(x,params);
    }
 
 
diff --git a/hist/hist/inc/TFormula.h b/hist/hist/inc/TFormula.h
index 1ad98609e0acd..c2e1b36d449ab 100644
--- a/hist/hist/inc/TFormula.h
+++ b/hist/hist/inc/TFormula.h
@@ -28,8 +28,6 @@
 #include <list>
 #include <map>
 
-using namespace std;
-
 class TFormulaFunction
 {
 public:
@@ -48,11 +46,11 @@ class TFormulaFunction
    TFormulaFunction(const TString& name)
    : fName(name),fBody(""),fNargs(0),fFound(false),fFuncCall(false){}
    Bool_t operator<(const TFormulaFunction &rhv) const
-   {  
+   {
       return fName < rhv.fName && fBody < rhv.fBody;
    }
    Bool_t operator==(const TFormulaFunction &rhv) const
-   {  
+   {
       return fName == rhv.fName && fBody == rhv.fBody && fNargs == rhv.fNargs;
    }
 };
@@ -83,11 +81,11 @@ class TFormula : public TNamed
    // All data members are transient apart from the string defining the formula and the parameter values
 
    TString           fClingInput;           //! input function passed to Cling
-   vector<Double_t>  fClingVariables;       //!  cached variables
-   vector<Double_t>  fClingParameters;      //  parameter values 
+   std::vector<Double_t>  fClingVariables;       //!  cached variables
+   std::vector<Double_t>  fClingParameters;      //  parameter values
    Bool_t            fReadyToExecute;       //!
    Bool_t            fClingInitialized;  //!  transient to force re-initialization
-   Bool_t            fAllParametersSetted;    // flag to control if all parameters are setted    
+   Bool_t            fAllParametersSetted;    // flag to control if all parameters are setted
    TMethodCall*      fMethod;        //! pointer to methocall
    TString           fClingName;     //! unique name passed to Cling to define the function ( double clingName(double*x, double*p) )
 
@@ -102,17 +100,17 @@ class TFormula : public TNamed
    void     HandleLinear(TString &formula);
    Bool_t   IsDefaultVariableName(const TString &name);
 protected:
-   
-   list<TFormulaFunction>         fFuncs;    //!
-   map<TString,TFormulaVariable>  fVars;     //!  list of  variable names
-   map<TString,Int_t>             fParams;   //!  list of  parameter names 
-   map<TString,Double_t>          fConsts;   //!  
-   map<TString,TString>           fFunctionsShortcuts;  //!
-   TString                        fFormula;     
+
+   std::list<TFormulaFunction>         fFuncs;    //!
+   std::map<TString,TFormulaVariable>  fVars;     //!  list of  variable names
+   std::map<TString,Int_t>             fParams;   //!  list of  parameter names
+   std::map<TString,Double_t>          fConsts;   //!
+   std::map<TString,TString>           fFunctionsShortcuts;  //!
+   TString                        fFormula;
    Int_t                          fNdim;  //!
    Int_t                          fNpar;  //!
    Int_t                          fNumber;  //!
-   std::vector<TObject*>          fLinearParts;  // vector of linear functions 
+   std::vector<TObject*>          fLinearParts;  // vector of linear functions
 
    Bool_t IsOperator(const char c);
    Bool_t IsBracket(const char c);
@@ -122,17 +120,17 @@ class TFormula : public TNamed
    void   ProcessFormula(TString &formula);
    Bool_t PrepareFormula(TString &formula);
    void   DoAddParameter(const TString &name, Double_t value, bool processFormula);
-   void   DoSetParameters(const Double_t * p, Int_t size); 
+   void   DoSetParameters(const Double_t * p, Int_t size);
 
    Double_t       DoEval(const Double_t * x  = nullptr, const Double_t * p = nullptr);
 
-   enum {      
+   enum {
       kNotGlobal     = BIT(10),  // don't store in gROOT->GetListOfFunction (it should be protected)
    };
 
 public:
-   
-   enum { 
+
+   enum {
       kNormalized    = BIT(14),   // set to true if the TFormula (ex gausn) is normalized
       kLinear        = BIT(16)    //set to true if the TFormula is for linear fitting
    };
@@ -142,10 +140,10 @@ class TFormula : public TNamed
    TFormula(const TString &name, TString formula, bool addToGlobList = true);
                   TFormula(const TFormula &formula);
                   TFormula(const char *name, Int_t nparams, Int_t ndims);
-   
+
    void           AddParameter(const TString &name, Double_t value) { DoAddParameter(name,value,true); }
    void           AddVariable(const TString &name, Double_t value);
-   void           AddVariables(const pair<TString,Double_t> *vars, const Int_t size);
+   void           AddVariables(const std::pair<TString,Double_t> *vars, const Int_t size);
    void           Copy(TObject &f1) const;
    Double_t       Eval(Double_t x);
    Double_t       Eval(Double_t x, Double_t y);
@@ -165,7 +163,7 @@ class TFormula : public TNamed
    void           GetParameters(Double_t *params) const;
    Double_t       GetVariable(const TString &name);
    Bool_t         IsValid() const { return fReadyToExecute; }
-   Bool_t         IsLinear() const { return TestBit(kLinear); } 
+   Bool_t         IsLinear() const { return TestBit(kLinear); }
    void           Print(Option_t *option = "") const;
    void           SetParameter(const char* name, Double_t value);
    void           SetParameter(Int_t param, Double_t value);
@@ -180,7 +178,7 @@ class TFormula : public TNamed
                              *name4="p4", const char *name5="p5",const char *name6="p6",const char *name7="p7",const char
                              *name8="p8",const char *name9="p9",const char *name10="p10"); // *MENU*
    void           SetVariable(const TString &name, Double_t value);
-   void           SetVariables(const pair<TString,Double_t> *vars, const Int_t size);
+   void           SetVariables(const std::pair<TString,Double_t> *vars, const Int_t size);
 
    ClassDef(TFormula,9)
 };
diff --git a/hist/hist/src/TFormula.cxx b/hist/hist/src/TFormula.cxx
index 4d62639d08589..beae569159782 100644
--- a/hist/hist/src/TFormula.cxx
+++ b/hist/hist/src/TFormula.cxx
@@ -26,6 +26,8 @@
 #include <cassert>
 #include <iostream>
 
+using namespace std;
+
 // #define __STDC_LIMIT_MACROS
 // #define __STDC_CONSTANT_MACROS
 
@@ -76,13 +78,13 @@ ClassImp(TFormula)
 //*-*     -  TMath::Erf(x)
 //*-*
 //*-*   Formula may contain constans, eg:
-//*-*    - sqrt2 
-//*-*    - e  
-//*-*    - pi 
-//*-*    - ln10 
+//*-*    - sqrt2
+//*-*    - e
+//*-*    - pi
+//*-*    - ln10
 //*-*    - infinity
 //*-*      and more.
-//*-*   
+//*-*
 //*-*   Comparisons operators are also supported (&&, ||, ==, <=, >=, !)
 //*-*   Examples:
 //*-*      sin(x*(x<0.5 || x>1))
@@ -103,10 +105,10 @@ ClassImp(TFormula)
 //*-*
 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
 
-// prefix used for function name passed to Cling    
+// prefix used for function name passed to Cling
 static const TString gNamePrefix = "T__";
 // function index number used to append in cling name to avoid a clash
-static int gFormulaIndex = 0; 
+static int gFormulaIndex = 0;
 
 Bool_t TFormula::IsOperator(const char c)
 {
@@ -165,21 +167,21 @@ TFormula::~TFormula()
    }
 
    if(fMethod)
-   {  
+   {
       fMethod->Delete();
    }
-   int nLinParts = fLinearParts.size(); 
-   if (nLinParts > 0) { 
-      for (int i = 0; i < nLinParts; ++i) delete fLinearParts[i]; 
+   int nLinParts = fLinearParts.size();
+   if (nLinParts > 0) {
+      for (int i = 0; i < nLinParts; ++i) delete fLinearParts[i];
    }
 }
 
 TFormula::TFormula(const char *name, Int_t nparams, Int_t ndims)
 {
-   //*-*     
+   //*-*
    //*-*  Constructor
    //*-*  When TF1 is constructed using C++ function, TF1 need space to keep parameters values.
-   //*-*  
+   //*-*
 
    fName = name;
    fTitle = "";
@@ -212,24 +214,24 @@ TFormula::TFormula(const TString &name, TString formula, bool addToGlobList)   :
    fNumber = 0;
    FillDefaults();
 
-   
-   if (addToGlobList && gROOT) { 
+
+   if (addToGlobList && gROOT) {
       TFormula *old = 0;
       R__LOCKGUARD2(gROOTMutex);
       old = dynamic_cast<TFormula*> ( gROOT->GetListOfFunctions()->FindObject(name) );
-      if (old) 
+      if (old)
          gROOT->GetListOfFunctions()->Remove(old);
       if (name == "x" || name == "y" || name == "z" || name == "t")
          Error("TFormula","The name %s is reserved as a TFormula variable name.\n",name.Data());
       else
-         gROOT->GetListOfFunctions()->Add(this);      
+         gROOT->GetListOfFunctions()->Add(this);
    }
    SetBit(kNotGlobal,!addToGlobList);
 
-   //fName = gNamePrefix + name;  // is this needed 
-   
+   //fName = gNamePrefix + name;  // is this needed
+
    PreProcessFormula(fFormula);
-   
+
    //std::cout << "formula " << GetName() << " is preprocessed " << std::endl;
    //std::cout << fFormula << std::endl;
 
@@ -258,16 +260,16 @@ TFormula::TFormula(const TFormula &formula) : TNamed(formula.GetName(),formula.G
    if (!TestBit(TFormula::kNotGlobal) && gROOT ) {
       R__LOCKGUARD2(gROOTMutex);
       TFormula *old = (TFormula*)gROOT->GetListOfFunctions()->FindObject(formula.GetName());
-      if (old) 
+      if (old)
          gROOT->GetListOfFunctions()->Remove(old);
-      
+
       if (strcmp(formula.GetName(),"x") == 0 || strcmp(formula.GetName(),"y") == 0 ||
           strcmp(formula.GetName(),"z") == 0 || strcmp(formula.GetName(),"t") == 0) {
          Error("TFormula","The name %s is reserved as a TFormula variable name.\n",formula.GetName());
-      } else 
+      } else
          gROOT->GetListOfFunctions()->Add(this);
    }
-   
+
    PreProcessFormula(fFormula);
    fClingInput = fFormula;
    PrepareFormula(fClingInput);
@@ -275,9 +277,9 @@ TFormula::TFormula(const TFormula &formula) : TNamed(formula.GetName(),formula.G
 
 TFormula& TFormula::operator=(const TFormula &rhs)
 {
-   //*-*    
-   //*-*  = Operator    
-   //*-*    
+   //*-*
+   //*-*  = Operator
+   //*-*
 
    if (this != &rhs) {
       rhs.Copy(*this);
@@ -288,7 +290,7 @@ void TFormula::Copy(TObject &obj) const
 {
    TNamed::Copy(obj);
    // need to copy also cling parameters
-   TFormula & fnew = dynamic_cast<TFormula&>(obj); 
+   TFormula & fnew = dynamic_cast<TFormula&>(obj);
 
    fnew.fClingParameters = fClingParameters;
    fnew.fClingVariables = fClingVariables;
@@ -306,20 +308,20 @@ void TFormula::Copy(TObject &obj) const
    // copy Linear parts (it is a vector of TFormula pointers) needs to be copied one by one
    // looping at all the elements
    // delete first previous elements
-   int nLinParts = fnew.fLinearParts.size(); 
-   if (nLinParts > 0) { 
-      for (int i = 0; i < nLinParts; ++i) delete fnew.fLinearParts[i]; 
+   int nLinParts = fnew.fLinearParts.size();
+   if (nLinParts > 0) {
+      for (int i = 0; i < nLinParts; ++i) delete fnew.fLinearParts[i];
       fnew.fLinearParts.clear();
    }
-   // old size that needs to be copied 
+   // old size that needs to be copied
    nLinParts = fLinearParts.size();
-   if (nLinParts > 0) { 
+   if (nLinParts > 0) {
       fnew.fLinearParts.reserve(nLinParts);
       for (int i = 0; i < nLinParts; ++i) {
          TFormula * linearNew = new TFormula();
          TFormula * linearOld = (TFormula*) fLinearParts[i];
          if (linearOld) {
-            linearOld->Copy(*linearNew); 
+            linearOld->Copy(*linearNew);
             fnew.fLinearParts.push_back(linearNew);
          }
          else
@@ -345,11 +347,11 @@ void TFormula::Copy(TObject &obj) const
 }
 void TFormula::PrepareEvalMethod()
 {
-   //*-*    
+   //*-*
    //*-*    Sets TMethodCall to function inside Cling environment
    //*-*    TFormula uses it to execute function.
-   //*-*    After call, TFormula should be ready to evaluate formula.   
-   //*-*    
+   //*-*    After call, TFormula should be ready to evaluate formula.
+   //*-*
    if(!fMethod)
    {
       fMethod = new TMethodCall();
@@ -377,7 +379,7 @@ void TFormula::PrepareEvalMethod()
          return ;
       }
 
-      // not needed anymore since we use the function pointer 
+      // not needed anymore since we use the function pointer
       // if(hasParameters)
       // {
       //    Long_t args[2];
@@ -394,15 +396,15 @@ void TFormula::PrepareEvalMethod()
 
       CallFunc_t * callfunc = fMethod->GetCallFunc();
       TInterpreter::CallFuncIFacePtr_t faceptr = gCling->CallFunc_IFacePtr(callfunc);
-      fFuncPtr = faceptr.fGeneric; 
+      fFuncPtr = faceptr.fGeneric;
    }
 }
 
 void TFormula::InputFormulaIntoCling()
 {
-   //*-*    
+   //*-*
    //*-*    Inputs formula, transfered to C++ code into Cling
-   //*-*    
+   //*-*
    if(!fClingInitialized && fReadyToExecute && fClingInput.Length() > 0)
    {
       char rawInputOn[]  = ".rawInput 1";
@@ -413,38 +415,38 @@ void TFormula::InputFormulaIntoCling()
       PrepareEvalMethod();
       fClingInitialized = true;
 
-      // // store function pointer 
+      // // store function pointer
       // TString funcAddress = "&" + TString(GetName() );
       // cling::StoredValueRef valref;
       // cling::runtime::gCling->evaluate(funcAddress,valref);
       // typedef Double_t (* FuncPointerType)(Double_t *, Double_t *);
       // void * ptr = valref.get().getAs(&ptr);
-      // FuncPointerType fFuncPointer = (FuncPointerType) ptr; 
+      // FuncPointerType fFuncPointer = (FuncPointerType) ptr;
    }
 }
 void TFormula::FillDefaults()
 {
-   //*-* 
+   //*-*
    //*-*    Fill structures with default variables, constants and function shortcuts
-   //*-*    
+   //*-*
 //#ifdef ROOT_CPLUSPLUS11
-   
+
    const TString defvars[] = { "x","y","z","t"};
    const pair<TString,Double_t> defconsts[] = { {"pi",TMath::Pi()}, {"sqrt2",TMath::Sqrt2()},
          {"infinity",TMath::Infinity()}, {"e",TMath::E()}, {"ln10",TMath::Ln10()},
-         {"loge",TMath::LogE()}, {"c",TMath::C()}, {"g",TMath::G()}, 
+         {"loge",TMath::LogE()}, {"c",TMath::C()}, {"g",TMath::G()},
          {"h",TMath::H()}, {"k",TMath::K()},{"sigma",TMath::Sigma()},
-         {"r",TMath::R()}, {"eg",TMath::EulerGamma()},{"true",1},{"false",0} }; 
+         {"r",TMath::R()}, {"eg",TMath::EulerGamma()},{"true",1},{"false",0} };
    const pair<TString,TString> funShortcuts[] = { {"sin","TMath::Sin" },
          {"cos","TMath::Cos" }, {"exp","TMath::Exp"}, {"log","TMath::Log"}, {"log10","TMath::Log10"},
          {"tan","TMath::Tan"}, {"sinh","TMath::SinH"}, {"cosh","TMath::CosH"},
          {"tanh","TMath::TanH"}, {"asin","TMath::ASin"}, {"acos","TMath::ACos"},
          {"atan","TMath::ATan"}, {"atan2","TMath::ATan2"}, {"sqrt","TMath::Sqrt"},
          {"ceil","TMath::Ceil"}, {"floor","TMath::Floor"}, {"pow","TMath::Power"},
-         {"binomial","TMath::Binomial"},{"abs","TMath::Abs"} }; 
+         {"binomial","TMath::Binomial"},{"abs","TMath::Abs"} };
 
    std::vector<TString> defvars2(10);
-   for (int i = 0; i < 9; ++i) 
+   for (int i = 0; i < 9; ++i)
       defvars2[i] = TString::Format("x[%d]",i);
 
    for(auto var : defvars)
@@ -454,7 +456,7 @@ void TFormula::FillDefaults()
       fClingVariables.push_back(0);
    }
    // add also the variables definesd like x[0],x[1],x[2],...
-   // support up to x[9] - if needed extend that to higher value 
+   // support up to x[9] - if needed extend that to higher value
    // const int maxdim = 10;
    // for (int i = 0; i < maxdim;  ++i) {
    //    TString xvar = TString::Format("x[%d]",i);
@@ -471,7 +473,7 @@ void TFormula::FillDefaults()
       fFunctionsShortcuts[fun.first] = fun.second;
    }
 
-/*** - old code tu support C++03 
+/*** - old code tu support C++03
 #else
 
    TString  defvarsNames[] = {"x","y","z","t"};
@@ -487,7 +489,7 @@ void TFormula::FillDefaults()
    TString  funShortcutsExtendedNames[] = {"TMath::Sin","TMath::Cos","TMath::Exp","TMath::Log","TMath::Tan","TMath::SinH",
                                            "TMath::CosH","TMath::TanH","TMath::ASin","TMath::ACos","TMath::ATan","TMath::ATan2",
                                            "TMath::Sqrt","TMath::Ceil","TMath::Floor","TMath::Power","TMath::Binomial","TMath::Abs"};
-   Int_t    funShortcutsLength = sizeof(funShortcutsNames)/sizeof(TString);                                           
+   Int_t    funShortcutsLength = sizeof(funShortcutsNames)/sizeof(TString);
 
    for(Int_t i = 0; i < defvarsLength; ++i)
    {
@@ -508,20 +510,20 @@ void TFormula::FillDefaults()
       fFunctionsShortcuts[fun.first] = fun.second;
    }
 
-#endif 
+#endif
 ***/
 
 }
 
 void TFormula::HandlePolN(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Handling polN
    //*-*    If before 'pol' exist any name, this name will be treated as variable used in polynomial
    //*-*    eg.
    //*-*    varpol2(5) will be replaced with: [5] + [6]*var + [7]*var^2
    //*-*    Empty name is treated like variable x.
-   //*-*    
+   //*-*
    Int_t polPos = formula.Index("pol");
    while(polPos != kNPOS)
    {
@@ -536,7 +538,7 @@ void TFormula::HandlePolN(TString &formula)
       if(!defaultCounter)
       {
           degree = TString(formula(polPos + 3,openingBracketPos - polPos - 3)).Atoi();
-          counter = TString(formula(openingBracketPos+1,formula.Index(')',polPos) - openingBracketPos)).Atoi(); 
+          counter = TString(formula(openingBracketPos+1,formula.Index(')',polPos) - openingBracketPos)).Atoi();
       }
       else
       {
@@ -584,33 +586,33 @@ void TFormula::HandlePolN(TString &formula)
       }
       else
       {
-         pattern = TString::Format("%spol%d(%d)",(defaultVariable ? "" : variable.Data()),degree,counter);   
+         pattern = TString::Format("%spol%d(%d)",(defaultVariable ? "" : variable.Data()),degree,counter);
       }
-      
+
       formula.ReplaceAll(pattern,replacement);
       polPos = formula.Index("pol");
    }
 }
 void TFormula::HandleParametrizedFunctions(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Handling parametrized functions
    //*-*    Function can be normalized, and have different variable then x.
    //*-*    Variables should be placed in brackets after function name.
    //*-*    No brackets are treated like [x].
    //*-*    Normalized function has char 'n' after name, eg.
    //*-*    gausn[var](0) will be replaced with [0]*exp(-0.5*((var-[1])/[2])^2)/(sqrt(2*pi)*[2])
-   //*-*    
+   //*-*
    //*-*    Adding function is easy, just follow these rules:
    //*-*    - Key for function map is pair of name and dimension of function
    //*-*    - value of key is a pair function body and normalized function body
    //*-*    - {Vn} is a place where variable appear, n represents n-th variable from variable list.
    //*-*      Count starts from 0.
-   //*-*    - [num] stands for parameter number. 
+   //*-*    - [num] stands for parameter number.
    //*-*      If user pass to function argument 5, num will stand for (5 + num) parameter.
-   //*-*    
+   //*-*
 
-   map< pair<TString,Int_t> ,pair<TString,TString> > functions; 
+   map< pair<TString,Int_t> ,pair<TString,TString> > functions;
    functions.insert(make_pair(make_pair("gaus",1),make_pair("[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))","[0]*exp(-0.5*(({V0}-[1])/[2])*(({V0}-[1])/[2]))/(sqrt(2*pi)*[2])")));
    functions.insert(make_pair(make_pair("landau",1),make_pair("[0]*TMath::Landau({V0},[1],[2],false)","[0]*TMath::Landau({V0},[1],[2],true)")));
    functions.insert(make_pair(make_pair("expo",1),make_pair("exp([0]+[1]*{V0})","")));
@@ -629,14 +631,14 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
    formula.ReplaceAll("xylandau","landau[x,y]");
    formula.ReplaceAll("xyexpo","expo[x,y]");
 
-   for(map<pair<TString,Int_t>,pair<TString,TString> >::iterator it = functions.begin(); it != functions.end(); ++it) 
+   for(map<pair<TString,Int_t>,pair<TString,TString> >::iterator it = functions.begin(); it != functions.end(); ++it)
    {
 
       TString funName = it->first.first;
       Int_t funPos = formula.Index(funName);
 
-     
- 
+
+
       //std::cout << formula << " ---- " << funName << "  " << funPos << std::endl;
       while(funPos != kNPOS)
       {
@@ -654,18 +656,18 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
                break;
             }
          }
-         
-         Bool_t isNormalized = false; 
-         if (lastFunPos < formula.Length() ) { 
+
+         Bool_t isNormalized = false;
+         if (lastFunPos < formula.Length() ) {
             // check if function is normalized by looking at "n" character after function name (e.g. gausn)
             isNormalized = (formula[lastFunPos] == 'n');
-            if (isNormalized) lastFunPos += 1; 
+            if (isNormalized) lastFunPos += 1;
             if (lastFunPos < formula.Length() ) {
                // check if also last character is not alphanumeric or a digit
-               if (isalnum(formula[lastFunPos] ) ) break; 
-               if (formula[lastFunPos] != '[' && formula[lastFunPos] != '(' && ! IsOperator(formula[lastFunPos] ) ) { 
+               if (isalnum(formula[lastFunPos] ) ) break;
+               if (formula[lastFunPos] != '[' && formula[lastFunPos] != '(' && ! IsOperator(formula[lastFunPos] ) ) {
                   funPos = formula.Index(funName,lastFunPos);
-                  continue; 
+                  continue;
                }
             }
          }
@@ -690,7 +692,7 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
             variables[0] = "x";
             defaultVariable = true;
          }
-         else 
+         else
          {
             // in case of [..] found, assume they specify all the variables. Use it to get function dimension
             closingBracketPos = formula.Index(']',openingBracketPos);
@@ -710,14 +712,14 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
                   variables[Nvar] = varName;
                   varName = "";
                   Nvar++;
-               }  
+               }
             }
             if(varName != "") // we will miss last variable
             {
                variables[Nvar] = varName;
             }
          }
-         // chech if dimension obtained from [...] is compatible with existing pre-defined functions 
+         // chech if dimension obtained from [...] is compatible with existing pre-defined functions
          if(dim != it->first.second)
          {
             pair<TString,Int_t> key = make_pair(funName,dim);
@@ -729,7 +731,7 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
             break;
          }
          // look now for the (..) brackets to get the parameter counter (e.g. gaus(0) + gaus(3) )
-         // need to start for a position 
+         // need to start for a position
          Int_t openingParenthesisPos = (closingBracketPos == kNPOS) ? openingBracketPos : closingBracketPos + 1;
          bool defaultCounter = (openingParenthesisPos > formula.Length() || formula[openingParenthesisPos] != '(');
 
@@ -738,13 +740,13 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
          Int_t counter;
          if(defaultCounter)
          {
-            counter = 0;           
+            counter = 0;
          }
          else
          {
-            counter = TString(formula(openingParenthesisPos+1,formula.Index(')',funPos) - openingParenthesisPos -1)).Atoi(); 
+            counter = TString(formula(openingParenthesisPos+1,formula.Index(')',funPos) - openingParenthesisPos -1)).Atoi();
          }
-         //std::cout << "openingParenthesisPos  " << openingParenthesisPos << " counter is " << counter <<  std::endl; 
+         //std::cout << "openingParenthesisPos  " << openingParenthesisPos << " counter is " << counter <<  std::endl;
 
          TString body = (isNormalized ? it->second.second : it->second.first);
          if(isNormalized && body == "")
@@ -767,7 +769,7 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
             }
             else if(body[i] == '[')
             {
-               // update parameter counters in case of many functions (e.g. gaus(0)+gaus(3) ) 
+               // update parameter counters in case of many functions (e.g. gaus(0)+gaus(3) )
                Int_t tmp = i;
                while(tmp < body.Length() && body[tmp] != ']')
                {
@@ -776,7 +778,7 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
                Int_t num = TString(body(i+1,tmp - 1 - i)).Atoi();
                num += counter;
                TString replacement = TString::Format("%d",num);
-              
+
                body.Replace(i+1,tmp - 1 - i,replacement,replacement.Length());
                i += replacement.Length() + 1;
             }
@@ -811,7 +813,7 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
                            counter);
          }
          TString replacement = body;
-         
+
          formula.Replace(funPos,pattern.Length(),replacement,replacement.Length());
 
          funPos = formula.Index(funName);
@@ -821,11 +823,11 @@ void TFormula::HandleParametrizedFunctions(TString &formula)
 }
 void TFormula::HandleExponentiation(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Handling exponentiation
    //*-*    Can handle multiple carets, eg.
-   //*-*    2^3^4 will be treated like 2^(3^4)    
-   //*-*    
+   //*-*    2^3^4 will be treated like 2^(3^4)
+   //*-*
    Int_t caretPos = formula.Last('^');
    while(caretPos != kNPOS)
    {
@@ -888,19 +890,19 @@ void TFormula::HandleLinear(TString &formula)
 {
    formula.ReplaceAll("++","@");
    Int_t linPos = formula.Index("@");
-   if (linPos == kNPOS ) return;  // function is not linear 
+   if (linPos == kNPOS ) return;  // function is not linear
    Int_t NofLinParts = formula.CountChar((int)'@');
-   assert(NofLinParts > 0); 
+   assert(NofLinParts > 0);
    fLinearParts.reserve(NofLinParts + 1);
    Int_t Nlinear = 0;
-   bool first = true; 
+   bool first = true;
    while(linPos != kNPOS)
    {
       SetBit(kLinear,1);
       // analyze left part only the first time
-      Int_t temp = 0; 
-      TString left; 
-      if (first) { 
+      Int_t temp = 0;
+      TString left;
+      if (first) {
          temp = linPos - 1;
          while(temp >= 0 && formula[temp] != '@')
          {
@@ -918,9 +920,9 @@ void TFormula::HandleLinear(TString &formula)
       TString pattern     = (first) ? TString::Format("%s@%s",left.Data(),right.Data()) : TString::Format("@%s",right.Data());
       TString replacement = (first) ? TString::Format("([%d]*(%s))+([%d]*(%s))",Nlinear,left.Data(),Nlinear+1,right.Data()) : TString::Format("+([%d]*(%s))",Nlinear,right.Data());
       Nlinear += (first) ? 2 : 1;
-         
+
       formula.ReplaceAll(pattern,replacement);
-      if (first) { 
+      if (first) {
          TFormula *lin1 = new TFormula("__linear1",left,false);
          fLinearParts.push_back(lin1);
       }
@@ -928,21 +930,21 @@ void TFormula::HandleLinear(TString &formula)
       fLinearParts.push_back(lin2);
 
       linPos = formula.Index("@");
-      first = false; 
+      first = false;
    }
 }
 
 void TFormula::PreProcessFormula(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Preprocessing of formula
    //*-*    Replace all ** by ^, and removes spaces.
    //*-*    Handle also parametrized functions like polN,gaus,expo,landau
    //*-*    and exponentiation.
    //*-*    Similar functionality should be added here.
-   //*-*    
+   //*-*
    formula.ReplaceAll("**","^");
-   formula.ReplaceAll(" ",""); 
+   formula.ReplaceAll(" ","");
    HandlePolN(formula);
    HandleParametrizedFunctions(formula);
    HandleExponentiation(formula);
@@ -952,17 +954,17 @@ Bool_t TFormula::PrepareFormula(TString &formula)
 {
    fFuncs.clear();
    fReadyToExecute = false;
-   ExtractFunctors(formula);   
+   ExtractFunctors(formula);
 
    // update the expression with the new formula
    fFormula = formula;
    // replace all { and }
    fFormula.ReplaceAll("{","");
    fFormula.ReplaceAll("}","");
-   
+
    //std::cout << "functors are extracted formula is " << std::endl;
    //std::cout << fFormula << std::endl << std::endl;
-   
+
    fFuncs.sort();
    fFuncs.unique();
 
@@ -971,7 +973,7 @@ Bool_t TFormula::PrepareFormula(TString &formula)
 }
 void TFormula::ExtractFunctors(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Extracts functors from formula, and put them in fFuncs.
    //*-*    Simple grammar:
    //*-*    <function>  := name(arg1,arg2...)
@@ -980,7 +982,7 @@ void TFormula::ExtractFunctors(TString &formula)
    //*-*    <name>      := String containing lower and upper letters, numbers, underscores
    //*-*    <number>    := Integer number
    //*-*    Operators are omitted.
-   //*-*    
+   //*-*
    TString name = "";
    TString body = "";
    for(Int_t i = 0 ; i < formula.Length(); ++i )
@@ -1005,13 +1007,13 @@ void TFormula::ExtractFunctors(TString &formula)
          continue;
       }
       // case of strings
-      if (formula[i] == '\"') { 
+      if (formula[i] == '\"') {
          // look for next instance of "\"
          do {
             i++;
          } while(formula[i] != '\"');
       }
-      if(isalpha(formula[i]) && !IsOperator(formula[i])) 
+      if(isalpha(formula[i]) && !IsOperator(formula[i]))
       {
          //std::cout << "character : " << i << " " << formula[i] << " is not an operator and is alpha " << std::endl;
 
@@ -1026,7 +1028,7 @@ void TFormula::ExtractFunctors(TString &formula)
             {
                fFuncs.push_back(TFormulaFunction(name,body,0));
                name = body = "";
-               continue;  
+               continue;
             }
             Int_t depth = 1;
             Int_t args  = 1; // we will miss first argument
@@ -1047,7 +1049,7 @@ void TFormula::ExtractFunctors(TString &formula)
             ExtractFunctors(body);
             formula.Replace(i-originalBodyLen,originalBodyLen,body,body.Length());
             i += body.Length() - originalBodyLen;
-            fFuncs.push_back(TFormulaFunction(name,body,args));         
+            fFuncs.push_back(TFormulaFunction(name,body,args));
          }
          else
          {
@@ -1056,14 +1058,14 @@ void TFormula::ExtractFunctors(TString &formula)
 
             // check if function is provided by gROOT
             TObject *obj = gROOT->GetListOfFunctions()->FindObject(name);
-            TFormula * f = dynamic_cast<TFormula*> (obj);  
+            TFormula * f = dynamic_cast<TFormula*> (obj);
             if (!f) {
                // maybe object is a TF1
                TF1 * f1 = dynamic_cast<TF1*> (obj);
                if (f1) f = f1->GetFormula();
             }
-            if (f) { 
-               TString replacementFormula = f->GetExpFormula(); 
+            if (f) {
+               TString replacementFormula = f->GetExpFormula();
                // analyze expression string
                //std::cout << "formula to replace for " << f->GetName() << " is " << replacementFormula << std::endl;
                PreProcessFormula(replacementFormula);
@@ -1071,13 +1073,13 @@ void TFormula::ExtractFunctors(TString &formula)
                // I need to replace all the terms in the functor for backward compatibility of the case
                // f1("[0]*x") f2("[0]*x") f1+f2 - it is weird but it is better to support
                //std::cout << "current number of parameter is " << fNpar << std::endl;
-               int nparOffset = 0; 
+               int nparOffset = 0;
                //if (fParams.find("0") != fParams.end() ) {
                // do in any case if parameters are existing
-               if (fNpar > 0) { 
+               if (fNpar > 0) {
                   nparOffset = fNpar;
                   // start from higher number to avoid overlap
-                  for (int jpar = f->GetNpar()-1; jpar >= 0; --jpar ) { 
+                  for (int jpar = f->GetNpar()-1; jpar >= 0; --jpar ) {
                      TString oldName = TString::Format("[%s]",f->GetParName(jpar));
                      TString newName = TString::Format("[%d]",nparOffset+jpar);
                      //std::cout << "replace - parameter " << f->GetParName(jpar) << " with " <<  newName << std::endl;
@@ -1087,15 +1089,15 @@ void TFormula::ExtractFunctors(TString &formula)
                }
                ExtractFunctors(replacementFormula);
                //std::cout << "after re-extracting functors " << replacementFormula << std::endl;
-                                 
+
                // set parameter value from replacement formula
-               for (int jpar = 0; jpar < f->GetNpar(); ++jpar) { 
-                  if (nparOffset> 0) { 
+               for (int jpar = 0; jpar < f->GetNpar(); ++jpar) {
+                  if (nparOffset> 0) {
                      // parameter have an offset- so take this into accound
                      TString newName = TString::Format("%d",nparOffset+jpar);
                      SetParameter(newName,  f->GetParameter(jpar) );
                   }
-                  else 
+                  else
                      // names are the same between current formula and replaced one
                      SetParameter(f->GetParName(jpar),  f->GetParameter(jpar) );
                }
@@ -1108,11 +1110,11 @@ void TFormula::ExtractFunctors(TString &formula)
 
                // we have extracted all the functor for "fname"
                //std::cout << " i = " << i << " f[i] = " << formula[i] << " - " << formula << std::endl;
-               
+
                continue;
             }
 
-            // add now functor in 
+            // add now functor in
             TString replacement = TString::Format("{%s}",name.Data());
             formula.Replace(i-name.Length(),name.Length(),replacement,replacement.Length());
             i += 2;
@@ -1120,12 +1122,12 @@ void TFormula::ExtractFunctors(TString &formula)
          }
       }
       name = body = "";
-      
+
    }
 }
 void TFormula::ProcessFormula(TString &formula)
 {
-   //*-*    
+   //*-*
    //*-*    Iterates through funtors in fFuncs and performs the appropriate action.
    //*-*    If functor has 0 arguments (has only name) can be:
    //*-*     - variable
@@ -1143,14 +1145,14 @@ void TFormula::ProcessFormula(TString &formula)
    //*-*       * first check if function exists, and has same number of arguments, then accept it and set as found.
    //*-*    If all functors after iteration are matched with corresponding action,
    //*-*    it inputs C++ code of formula into cling, and sets flag that formula is ready to evaluate.
-   //*-*    
+   //*-*
 
    //std::cout << "Begin: formula is " << formula << " list of functors " << fFuncs.size() << std::endl;
 
    for(list<TFormulaFunction>::iterator funcsIt = fFuncs.begin(); funcsIt != fFuncs.end(); ++funcsIt)
    {
       TFormulaFunction & fun = *funcsIt;
-      
+
       //std::cout << "fun is " << fun.GetName() << std::endl;
 
       if(fun.fFound)
@@ -1168,12 +1170,12 @@ void TFormula::ProcessFormula(TString &formula)
          if(fun.fName.Contains("::")) // add support for nested namespaces
          {
             // look for last occurence of "::"
-            std::string name(fun.fName); 
+            std::string name(fun.fName);
             size_t index = name.rfind("::");
-            assert(index != std::string::npos);               
-            TString className = fun.fName(0,fun.fName(0,index).Length());           
+            assert(index != std::string::npos);
+            TString className = fun.fName(0,fun.fName(0,index).Length());
             TString functionName = fun.fName(index + 2, fun.fName.Length());
-                                                   
+
             Bool_t silent = true;
             TClass *tclass = new TClass(className,silent);
             // std::cout << "looking for class " << className << std::endl;
@@ -1184,7 +1186,7 @@ void TFormula::ProcessFormula(TString &formula)
             {
                if (strcmp(p->GetName(),functionName.Data()) == 0  &&
                    (fun.GetNargs() <=  p->GetNargs() && fun.GetNargs() >=  p->GetNargs() - p->GetNargsOpt() ) )
-               { 
+               {
                   fun.fFound = true;
                   break;
                }
@@ -1196,11 +1198,11 @@ void TFormula::ProcessFormula(TString &formula)
             TFunction * f = (TFunction*) gROOT->GetListOfGlobalFunctions(true)->FindObject(fun.fName);
             // if found a function with matching arguments
             if (f && fun.GetNargs() <=  f->GetNargs() && fun.GetNargs() >=  f->GetNargs() - f->GetNargsOpt() )
-            { 
+            {
                fun.fFound = true;
             }
          }
-               
+
          if(!fun.fFound)
          {
             Error("TFormula","Could not find %s function with %d argument(s)",fun.GetName(),fun.GetNargs());
@@ -1211,7 +1213,7 @@ void TFormula::ProcessFormula(TString &formula)
          TFormula *old = (TFormula*)gROOT->GetListOfFunctions()->FindObject(gNamePrefix + fun.fName);
          if(old)
          {
-            // we should not go here (this analysis is done before in ExtractFunctors) 
+            // we should not go here (this analysis is done before in ExtractFunctors)
             assert(false);
             fun.fFound = true;
             TString pattern = TString::Format("{%s}",fun.GetName());
@@ -1223,7 +1225,7 @@ void TFormula::ProcessFormula(TString &formula)
          }
          // looking for default variables defined in fVars
          map<TString,TFormulaVariable>::iterator varsIt = fVars.find(fun.GetName());
-         if(varsIt!= fVars.end()) 
+         if(varsIt!= fVars.end())
          {
             TString name = (*varsIt).second.GetName();
             Double_t value = (*varsIt).second.fValue;
@@ -1232,53 +1234,53 @@ void TFormula::ProcessFormula(TString &formula)
             {
                fVars[name].fFound = true;
                int varDim =  (*varsIt).second.fArrayPos;  // variable dimenions (0 for x, 1 for y, 2, for z)
-               if (varDim >= fNdim) { 
+               if (varDim >= fNdim) {
                   fNdim = varDim+1;
-                  // we need to be sure that all other variables are added with position less 
-                  for ( auto &v : fVars) { 
-                     if (v.second.fArrayPos < varDim && !v.second.fFound ) {                         
+                  // we need to be sure that all other variables are added with position less
+                  for ( auto &v : fVars) {
+                     if (v.second.fArrayPos < varDim && !v.second.fFound ) {
                         AddVariable(v.first, v.second.fValue);
-                        v.second.fFound = true; 
+                        v.second.fFound = true;
                      }
                   }
-               } 
+               }
             }
             // remove the "{.. }" added around the variable
-            TString pattern = TString::Format("{%s}",name.Data());   
+            TString pattern = TString::Format("{%s}",name.Data());
             TString replacement = TString::Format("x[%d]",(*varsIt).second.fArrayPos);
             formula.ReplaceAll(pattern,replacement);
 
             //std::cout << "Found an observable for " << fun.GetName()  << std::endl;
-              
-            fun.fFound = true; 
-            continue;          
+
+            fun.fFound = true;
+            continue;
          }
          // check for observables defined as x[0],x[1],....
          // maybe could use a regular expression here
          // only in case match with defined variables is not successfull
-         TString funname = fun.GetName(); 
-         if (funname.Contains("x[") && funname.Contains("]") ) { 
+         TString funname = fun.GetName();
+         if (funname.Contains("x[") && funname.Contains("]") ) {
             TString sdigit = funname(2,funname.Index("]") );
-            int digit = sdigit.Atoi(); 
-            if (digit >= fNdim) { 
+            int digit = sdigit.Atoi();
+            if (digit >= fNdim) {
                fNdim = digit+1;
                // we need to add the variables in fVars all of them before x[n]
-               for (int j = 0; j < fNdim; ++j) { 
+               for (int j = 0; j < fNdim; ++j) {
                   TString vname = TString::Format("x[%d]",j);
-                     if (fVars.find(vname) == fVars.end() ) { 
-                        fVars[vname] = TFormulaVariable(vname,0,j);  
+                     if (fVars.find(vname) == fVars.end() ) {
+                        fVars[vname] = TFormulaVariable(vname,0,j);
                         fVars[vname].fFound = true;
                         AddVariable(vname,0.);
                      }
                }
             }
             //std::cout << "Found matching observable for " << funname  << std::endl;
-            fun.fFound = true; 
+            fun.fFound = true;
             // remove the "{.. }" added around the variable
-            TString pattern = TString::Format("{%s}",funname.Data());   
+            TString pattern = TString::Format("{%s}",funname.Data());
             formula.ReplaceAll(pattern,funname);
             continue;
-         } 
+         }
          //}
 
          auto paramsIt = fParams.find(fun.GetName());
@@ -1293,7 +1295,7 @@ void TFormula::ProcessFormula(TString &formula)
                TString replacement = TString::Format("p[%d]",(*paramsIt).second);
                //std::cout << "replace pattern  " << pattern << " with " << replacement << std::endl;
                formula.ReplaceAll(pattern,replacement);
-               
+
             }
             fun.fFound = true;
             continue;
@@ -1313,7 +1315,7 @@ void TFormula::ProcessFormula(TString &formula)
             //std::cout << "constant with name " << fun.GetName() << " is found " << std::endl;
             continue;
          }
-         
+
 
          fun.fFound = false;
       }
@@ -1330,7 +1332,7 @@ void TFormula::ProcessFormula(TString &formula)
          break;
       }
    }
-   
+
    if(!fReadyToExecute && allFunctorsMatched)
    {
       fReadyToExecute = true;
@@ -1341,31 +1343,31 @@ void TFormula::ProcessFormula(TString &formula)
          fAllParametersSetted = true;
       }
       // assume a function without variables is always 1-dimensional
-      if (hasParameters && ! hasVariables) { 
-         fNdim = 1; 
+      if (hasParameters && ! hasVariables) {
+         fNdim = 1;
          AddVariable("x",0);
-         hasVariables = true; 
+         hasVariables = true;
       }
       Bool_t hasBoth = hasVariables && hasParameters;
       Bool_t inputIntoCling = (formula.Length() > 0);
-      TString argumentsPrototype = 
+      TString argumentsPrototype =
          TString::Format("%s%s%s",(hasVariables ? "Double_t *x" : ""), (hasBoth ? "," : ""),
                         (hasParameters  ? "Double_t *p" : ""));
-     
+
       // hack for function names created with ++ in doing linear fitter. In this case use a different name
-      // shuld make to all the case where special operator character are use din the name 
+      // shuld make to all the case where special operator character are use din the name
       if (fClingName.Contains("++") )
          fClingName = gNamePrefix + TString("linearFunction_of_") + fClingName;
       else
          fClingName = gNamePrefix + fName;
-      
+
       fClingName.ReplaceAll(" ",""); // remove also white space from function name;
       // remova also parenthesis
       fClingName.ReplaceAll("(","_");
       fClingName.ReplaceAll(")","_");
       // remove also operators
-      fClingName.ReplaceAll("++","_and_"); // for linear function 
-      fClingName.ReplaceAll("+","_plus_"); 
+      fClingName.ReplaceAll("++","_and_"); // for linear function
+      fClingName.ReplaceAll("+","_plus_");
       fClingName.ReplaceAll("-","_minus_");
       fClingName.ReplaceAll("*","_times_");
       fClingName.ReplaceAll("/","_div_");
@@ -1392,18 +1394,18 @@ void TFormula::ProcessFormula(TString &formula)
       }
 
    }
-   // clean up un-used default variables 
-   auto itvar = fVars.begin(); 
+   // clean up un-used default variables
+   auto itvar = fVars.begin();
    do
    {
       if ( ! itvar->second.fFound ) {
          //std::cout << "Erase variable " << itvar->first << std::endl;
          itvar = fVars.erase(itvar);
       }
-      else 
+      else
          itvar++;
    }
-   while( itvar != fVars.end() ); 
+   while( itvar != fVars.end() );
 
 }
 const TObject* TFormula::GetLinearPart(Int_t i) const
@@ -1412,7 +1414,7 @@ const TObject* TFormula::GetLinearPart(Int_t i) const
 
    if (!fLinearParts.empty()) {
       int n = fLinearParts.size();
-      if (i < 0 || i >= n ) { 
+      if (i < 0 || i >= n ) {
          Error("GetLinearPart","Formula %s has only %d linear parts - requested %d",GetName(),n,i);
          return nullptr;
       }
@@ -1422,16 +1424,16 @@ const TObject* TFormula::GetLinearPart(Int_t i) const
 }
 void TFormula::AddVariable(const TString &name, Double_t value)
 {
-   //*-*    
+   //*-*
    //*-*    Adds variable to known variables, and reprocess formula.
-   //*-*    
-   
+   //*-*
+
    if(fVars.find(name) != fVars.end() )
    {
       TFormulaVariable & var = fVars[name];
       var.fValue = value;
-      
-      // If the position is not defined in the Cling vectors, make space for it 
+
+      // If the position is not defined in the Cling vectors, make space for it
       // but normally is variable is defined in fVars a slot should be also present in fClingVariables
       if(var.fArrayPos < 0)
       {
@@ -1454,13 +1456,13 @@ void TFormula::AddVariable(const TString &name, Double_t value)
 }
 void TFormula::AddVariables(const pair<TString,Double_t> *vars, const Int_t size)
 {
-   //*-*    
+   //*-*
    //*-*    Adds multiple variables.
    //*-*    First argument is an array of pairs<TString,Double>, where
    //*-*    first argument is name of variable,
    //*-*    second argument represents value.
    //*-*    size - number of variables passed in first argument
-   //*-*    
+   //*-*
 
    Bool_t anyNewVar = false;
    for(Int_t i = 0 ; i < size; ++i)
@@ -1501,7 +1503,7 @@ void TFormula::AddVariables(const pair<TString,Double_t> *vars, const Int_t size
 }
 void TFormula::SetVariables(const pair<TString,Double_t> *vars, const Int_t size)
 {
-   //*-*    
+   //*-*
    //*-*    Sets multiple variables.
    //*-*    First argument is an array of pairs<TString,Double>, where
    //*-*    first argument is name of variable,
@@ -1515,7 +1517,7 @@ void TFormula::SetVariables(const pair<TString,Double_t> *vars, const Int_t size
       {
          fVars[v.first].fValue = v.second;
          fClingVariables[fVars[v.first].fArrayPos] = v.second;
-      }  
+      }
       else
       {
          Error("SetVariables","Variable %s is not defined.",v.first.Data());
@@ -1525,9 +1527,9 @@ void TFormula::SetVariables(const pair<TString,Double_t> *vars, const Int_t size
 
 Double_t TFormula::GetVariable(const TString &name)
 {
-   //*-*    
+   //*-*
    //*-*    Returns variable value.
-   //*-*    
+   //*-*
    if(fVars.find(name) == fVars.end())
    {
       Error("GetVariable","Variable %s is not defined.",name.Data());
@@ -1537,9 +1539,9 @@ Double_t TFormula::GetVariable(const TString &name)
 }
 void TFormula::SetVariable(const TString &name, Double_t value)
 {
-   //*-*    
+   //*-*
    //*-*    Sets variable value.
-   //*-*    
+   //*-*
    if(fVars.find(name) == fVars.end())
    {
       Error("SetVariable","Variable %s is not defined.",name.Data());
@@ -1551,11 +1553,11 @@ void TFormula::SetVariable(const TString &name, Double_t value)
 
 void TFormula::DoAddParameter(const TString &name, Double_t value, Bool_t processFormula)
 {
-   //*-*    
+   //*-*
    //*-*    Adds parameter to known parameters.
    //*-*    User should use SetParameter, because parameters are added during initialization part,
    //*-*    and after that adding new will be pointless.
-   //*-*    
+   //*-*
 
    //std::cout << "adding parameter " << name << std::endl;
 
@@ -1568,7 +1570,7 @@ void TFormula::DoAddParameter(const TString &name, Double_t value, Bool_t proces
       if (ipos < 0)
       {
          ipos = fParams.size();
-         fParams[name] = ipos; 
+         fParams[name] = ipos;
       }
       if(ipos >= (int)fClingParameters.capacity())
       {
@@ -1581,11 +1583,11 @@ void TFormula::DoAddParameter(const TString &name, Double_t value, Bool_t proces
       // new parameter defined
       fNpar++;
       //TFormulaVariable(name,value,fParams.size());
-      int pos = fParams.size(); 
+      int pos = fParams.size();
       //fParams.insert(std::make_pair<TString,TFormulaVariable>(name,TFormulaVariable(name,value,pos)));
       fParams.insert(std::make_pair(name,pos));
       fClingParameters.push_back(value);
-      if (processFormula) { 
+      if (processFormula) {
          // replace first in input parameter name with [name]
          fClingInput.ReplaceAll(name,TString::Format("[%s]",name.Data() ) );
          ProcessFormula(fClingInput);
@@ -1595,7 +1597,7 @@ void TFormula::DoAddParameter(const TString &name, Double_t value, Bool_t proces
 }
 Int_t TFormula::GetParNumber(const char * name) const {
    // return parameter index given a name (return -1 for not existing parameters)
-   auto it = fParams.find(name); 
+   auto it = fParams.find(name);
    if(it == fParams.end())
    {
       Error("GetParameter","Parameter %s is not defined.",name);
@@ -1607,33 +1609,33 @@ Int_t TFormula::GetParNumber(const char * name) const {
 
 Double_t TFormula::GetParameter(const char * name) const
 {
-   //*-*    
+   //*-*
    //*-*    Returns parameter value given by string.
    //*-*
-   return GetParameter( GetParNumber(name) ); 
+   return GetParameter( GetParNumber(name) );
 }
 Double_t TFormula::GetParameter(Int_t param) const
 {
-   //*-*    
+   //*-*
    //*-*    Return parameter value given by integer.
-   //*-*    
-   //*-*    
+   //*-*
+   //*-*
    //TString name = TString::Format("%d",param);
    if(param >=0 && param < (int) fClingParameters.size())
       return fClingParameters[param];
    Error("GetParameter","wrong index used - use GetParameter(name)");
-   return 0; 
+   return 0;
 }
 const char * TFormula::GetParName(Int_t ipar) const
 {
-   //*-*    
+   //*-*
    //*-*    Return parameter name given by integer.
    //*-*
    if (ipar < 0 || ipar >= fNpar) return "";
 
    // need to loop on the map to find corresponding parameter
    for ( auto & p : fParams) {
-      if (p.second == ipar) return p.first.Data(); 
+      if (p.second == ipar) return p.first.Data();
    }
    Warning("GetParName","Parameter with index not found !!");
    return TString::Format("p%d",ipar);
@@ -1641,7 +1643,7 @@ const char * TFormula::GetParName(Int_t ipar) const
 Double_t* TFormula::GetParameters() const
 {
    if(!fClingParameters.empty())
-      return const_cast<Double_t*>(&fClingParameters[0]); 
+      return const_cast<Double_t*>(&fClingParameters[0]);
    return 0;
 }
 
@@ -1649,15 +1651,15 @@ void TFormula::GetParameters(Double_t *params) const
 {
    for(Int_t i = 0; i < fNpar; ++i)
    {
-      if (Int_t(fClingParameters.size()) > i) 
+      if (Int_t(fClingParameters.size()) > i)
          params[i] = fClingParameters[i];
-      else 
+      else
          params[i] = -1;
    }
 }
 void TFormula::SetParameter(const char *name, Double_t value)
 {
-   //*-*    
+   //*-*
    //*-*    Sets parameter value.
    //*-*
 
@@ -1682,18 +1684,18 @@ void TFormula::SetParameter(const char *name, Double_t value)
          break;
       }
    }
-#endif   
+#endif
 }
 #ifdef OLDPARAMS
 void TFormula::SetParameters(const pair<TString,Double_t> *params,const Int_t size)
 {
-   //*-*    
+   //*-*
    //*-*    Set multiple parameters.
    //*-*    First argument is an array of pairs<TString,Double>, where
    //*-*    first argument is name of parameter,
    //*-*    second argument represents value.
    //*-*    size - number of params passed in first argument
-   //*-*    
+   //*-*
    for(Int_t i = 0 ; i < size ; ++i)
    {
       pair<TString,Double_t> p = params[i];
@@ -1729,7 +1731,7 @@ void TFormula::DoSetParameters(const Double_t *params, Int_t size)
          TString name = TString::Format("%d",i);
          SetParameter(name,params[i]);
       }
-      return; 
+      return;
    }
    fAllParametersSetted = true;
    std::copy(params, params+size, fClingParameters.begin() );
@@ -1759,7 +1761,7 @@ void TFormula::SetParameter(Int_t param, Double_t value)
 {
    if (param < 0 || param >= fNpar) return;
    assert(int(fClingParameters.size()) == fNpar);
-   fClingParameters[param] = value; 
+   fClingParameters[param] = value;
    // TString name = TString::Format("%d",param);
    // SetParameter(name,value);
 }
@@ -1786,23 +1788,23 @@ void TFormula::SetParName(Int_t ipar, const char * name)
       Error("SetParName","Wrong Parameter index %d ",ipar);
       return;
    }
-   TString oldName; 
-   // find parameter with given index 
-   for ( auto &it : fParams) { 
-      if (it.second  == ipar) { 
+   TString oldName;
+   // find parameter with given index
+   for ( auto &it : fParams) {
+      if (it.second  == ipar) {
          oldName =  it.first;
-         fParams.erase(oldName); 
-         fParams.insert(std::make_pair(name, ipar) );  
+         fParams.erase(oldName);
+         fParams.insert(std::make_pair(name, ipar) );
          break;
       }
    }
-   if (oldName.IsNull() ) { 
+   if (oldName.IsNull() ) {
       Error("SetParName","Parameter %d is not existing.",ipar);
       return;
    }
    // replace also in fFormula the parameter name
-   if (!fFormula.IsNull() ) { 
-      bool found = false; 
+   if (!fFormula.IsNull() ) {
+      bool found = false;
       for(list<TFormulaFunction>::iterator it = fFuncs.begin(); it != fFuncs.end(); ++it)
       {
          if(oldName == it->GetName())
@@ -1821,7 +1823,7 @@ void TFormula::SetParName(Int_t ipar, const char * name)
       TString replacement = TString::Format("[%s]",name);
       fFormula.ReplaceAll(pattern,replacement);
    }
-      
+
 
       // old code
       /*
@@ -1845,7 +1847,7 @@ void TFormula::SetParName(Int_t ipar, const char * name)
       TString replacement = TString::Format("[%s]",name);
       fFormula.ReplaceAll(pattern,replacement);
    }
-   
+
    map<TString,TFormulaVariable>::iterator it = fParams.find(curName);
    TFormulaVariable copy = it->second;
    copy.fName = name;
@@ -1861,12 +1863,12 @@ Double_t TFormula::EvalPar(const Double_t *x,const Double_t *params)
    //if (params) SetParameters(params, fNpar);
 
    // Print("v");
-   // 
+   //
    // if (fNdim >  fClingVariables.size() ) {
    //    std::cout << "dim " << fNdim << "  cling variables size " << fClingVariables.size() << std::endl;
    //    Print("v");
    // }
-   
+
    // assert(fNdim <= fClingVariables.size() );
 
    // std::copy(x, x+fNdim, fClingVariables.begin() );
@@ -1885,9 +1887,9 @@ Double_t TFormula::EvalPar(const Double_t *x,const Double_t *params)
 }
 Double_t TFormula::Eval(Double_t x, Double_t y, Double_t z, Double_t t)
 {
-   //*-*    
+   //*-*
    //*-*    Sets first 4  variables (e.g. x, y, z, t) and evaluate formula.
-   //*-*    
+   //*-*
    if(fNdim >= 1) fClingVariables[0] = x;
    if(fNdim >= 2) fClingVariables[1] = y;
    if(fNdim >= 3) fClingVariables[2] = z;
@@ -1896,9 +1898,9 @@ Double_t TFormula::Eval(Double_t x, Double_t y, Double_t z, Double_t t)
 }
 Double_t TFormula::Eval(Double_t x, Double_t y , Double_t z)
 {
-   //*-*    
+   //*-*
    //*-*    Sets first 3  variables (e.g. x, y, z) and evaluate formula.
-   //*-*    
+   //*-*
 
    if(fNdim >= 1) fClingVariables[0] = x;
    if(fNdim >= 2) fClingVariables[1] = y;
@@ -1911,9 +1913,9 @@ Double_t TFormula::Eval(Double_t x, Double_t y , Double_t z)
 }
 Double_t TFormula::Eval(Double_t x, Double_t y)
 {
-   //*-*    
+   //*-*
    //*-*    Sets first 2  variables (e.g. x and y) and evaluate formula.
-   //*-*    
+   //*-*
 
    if(fNdim >= 1) fClingVariables[0] = x;
    if(fNdim >= 2) fClingVariables[1] = y;
@@ -1921,21 +1923,21 @@ Double_t TFormula::Eval(Double_t x, Double_t y)
 }
 Double_t TFormula::Eval(Double_t x)
 {
-   //*-*    
+   //*-*
    //*-*    Sets first variable (e.g. x) and evaluate formula.
-   //*-*    
+   //*-*
 
    if(fNdim >= 1) fClingVariables[0] = x;
    return DoEval();
 }
 Double_t TFormula::DoEval(const double * x, const double * params)
 {
-   //*-*    
+   //*-*
    //*-*    Evaluate formula.
-   //*-*    If formula is not ready to execute(missing parameters/variables), 
+   //*-*    If formula is not ready to execute(missing parameters/variables),
    //*-*    print these which are not known.
    //*-*    If parameter has default value, and has not been setted, appropriate warning is shown.
-   //*-*    
+   //*-*
 
 
    if(!fReadyToExecute)
@@ -1952,9 +1954,9 @@ Double_t TFormula::DoEval(const double * x, const double * params)
       return -1;
    }
    // this is needed when reading from a file
-   if (!fClingInitialized) { 
-      // need to replace in cling the name of the pointer of this object 
-      TString oldClingName = fClingName; 
+   if (!fClingInitialized) {
+      // need to replace in cling the name of the pointer of this object
+      TString oldClingName = fClingName;
       fClingName.Replace(fClingName.Index("_0x")+1,fClingName.Length(), TString::Format("%p",this) );
       fClingInput.ReplaceAll(oldClingName, fClingName);
       InputFormulaIntoCling();
@@ -1971,14 +1973,14 @@ Double_t TFormula::DoEval(const double * x, const double * params)
    //       {
    //          printf("%s has default value %lf\n",param.first.Data(),param.second.GetInitialValue());
    //       }
-   //    }  
+   //    }
 
    // }
    Double_t result = 0;
-   void* args[2]; 
+   void* args[2];
    double * vars = (x) ? const_cast<double*>(x) : fClingVariables.data();
-   args[0] = &vars; 
-   if (fNpar <= 0) 
+   args[0] = &vars;
+   if (fNpar <= 0)
       (*fFuncPtr)(0, 1, args, &result);
    else {
       double * pars = (params) ? const_cast<double*>(params) : fClingParameters.data();
@@ -1998,18 +2000,18 @@ void TFormula::Print(Option_t *option) const
    TString opt(option);
    opt.ToUpper();
    // do an evaluation as a cross-check
-   //if (fReadyToExecute) Eval(); 
+   //if (fReadyToExecute) Eval();
 
-   if (opt.Contains("V") ) { 
+   if (opt.Contains("V") ) {
       if (fNdim > 0) {
          printf("List of  Variables: \n");
-         for ( map<TString,TFormulaVariable>::const_iterator it = fVars.begin(); it != fVars.end(); ++it) { 
+         for ( map<TString,TFormulaVariable>::const_iterator it = fVars.begin(); it != fVars.end(); ++it) {
             printf(" %20s =  %10f (%s)\n",it->first.Data(), fClingVariables[it->second.GetArrayPos()],it->second.GetName() );
          }
       }
       if (fNpar > 0) {
          printf("List of  Parameters: \n");
-         for ( auto & it : fParams) { 
+         for ( auto & it : fParams) {
             printf(" %20s =  %10f \n",it.first.Data(), fClingParameters[it.second] );
          }
       }
@@ -2030,7 +2032,7 @@ void TFormula::Print(Option_t *option) const
    }
    if(!fAllParametersSetted)
    {
-      // we can skip this 
+      // we can skip this
       // Info("Print","Not all parameters are setted.");
       // for(map<TString,TFormulaVariable>::const_iterator it = fParams.begin(); it != fParams.end(); ++it)
       // {
@@ -2039,11 +2041,11 @@ void TFormula::Print(Option_t *option) const
       //    {
       //       printf("%s has default value %lf\n",param.first.Data(),param.second.GetInitialValue());
       //    }
-      // }  
+      // }
 
    }
 
-} 
+}
 
 //______________________________________________________________________________
 void TFormula::Streamer(TBuffer &b)
@@ -2055,7 +2057,7 @@ void TFormula::Streamer(TBuffer &b)
       //std::cout << "version " << v << std::endl;
       if (v <= 8 && v > 3 && v != 6) {
          // old TFormula class
-         TFormulaOld * fold = new TFormulaOld(); 
+         TFormulaOld * fold = new TFormulaOld();
          b.ReadClassBuffer(TFormulaOld::Class(), fold, v, R__s, R__c);
          //std::cout << "read old tformula class " << std::endl;
          //fold->Print();
@@ -2066,7 +2068,7 @@ void TFormula::Streamer(TBuffer &b)
             Error("Streamer","Old formula read from file is NOT valid");
             Print("v");
          }
-         delete fold; 
+         delete fold;
          return;
       }
       else if (v > 8) {
@@ -2076,7 +2078,7 @@ void TFormula::Streamer(TBuffer &b)
          //std::cout << "reading npar = " << GetNpar() << std::endl;
 
          // initialize the formula
-         // need to set size of fClingVariables which is transient  
+         // need to set size of fClingVariables which is transient
          //fClingVariables.resize(fNdim);
 
          // case of formula contains only parameters
@@ -2084,16 +2086,16 @@ void TFormula::Streamer(TBuffer &b)
 
          // store parameter values
          std::vector<double> parValues = fClingParameters;
-         fClingParameters.clear();  // need to be reset before re-initializing it 
-         
+         fClingParameters.clear();  // need to be reset before re-initializing it
+
          FillDefaults();
 
          //std::cout << "Streamer::Reading preprocess the formula " << fFormula << " ndim = " << fNdim << " npar = " << fNpar << std::endl;
-         
+
          PreProcessFormula(fFormula);
 
          //std::cout << "Streamer::after pre-process the formula " << fFormula << " ndim = " << fNdim << " npar = " << fNpar << std::endl;
-         
+
          fClingInput = fFormula;
          PrepareFormula(fClingInput);
 
@@ -2101,7 +2103,7 @@ void TFormula::Streamer(TBuffer &b)
 
 
          // restore parameter values
-         if (fNpar != (int) parValues.size() ) { 
+         if (fNpar != (int) parValues.size() ) {
             Error("Streamer","number of parameters computed (%d) is not same as the stored parameters (%d)",fNpar,int(parValues.size()) );
             Print("v");
          }
@@ -2109,12 +2111,12 @@ void TFormula::Streamer(TBuffer &b)
          std::copy( parValues.begin(), parValues.end(), fClingParameters.begin() );
 
          // input formula into Cling
-             // need to replace in cling the name of the pointer of this object 
-         // TString oldClingName = fClingName; 
+             // need to replace in cling the name of the pointer of this object
+         // TString oldClingName = fClingName;
          // fClingName.Replace(fClingName.Index("_0x")+1,fClingName.Length(), TString::Format("%p",this) );
          // fClingInput.ReplaceAll(oldClingName, fClingName);
          // InputFormulaIntoCling();
-         
+
          if (!TestBit(kNotGlobal)) {
             R__LOCKGUARD2(gROOTMutex);
             gROOT->GetListOfFunctions()->Add(this);
@@ -2138,7 +2140,7 @@ void TFormula::Streamer(TBuffer &b)
        //std::cout << "writing npar = " << GetNpar() << std::endl;
    }
 }
-   
-      
 
-      
+
+
+

From 7ab0e6ad48c797f8ee7c03e688c08c84456a6496 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Wed, 25 Feb 2015 16:04:06 +0100
Subject: [PATCH 068/200] Proof: Set TPacketizer default data packetizer

TPacketizer now supports dynamic addition of workers and for the rest the behaviour has always ben similar
the more complicated TPacketizerAdaptive.
---
 proof/proofplayer/src/TPacketizer.cxx      | 4 ++--
 proof/proofplayer/src/TPacketizerMulti.cxx | 4 ++--
 proof/proofplayer/src/TProofPlayer.cxx     | 3 +--
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/proof/proofplayer/src/TPacketizer.cxx b/proof/proofplayer/src/TPacketizer.cxx
index 8c85078d5b845..7bc97e6068177 100644
--- a/proof/proofplayer/src/TPacketizer.cxx
+++ b/proof/proofplayer/src/TPacketizer.cxx
@@ -293,7 +293,7 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
    fDefMaxWrkNode = kTRUE;
 
    if (!fProgressStatus) {
-      Error("TPacketizerAdaptive", "No progress status");
+      Error("TPacketizer", "No progress status");
       return;
    }
 
@@ -394,7 +394,7 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
    Bool_t byfile = (gprc == 0 && validateMode > 0 && num > -1) ? kTRUE : kFALSE;
    if (num > -1)
       PDB(kPacketizer,2)
-         Info("TPacketizerAdaptive",
+         Info("TPacketizer",
               "processing subset of entries: validating by file? %s", byfile ? "yes": "no");
    ValidateFiles(dset, slaves, num, byfile);
 
diff --git a/proof/proofplayer/src/TPacketizerMulti.cxx b/proof/proofplayer/src/TPacketizerMulti.cxx
index d03145a194155..c67f0722a8d4a 100644
--- a/proof/proofplayer/src/TPacketizerMulti.cxx
+++ b/proof/proofplayer/src/TPacketizerMulti.cxx
@@ -277,8 +277,8 @@ TVirtualPacketizer *TPacketizerMulti::CreatePacketizer(TDSet *dset, TList *wrks,
    }
 
    if (TProof::GetParameter(input, "PROOF_Packetizer", packetizername) != 0) {
-      // Using standard packetizer TAdaptivePacketizer
-      packetizername = "TPacketizerAdaptive";
+      // Using standard packetizer TPacketizer
+      packetizername = "TPacketizer";
    } else {
       Info("CreatePacketizer", "using alternate packetizer: %s", packetizername.Data());
    }
diff --git a/proof/proofplayer/src/TProofPlayer.cxx b/proof/proofplayer/src/TProofPlayer.cxx
index 88d45533c817c..7ab124720ff1f 100644
--- a/proof/proofplayer/src/TProofPlayer.cxx
+++ b/proof/proofplayer/src/TProofPlayer.cxx
@@ -2211,8 +2211,7 @@ Long64_t TProofPlayerRemote::Process(TDSet *dset, const char *selector_file,
       if (dset->TestBit(TDSet::kEmpty))
          set->SetBit(TDSet::kEmpty);
 
-      const char *datapack = (fProof->IsLite()) ? "TPacketizer" : "TPacketizerAdaptive";
-      if (InitPacketizer(dset, nentries, first, "TPacketizerUnit", datapack) != 0) {
+      if (InitPacketizer(dset, nentries, first, "TPacketizerUnit", "TPacketizer") != 0) {
          Error("Process", "cannot init the packetizer");
          fExitStatus = kAborted;
          return -1;

From 93160cc4f18202331dc8d43cca148f7c0c1ba613 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Thu, 26 Feb 2015 10:46:53 +0100
Subject: [PATCH 069/200] Proof: improve dynamic startup workflow

The current implementation of dynamic worker startup requires at least one worker available to launch a query.
This patch allows to submit a query even without workers and to have it automatically start processing when the
first workers comes. Required for PoD setups using resource management systems with potentially large startup
latency, e.g. PanDa.
The time the master waits for the first worker to come is controlled by the ROOT-rc

       Proof.DynamicStartupTimeout <value in seconds>

Default is infinite.
---
 proof/proofx/src/TXProofServ.cxx | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/proof/proofx/src/TXProofServ.cxx b/proof/proofx/src/TXProofServ.cxx
index c9ade876751c6..707254b20ce7b 100644
--- a/proof/proofx/src/TXProofServ.cxx
+++ b/proof/proofx/src/TXProofServ.cxx
@@ -800,8 +800,19 @@ TProofServ::EQueryAction TXProofServ::GetWorkers(TList *workers,
       }
    }
    // Send request to the coordinator
-   TObjString *os =
-      ((TXSocket *)fSocket)->SendCoordinator(kGetWorkers, seqnum.Data());
+   TObjString *os = 0;
+   if (dynamicStartup) {
+      // We wait dynto seconds for the first worker to come; -1 means forever
+      Int_t dynto = gEnv->GetValue("Proof.DynamicStartupTimeout", -1);
+      Bool_t doto = (dynto > 0) ? kTRUE : kFALSE;
+      while (!(os = ((TXSocket *)fSocket)->SendCoordinator(kGetWorkers, seqnum.Data()))) {
+         if (doto > 0 && --dynto < 0) break;
+         // Another second
+         gSystem->Sleep(1000);
+      }
+   } else {
+      os = ((TXSocket *)fSocket)->SendCoordinator(kGetWorkers, seqnum.Data());
+   }
 
    // The reply contains some information about the master (image, workdir)
    // followed by the information about the workers; the tokens for each node

From 36e9a52c0d3147d93433a93777600c8bd1d03859 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Thu, 26 Feb 2015 11:11:37 +0100
Subject: [PATCH 070/200] Proof-Packetizer: remove redefinition of a member

The TMap fSlaveStats is defined in TVirtualPacketizer and must not be redefined here.
Also fixes an issue with stressProof when testing different packetizers.
---
 proof/proofplayer/inc/TPacketizer.h   | 1 -
 proof/proofplayer/src/TPacketizer.cxx | 2 --
 2 files changed, 3 deletions(-)

diff --git a/proof/proofplayer/inc/TPacketizer.h b/proof/proofplayer/inc/TPacketizer.h
index 55bf213c02179..c7d850494733d 100644
--- a/proof/proofplayer/inc/TPacketizer.h
+++ b/proof/proofplayer/inc/TPacketizer.h
@@ -51,7 +51,6 @@ class TPacketizer : public TVirtualPacketizer {
    TList    *fFileNodes;    // nodes with files
    TList    *fUnAllocated;  // nodes with unallocated files
    TList    *fActive;       // nodes with unfinished files
-   TMap     *fSlaveStats;   // slave status, keyed by correspondig TSlave
 
    Long64_t  fPacketSize;   // global base packet size
                                  // It can be set with PROOF_PacketSize
diff --git a/proof/proofplayer/src/TPacketizer.cxx b/proof/proofplayer/src/TPacketizer.cxx
index 7bc97e6068177..e6d25986686d5 100644
--- a/proof/proofplayer/src/TPacketizer.cxx
+++ b/proof/proofplayer/src/TPacketizer.cxx
@@ -281,9 +281,7 @@ TPacketizer::TPacketizer(TDSet *dset, TList *slaves, Long64_t first,
    PDB(kPacketizer,1) Info("TPacketizer", "Enter (first %lld, num %lld)", first, num);
 
    // Init pointer members
-   fSlaveStats = 0;
    fPackets = 0;
-   fSlaveStats = 0;
    fUnAllocated = 0;
    fActive = 0;
    fFileNodes = 0;

From bc1476422f39ebe56748bd6bbeea908c84687829 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Thu, 26 Feb 2015 11:45:36 +0100
Subject: [PATCH 071/200] Fix for ROOT-7048 - Issue while loading libraries
 that start with the same string

---
 core/base/src/TSystem.cxx | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx
index adde31d53d792..5bca540688424 100644
--- a/core/base/src/TSystem.cxx
+++ b/core/base/src/TSystem.cxx
@@ -1771,8 +1771,7 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
    if (idx != kNPOS) {
       l.Remove(idx+1);
    }
-   idx = libs.Index(l);
-   if (idx != kNPOS) {
+   for (idx = libs.Index(l); idx != kNPOS; idx = libs.Index(l,idx+1)) {
       // The libs contains the sub-string 'l', let's make sure it is
       // not just part of a larger name.
       if (idx == 0 || libs[idx-1] == '/' || libs[idx-1] == '\\') {
@@ -1801,11 +1800,11 @@ int TSystem::Load(const char *module, const char *entry, Bool_t system)
    }
    if (l.BeginsWith("lib")) {
       l.Replace(0, 3, "-l");
-      idx = libs.Index(l);
-      if (idx != kNPOS &&
-          (idx == 0 || libs[idx-1] == ' ') &&
-          (libs[idx+l.Length()] == ' ' || libs[idx+l.Length()] == 0)) {
-         return 1;
+      for(idx = libs.Index(l); idx != kNPOS; idx = libs.Index(l,idx+1)) {
+         if ((idx == 0 || libs[idx-1] == ' ') &&
+             (libs[idx+l.Length()] == ' ' || libs[idx+l.Length()] == 0)) {
+            return 1;
+         }
       }
    }
 

From ae2a52d40a1537a826f6308a1365a984ea938f1b Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 26 Feb 2015 12:22:48 +0100
Subject: [PATCH 072/200] From Axel: Fix for late template parsed functions
 (Microsoft feature)

---
 .../cling/lib/Interpreter/AutoSynthesizer.cpp        | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp b/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp
index 0b003729b50a7..586440afea3dc 100644
--- a/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp
+++ b/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp
@@ -82,9 +82,15 @@ namespace cling {
       // Copy DCI; it might get relocated below.
       Transaction::DelayCallInfo DCI = *I;
       for (DeclGroupRef::const_iterator J = DCI.m_DGR.begin(),
-             JE = DCI.m_DGR.end(); J != JE; ++J)
-        if ((*J)->hasBody())
-          m_AutoFixer->Fix(cast<CompoundStmt>((*J)->getBody()));
+             JE = DCI.m_DGR.end(); J != JE; ++J) {
+        if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*J)) {
+          // getBody() might return nullptr even though hasBody() is true for
+          // late template parsed functions. We simply don't do auto auto on
+          // those.
+          if (CompoundStmt* CS = cast_or_null<CompoundStmt>(FD->getBody()))
+            m_AutoFixer->Fix(CS);
+        }
+      }
     }
   }
 } // end namespace cling

From 33024c0dcc3e13cae7666667e50d75a98b99eeb7 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Thu, 26 Feb 2015 13:44:11 +0100
Subject: [PATCH 073/200] Fix for ROOT-7105 - root.desktop file doesn't conform
 freedesktop standard

---
 etc/root.desktop | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/etc/root.desktop b/etc/root.desktop
index ca382111cc3ae..688ecfa9e3ba6 100644
--- a/etc/root.desktop
+++ b/etc/root.desktop
@@ -8,5 +8,5 @@ Name[de]=ROOT
 Comment=An object-oriented data analysis framework
 Comment[de]=Ein objektorientiertes Framework zur Datenanalyse
 StartupNotify=true
-MimeType=application/x-root;text/x-c++src
-Categories=Science;Development;Application;
+MimeType=application/x-root;text/x-c++src;
+Categories=Science;Development;

From d9a452561d3f462528044bbaac1f0e91240d2c04 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Wed, 25 Feb 2015 09:44:37 +0100
Subject: [PATCH 074/200] jsroot: better support of foreignObject in SVG
 graphic

1. foreignObject used to display HTML content inside SVG.
Safari/Chrome has several problems with them like
http://bit.ly/1wjqCQ9
IE do not support foreignObjects at all.
foreignObjects used for TH2 draw options col2/col3 with HTML5 canvas.
2. First try to use MathJax. It is incapsulated into foreignObjects.
Test implementation in TLegend painter.
In future JSROOT versions one need to implement full
converted from ROOT TLatex into normal (La)Tex.

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/changes.md               |   2 +
 etc/http/files/draw.htm           |  18 +-
 etc/http/scripts/JSRootCore.js    |  13 +-
 etc/http/scripts/JSRootPainter.js | 263 +++++++++++++++++-------------
 4 files changed, 171 insertions(+), 125 deletions(-)

diff --git a/etc/http/changes.md b/etc/http/changes.md
index a4632659e4b9a..13275228ab61e 100644
--- a/etc/http/changes.md
+++ b/etc/http/changes.md
@@ -28,6 +28,8 @@ Many old problems and errors are fixed, new functions are provided.
     plain text in the browser. If property 'mathjax' specified,
     MathJax.js library will be loaded and used for rendering.
     See httpcontrol.C macro for example.
+13. When using foreignObject, provide workaround for absolute positioning 
+    problem in Chrome/Safari, see <http://bit.ly/1wjqCQ9>
    
 
 ## Changes in 3.2
diff --git a/etc/http/files/draw.htm b/etc/http/files/draw.htm
index f31b49aea1e63..758be937fcfc1 100644
--- a/etc/http/files/draw.htm
+++ b/etc/http/files/draw.htm
@@ -10,7 +10,7 @@
 
    <script type='text/javascript'>
 
-      function GetCashedObject() { return "$$$root.json$$$"; }
+      function GetCachedObject() { return "$$$root.json$$$"; }
 
       function CreateDrawGui() {
          // analyze URL options
@@ -21,6 +21,7 @@
          if (monitor != null) monitor = parseInt(monitor);
 
          var objpainter = null;
+         var req_url = 'root.json.gz?compact=3';
 
          function draw_function(obj) {
             if (!obj) {
@@ -33,18 +34,23 @@
          }
 
          function get_function() {
-            var req = JSROOT.NewHttpRequest("root.json.gz?compact=3", 'object', draw_function);
+            var req = JSROOT.NewHttpRequest(req_url, 'object', draw_function);
             // submit request
             req.send(null);
          }
 
-         var obj = GetCashedObject();
+         var obj = GetCachedObject();
 
-         if (typeof obj =='object') {
+         if (typeof obj != 'object') {
+            get_function();
+         } else
+         if (obj['_typename'] == 'TFolder') {
+            // special case - seems to be it is item in the sniffer
+            req_url = 'get.json.gz?compact=3';
+            get_function();
+         } else {
             obj = JSROOT.JSONR_unref(obj);
             draw_function(obj);
-         } else { 
-            get_function();
          }
 
          if (monitor!=null)
diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index d0f01e031ca8e..a2cfcd82bd558 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,7 +14,7 @@
 
    JSROOT = {};
 
-   JSROOT.version = "3.3 dev 20/02/2015";
+   JSROOT.version = "3.3 25/02/2015";
 
    JSROOT.source_dir = "";
 
@@ -27,6 +27,15 @@
 
    JSROOT.touches = ('ontouchend' in document); // identify if touch events are supported
 
+   JSROOT.browser = {};
+
+   JSROOT.browser.isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
+   JSROOT.browser.isFirefox = typeof InstallTrigger !== 'undefined';
+   JSROOT.browser.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
+   JSROOT.browser.isChrome = !!window.chrome && !JSROOT.browser.isOpera;
+   JSROOT.browser.isIE = false || !!document.documentMode;
+   JSROOT.browser.isWebKit = JSROOT.browser.isChrome || JSROOT.browser.isSafari;
+
    JSROOT.function_list = []; // do we really need it here?
 
    JSROOT.BIT = function(n) { return 1 << (n); }
@@ -488,7 +497,7 @@
                      ";$$$scripts/JSRoot3DPainter.js";
 
       if (kind.indexOf("mathjax;")>=0)
-         allfiles += ";https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+        allfiles += ";https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
 
       if (kind.indexOf("simple;")>=0)
          allfiles += ';$$$scripts/JSRootInterface.js' +
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index c4ed30774e914..23668086d728d 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -46,7 +46,8 @@
       StatFill : { fFillColor: 0, fFillStyle: 1001 },
       TimeOffset : 788918400000, // UTC time at 01/01/95
       StatFormat : function(v) { return (Math.abs(v) < 1e5) ? v.toFixed(5) : v.toExponential(7); },
-      StatEntriesFormat : function(v) { return (Math.abs(v) < 1e7) ? v.toFixed(0) : v.toExponential(7); }
+      StatEntriesFormat : function(v) { return (Math.abs(v) < 1e7) ? v.toFixed(0) : v.toExponential(7); },
+      MathJax : 0,  // 0 - never, 1 - only for complex cases, 2 - always
    };
 
    /**
@@ -78,6 +79,13 @@
          col = parseInt(col);
          if ((col!=NaN) && (col>0) && (col<4)) JSROOT.gStyle.DefaultCol = col;
       }
+
+      var mathjax = JSROOT.GetUrlOption("mathjax", url);
+      if (mathjax == "") JSROOT.gStyle.MathJax = 1; else
+      if (mathjax != null) {
+         JSROOT.gStyle.MathJax = parseInt(mathjax);
+         if (JSROOT.gStyle.MathJax == NaN) JSROOT.gStyle.MathJax = 1;
+      }
    }
 
    JSROOT.createMenu = function(menuname) {
@@ -434,6 +442,11 @@
             selection.attr("font-style", this.style);
       }
 
+      res.asStyle = function(sz) {
+         // return font name, which could be applied with d3.select().style('font')
+         return ((sz!=null) ? sz : this.size) + "px " + this.name;
+      }
+
       res.stringWidth = function(svg, line) {
          /* compute the bounding box of a string by using temporary svg:text */
          var text = svg.append("svg:text")
@@ -1047,6 +1060,28 @@
          svg_p['mainpainter'] = this;
    }
 
+   JSROOT.TObjectPainter.prototype.SetForeignObjectPosition = function(fo, x, y) {
+      // method used to set absolute coordinates for foreignObject
+      // it is known problem of WebKit http://bit.ly/1wjqCQ9
+
+      var sel = fo;
+
+      if (JSROOT.browser.isWebKit) {
+         // force canvas redraw when foreign object used - it is not correctly scaled
+         this.svg_canvas(true).property('redraw_by_resize', true);
+         while (sel && sel.attr('class') != 'root_canvas') {
+            if ((sel.attr('class') == 'root_frame') || (sel.attr('class') == 'root_pad')) {
+              x += parseInt(sel.attr("x"));
+              y += parseInt(sel.attr("y"));
+            }
+            sel = d3.select(sel.node().parentNode);
+         }
+      }
+
+      fo.attr("x",x).attr("y",y);
+   }
+
+
    JSROOT.TObjectPainter.prototype.createAttFill = function(attfill, pattern, color) {
 
       if ((pattern==null) && attfill) pattern = attfill['fFillStyle'];
@@ -2662,7 +2697,7 @@
          var oldh = svg.property('last_height');
 
          if (check_resize == 1) {
-            if ((svg.attr('width')==w) && (svg.attr('height')==h)) return false;
+            if ((svg.attr('width') == w) && (svg.attr('height') == h)) return false;
             if ((oldw == w) && (oldh == h)) return false;
          }
 
@@ -2674,12 +2709,12 @@
             render_to.height(h);
          }
 
-         if ((check_resize==1) && (oldw>0) && (oldh>0))
+         if ((check_resize==1) && (oldw>0) && (oldh>0) && !svg.property('redraw_by_resize'))
             if ((w/oldw>0.5) && (w/oldw<2) && (h/oldh>0.5) && (h/oldh<2)) {
-              // change view port without changing view box
-              // let SVG scale drawing itself
-              svg.attr("width", w).attr("height", h);
-              return false;
+               // change view port without changing view box
+               // let SVG scale drawing itself
+               svg.attr("width", w).attr("height", h);
+               return false;
             }
 
       } else {
@@ -2728,7 +2763,8 @@
          .attr("preserveAspectRatio", "none")  // we do not keep relative ratio
          .property('height_factor', factor)
          .property('last_width', w)
-         .property('last_height', h);
+         .property('last_height', h)
+         .property('redraw_by_resize', false);
 
       return true;
    }
@@ -5791,14 +5827,12 @@
 
       var dx = i2-i1, dy = j2-j1;
 
-      var canvas =
-         this.draw_g.append("foreignObject")
-                 .attr("width", w)
-                 .attr("height", h)
-                 .append("xhtml:canvas")
-                 .attr("width", dx)
-                 .attr("height", dy)
-                 .attr("style", "width: " + w + "px; height: "+ h + "px");
+      var fo = this.draw_g.append("foreignObject").attr("width", w).attr("height", h);
+      this.SetForeignObjectPosition(fo, 0, 0);
+
+      var canvas = fo.append("xhtml:canvas")
+                     .attr("width", dx).attr("height", dy)
+                     .attr("style", "width: " + w + "px; height: "+ h + "px");
 
       var context = canvas.node().getContext("2d");
       var image = context.createImageData(dx, dy);
@@ -5824,32 +5858,13 @@
 
       var local_bins = this.CreateDrawBins(w, h, 0, 0);
 
-      var foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject' );
-      // var body = document.createElement( 'body' );
+      var fo = this.draw_g.append("foreignObject").attr("width", w).attr("height", h);
+      this.SetForeignObjectPosition(fo, 0, 0);
 
-      var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
+      var canvas = fo.append("xhtml:canvas").attr("width", w).attr("height", h);
 
-      $(canvas).attr('width', w).attr('height',h)
-
-//      $(body).append(canvas);
-
-      $(foreignObject).attr("width", w).attr("height", h).append(canvas);
-
-      $(this.draw_g.node()).append(foreignObject);
-
-      var ctx = canvas.getContext("2d");
-
-/*
-      var canvas =
-         this.draw_g.append("foreignObject")
-                 .attr("width", w)
-                 .attr("height", h)
-                 .append("xhtml:canvas")
-                 .attr("width", w)
-                 .attr("height", h)
-                 .attr("style", "width: " + w + "px; height: "+ h + "px");
       var ctx = canvas.node().getContext("2d");
-*/
+
       for (var i in local_bins) {
          var bin = local_bins[i];
          ctx.fillStyle = bin.fill;
@@ -5867,13 +5882,12 @@
       var w = Number(this.svg_frame(true).attr("width")),
           h = Number(this.svg_frame(true).attr("height"));
 
-      if (this.options.Color==2)
+      if ((this.options.Color==2) && !JSROOT.browser.isIE)
          return this.DrawSimpleCanvas(w,h);
 
-      if (this.options.Color==3)
+      if ((this.options.Color==3) && !JSROOT.browser.isIE)
          return this.DrawNormalCanvas(w,h);
 
-
       // this.options.Scat =1;
       // this.histo['fMarkerStyle'] = 2;
 
@@ -6227,41 +6241,35 @@
            .style("stroke", lcolor.color);
 
       var tcolor = JSROOT.Painter.root_colors[pave['fTextColor']];
-      var tpos_x = pave['fMargin'] * w;
+      var tpos_x = Math.round(pave['fMargin'] * w);
+      var padding_x = Math.round(0.03 * w);
+      var padding_y = Math.round(0.03 * h);
       var nlines = pave.fPrimitives.arr.length;
       var font = JSROOT.Painter.getFontDetails(pave['fTextFont'], h / (nlines * 1.5));
 
-      var max_len = 0, mul = 1.4;
+      var min_fact = 1.;
       for (var j = 0; j < nlines; ++j) {
-         var line = JSROOT.Painter.translateLaTeX(pave.fPrimitives.arr[j]['fLabel']);
-         var lw = tpos_x  + font.stringWidth(svg, line);
-         if (lw > max_len) max_len = lw;
-      }
-      if (max_len > w) {
-         font.size = Math.floor(font.size * 0.95 * (w / max_len));
-         mul *= 0.95 * (max_len / w);
-      }
-      var x1 = pave['fX1NDC'];
-      var x2 = pave['fX2NDC'];
-      var y1 = pave['fY1NDC'];
-      var y2 = pave['fY2NDC'];
-      var margin = pave['fMargin'] * (x2 - x1) / pave['fNColumns'];
-      var yspace = (y2 - y1) / nlines;
-      var ytext = y2 + 0.5 * yspace; // y-location of 0th entry
-      var boxw = margin * 0.35;
+         var leg = pave.fPrimitives.arr[j];
+         var lopt = leg['fOption'].toLowerCase();
+         var label = JSROOT.Painter.translateLaTeX(leg['fLabel']);
+         var lw = font.stringWidth(svg, label);
+         var allowed = w - 2*padding_x;
+         if ((lopt.indexOf("h")<0) && (lopt.length>0)) allowed = w - tpos_x - padding_x;
+         var fact = lw > 5 ? allowed / lw : 1.;
+         if (fact < min_fact) min_fact = fact;
+      }
+
+      if (min_fact<1) font.size = Math.floor(font.size * min_fact);
+
+      var step_y = (h - 2*padding_y)/nlines;
 
       for (var i = 0; i < nlines; ++i) {
          var leg = pave.fPrimitives.arr[i];
          var lopt = leg['fOption'].toLowerCase();
 
-         var string = leg['fLabel'];
+         var label = JSROOT.Painter.translateLaTeX(leg['fLabel']);
 
-         var pos_y = ((i + 1) * (font.size * mul)) - (font.size / 3);
-         var tpos_y = (i + 1) * (font.size * mul);
-         if (nlines == 1) {
-            var pos_y = (h * 0.75) - (font.size / 3);
-            var tpos_y = h * 0.75;
-         }
+         var pos_y = padding_y + (i+0.5)*step_y; // middle of each line
 
          var attfill = leg;
          var attmarker = leg;
@@ -6278,57 +6286,24 @@
          var fill = this.createAttFill(attfill);
          var llll = JSROOT.Painter.createAttLine(attline);
 
-         p.append("text")
-              .attr("class", "text")
-              .attr("text-anchor", "start")
-              .attr("x", tpos_x)
-              .attr("y", tpos_y)
-              .call(font.func)
-              .attr("fill", tcolor)
-              .text(string);
-
          // Draw fill pattern (in a box)
          if (lopt.indexOf('f') != -1) {
             // box total height is yspace*0.7
             // define x,y as the center of the symbol for this entry
-            var xsym = margin / 2;
-            var ysym = ytext;
-            var xf = new Array(4), yf = new Array(4);
-            xf[0] = xsym - boxw;
-            yf[0] = ysym - yspace * 0.35;
-            xf[1] = xsym + boxw;
-            yf[1] = yf[0];
-            xf[2] = xf[1];
-            yf[2] = ysym + yspace * 0.35;
-            xf[3] = xf[0];
-            yf[3] = yf[2];
-            for (var j = 0; j < 4; j++) {
-               xf[j] = xf[j] * Number(svg.attr("width"));
-               yf[j] = yf[j] * Number(svg.attr("height"));
-            }
-            var ww = xf[1] - xf[0];
-            var hh = yf[2] - yf[0];
-            pos_y = pos_y - (hh / 2);
-            var pos_x = (tpos_x / 2) - (ww / 2);
-
             p.append("svg:rect")
-                   .attr("x", pos_x)
-                   .attr("y", pos_y)
-                   .attr("width", ww)
-                   .attr("height", hh)
+                   .attr("x", padding_x)
+                   .attr("y", pos_y-step_y/3)
+                   .attr("width", tpos_x - 2*padding_x)
+                   .attr("height", 2*step_y/3)
                    .call(llll.func)
                    .call(fill.func);
          }
          // Draw line
          if (lopt.indexOf('l') != -1) {
-
-            // line total length (in x) is margin*0.8
-            var line_length = (0.7 * pave['fMargin']) * w;
-            var pos_x = (tpos_x - line_length) / 2;
             p.append("svg:line")
-               .attr("x1", pos_x)
+               .attr("x1", padding_x)
                .attr("y1", pos_y)
-               .attr("x2", pos_x + line_length)
+               .attr("x2", tpos_x - padding_x)
                .attr("y2", pos_y)
                .call(llll.func);
          }
@@ -6337,15 +6312,65 @@
          }
          // Draw Polymarker
          if (lopt.indexOf('p') != -1) {
-
-            var line_length = (0.7 * pave['fMargin']) * w;
-            var pos_x = tpos_x / 2;
-
             var marker = JSROOT.Painter.createAttMarker(attmarker);
             p.append("svg:path")
-                .attr("transform", function(d) { return "translate(" + pos_x + "," + pos_y + ")"; })
+                .attr("transform", function(d) { return "translate(" + tpos_x/2 + "," + pos_y + ")"; })
                 .call(marker.func);
          }
+
+         var pos_x = tpos_x;
+         if ((lopt.indexOf('h')>=0) || (lopt.length==0)) pos_x = padding_x;
+
+         if ((JSROOT.gStyle.MathJax < 1) || (label.indexOf("#frac")<0)) {
+           p.append("text")
+              .attr("class", "text")
+              .attr("text-anchor", "start")
+              .attr("dominant-baseline", "central")
+              .attr("x", pos_x)
+              .attr("y", pos_y /*+ font.size*0.3*/)
+              .call(font.func)
+              .attr("fill", tcolor)
+              .text(label);
+         } else {
+
+            var fo_x = Math.round(pos_x);
+            var fo_y = Math.round(pos_y - 0.5*step_y);
+            var fo_w = Math.round(w - padding_x - pos_x);
+            var fo_h = Math.round(step_y);
+
+            var fo = this.draw_g.append("foreignObject").attr("width", fo_w).attr("height", fo_h);
+            this.SetForeignObjectPosition(fo, fo_x, fo_y);
+
+            // this is just workaround, one need real parser to find all #frac and so on
+            label = label.replace("#frac","\\(\\frac") + "\\)";
+
+            var body = fo.append("xhtml:body")
+                         .style("display", "table")
+                         .append("xhtml:div")
+                         .style("display", "table-cell")
+                         .style('vertical-align', 'middle') // force to align in the center
+                         .style("font", font.asStyle())
+                         .html(label);
+
+            JSROOT.AssertPrerequisites('mathjax', function() {
+               if (typeof MathJax != 'object') return;
+
+               // MathJax.Hub.Queue(["Typeset", MathJax.Hub, body.node()]);
+
+               MathJax.Hub.Queue(function() {
+                  MathJax.Hub.Typeset(body.node());
+                  // rescale one again
+                  var rect = body.node().getBoundingClientRect();
+                  var fact_x = parseInt(rect.right - rect.left) / fo_w;
+                  var fact_y = parseInt(rect.bottom - rect.top) / fo_h;
+                  if (Math.max(fact_x, fact_y) > 1)
+                     body.style("font", font.asStyle(Math.round(font.size/Math.max(fact_x, fact_y))));
+               });
+            });
+
+
+         }
+
       }
       if (lwidth && lwidth > 1) {
          p.append("svg:line")
@@ -6756,14 +6781,18 @@
 
       var mathjax = 'mathjax' in this.txt;
 
-      if (!mathjax && !('as_is' in this.txt)) {
-         var arr = txt.split("\n"); txt = "";
-         for (var i in arr)
-            txt += "<pre>" + arr[i] + "</pre>";
+      if ('load' in this.txt) {
+         frame.html("<div style='overflow:hidden'></div>");
+         frame.find('div').load(this.txt.load);
+      } else {
+         if (!mathjax && !('as_is' in this.txt)) {
+            var arr = txt.split("\n"); txt = "";
+            for (var i in arr)
+               txt += "<pre>" + arr[i] + "</pre>";
+         }
+         frame.html("<div style='overflow:hidden'>" + txt + "</div>");
       }
 
-      frame.html("<div style='overflow:hidden'>" + txt + "</div>");
-
       // (re) set painter to first child element
       this.SetDivId(this.divid);
 

From 1e181cbb9b576862c3d4824bc762e7048183e262 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Thu, 26 Feb 2015 15:26:16 +0100
Subject: [PATCH 075/200] Make sure that "/" and "." are not part of the method
 name when a canvas is saved as a .C file (ROOT-7071).

---
 graf2d/gpad/src/TCanvas.cxx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx
index b56d88318d866..2280af0ce118f 100644
--- a/graf2d/gpad/src/TCanvas.cxx
+++ b/graf2d/gpad/src/TCanvas.cxx
@@ -1747,8 +1747,9 @@ void TCanvas::SaveSource(const char *filename, Option_t *option)
    }
 
    TString mname(fname);
-   Int_t p = mname.Index(".");
-   out <<"void " << mname(0,p) << "()" <<std::endl;
+   Int_t p = mname.Last('.');
+   Int_t s = mname.Last('/')+1;
+   out <<"void " << mname(s,p-s) << "()" <<std::endl;
    out <<"{"<<std::endl;
    out <<"//=========Macro generated from canvas: "<<GetName()<<"/"<<GetTitle()<<std::endl;
    out <<"//=========  ("<<t.AsString()<<") by ROOT version"<<gROOT->GetVersion()<<std::endl;

From 310d58a22c4dc4c294d89799daf43c8eb999145c Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Thu, 26 Feb 2015 15:31:48 +0100
Subject: [PATCH 076/200] TCanvas

---
 graf2d/doc/v604/index.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/graf2d/doc/v604/index.md b/graf2d/doc/v604/index.md
index 05b6abc051394..f7ece3de50e0f 100644
--- a/graf2d/doc/v604/index.md
+++ b/graf2d/doc/v604/index.md
@@ -53,6 +53,11 @@
 - In `Pad::Print()`, make sure the file format is "pdf" when the option "Title:"
   is present.
 
+### TCanvas
+
+- Make sure that "/" and "." are not part of the method name when a canvas is
+ saved as a .C file.
+
 ### TLatex
 
 - With the Cocoa backend the PDF and PS output produced miss-aligned exponents

From 1b7d621e377b8398038efad12884c305ceb23775 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Thu, 26 Feb 2015 17:49:04 +0100
Subject: [PATCH 077/200] Fix tutorial crash after OrcJIT upgrade (ROOT-7111).

---
 tutorials/roofit/rf401_importttreethx.C | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tutorials/roofit/rf401_importttreethx.C b/tutorials/roofit/rf401_importttreethx.C
index c4c9e91adb4af..cfd7eaf826ca3 100644
--- a/tutorials/roofit/rf401_importttreethx.C
+++ b/tutorials/roofit/rf401_importttreethx.C
@@ -25,6 +25,7 @@
 #include "TH1.h"
 #include "TTree.h"
 #include "TRandom.h"
+#include <map>
 
 using namespace RooFit ;
 

From a4b76978d70eab8c01311b4fcd79c3e9df7c492a Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 09:49:28 +0100
Subject: [PATCH 078/200] Use correct forward declaration (fix unresolved
 external symbol at link time)

---
 core/textinput/src/textinput/History.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/textinput/src/textinput/History.cpp b/core/textinput/src/textinput/History.cpp
index f7138182ed588..e186842970908 100644
--- a/core/textinput/src/textinput/History.cpp
+++ b/core/textinput/src/textinput/History.cpp
@@ -20,7 +20,7 @@
 
 #ifdef WIN32
 # include <stdio.h>
-extern "C" unsigned int GetCurrentProcessId();
+extern "C" unsigned long __stdcall GetCurrentProcessId(void);
 #else
 # include <unistd.h>
 #endif

From 2be2c9647af5fdbc39833e20e50a2245608334fd Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 09:53:04 +0100
Subject: [PATCH 079/200] Add missing compilation flags (MSVC)

---
 core/utils/CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt
index 8cef6fbe462ec..9f3fa9bb97468 100644
--- a/core/utils/CMakeLists.txt
+++ b/core/utils/CMakeLists.txt
@@ -8,6 +8,8 @@ ROOT_USE_PACKAGE(io/io)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/../metautils/src ${LLVM_INCLUDE_DIRS} ${CLING_INCLUDE_DIRS})
 if(NOT MSVC)
   add_definitions(${CLING_CXXFLAGS} -Wno-shadow -Wno-unused-parameter)
+else()
+  set_source_files_properties(src/rootcling.cxx PROPERTIES COMPILE_FLAGS "-DNOMINMAX -D_XKEYCHECK_H")
 endif()
 ROOT_EXECUTABLE(rootcling src/LinkdefReader.cxx src/DictSelectionReader.cxx
                           src/TModuleGenerator.cxx src/rootcling.cxx src/rootclingTCling.cxx

From 4fae7153a1191a4bb6253196949941eb6909fe29 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 09:54:40 +0100
Subject: [PATCH 080/200] Remove obsolete calls to cint

---
 core/winnt/src/TWinNTSystem.cxx | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/core/winnt/src/TWinNTSystem.cxx b/core/winnt/src/TWinNTSystem.cxx
index 46af8ac4af108..3926246feeabf 100644
--- a/core/winnt/src/TWinNTSystem.cxx
+++ b/core/winnt/src/TWinNTSystem.cxx
@@ -100,8 +100,6 @@
 
 extern "C" {
    extern void Gl_setwidth(int width);
-   extern int G__get_security_error();
-   extern int G__genericerror(const char* msg);
    void *_ReturnAddress(void);
 }
 
@@ -432,13 +430,9 @@ namespace {
                ((TWinNTSystem*)gSystem)->DispatchSignals(kSigInterrupt);
             }
             else {
-               if (!G__get_security_error()) {
-                  G__genericerror("\n *** Break *** keyboard interrupt");
-               } else {
-                  Break("TInterruptHandler::Notify", "keyboard interrupt");
-                  if (TROOT::Initialized()) {
-                     gInterpreter->RewindDictionary();
-                  }
+               Break("TInterruptHandler::Notify", "keyboard interrupt");
+               if (TROOT::Initialized()) {
+                  gInterpreter->RewindDictionary();
                }
             }
             return kTRUE;

From 656e2078df6d5f2240329fa06c2c94dfd6d1a4f3 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 09:58:56 +0100
Subject: [PATCH 081/200] Don't redefine known types (fix compilation error)

---
 core/base/src/TString.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/base/src/TString.cxx b/core/base/src/TString.cxx
index 7f848a5b846bc..ea432fdbbedea 100644
--- a/core/base/src/TString.cxx
+++ b/core/base/src/TString.cxx
@@ -613,7 +613,7 @@ namespace {
 
    // From MurmurHash.h:
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER < 1800)
    // Microsoft Visual Studio
    typedef unsigned char uint8_t;
    typedef unsigned long uint32_t;

From 27f216ebec0e1bcef35969f7333776a27d893661 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 10:01:34 +0100
Subject: [PATCH 082/200] Fix compilation error C2483: object with constructor
 or destructor cannot be declared 'thread'

---
 core/base/src/TSystem.cxx | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx
index 5bca540688424..58e1b82f06c92 100644
--- a/core/base/src/TSystem.cxx
+++ b/core/base/src/TSystem.cxx
@@ -1991,7 +1991,11 @@ TString &TSystem::GetLastErrorString()
 {
    // Return the thread local storage for the custom last error message
 
+#ifdef R__WIN32
+   static TString gLastErrorString;
+#else
    thread_local TString gLastErrorString;
+#endif
 
    return gLastErrorString;
 }

From 0fe9b17ad2844392c92bbd1b3168508a1338c500 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 10:07:43 +0100
Subject: [PATCH 083/200] Fix MSVC compilation error C2466: cannot allocate an
 array of constant size 0

---
 core/base/src/TListOfTypes.cxx | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/core/base/src/TListOfTypes.cxx b/core/base/src/TListOfTypes.cxx
index 7341889cec44e..c33cc768c3e2e 100644
--- a/core/base/src/TListOfTypes.cxx
+++ b/core/base/src/TListOfTypes.cxx
@@ -67,7 +67,11 @@ static bool NameExistsElsewhere(const char* name){
       // We have a scope
       const auto enName = lastPos + 1;
       const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)name) / sizeof(decltype(*lastPos)) - 1;
+#ifdef R__WIN32
+      char *scopeName = new char[scopeNameSize + 1];
+#else
       char scopeName[scopeNameSize + 1]; // on the stack, +1 for the terminating character '\0'
+#endif
       strncpy(scopeName, name, scopeNameSize);
       scopeName[scopeNameSize] = '\0';
       // We have now an enum name and a scope name
@@ -82,6 +86,9 @@ static bool NameExistsElsewhere(const char* name){
                theEnum = listOfEnums->THashList::FindObject(enName);
          }
       }
+#ifdef R__WIN32
+      delete [] scopeName;
+#endif
    } else { // Here we look in the global scope
       theEnum = ((TListOfEnums*)gROOT->GetListOfEnums())->THashList::FindObject(name);
    }

From c78ad07a7c6c452778daad86bf393d2e8e679f8f Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 10:12:39 +0100
Subject: [PATCH 084/200] Don't define a global dlerror() function (on Windows)
 to avoid potential redefinition in TROOT.cxx

---
 core/meta/src/TCling.cxx | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index e92e15117a3b1..9aae2599fa237 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -171,13 +171,6 @@ extern "C" {
 #define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
 #define dlopen(library_name, flags) ::LoadLibraryEx(library_name, NULL, DONT_RESOLVE_DLL_REFERENCES)
 #define dlclose(library) ::FreeLibrary((HMODULE)library)
-char *dlerror() {
-   static char Msg[1000];
-   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
-                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg,
-                 sizeof(Msg), NULL);
-   return Msg;
-}
 #define thread_local static __declspec(thread)
 #endif
 #endif
@@ -1463,8 +1456,16 @@ void TCling::RegisterModule(const char* modulename,
    if (dyLibName) {
       // We were able to determine the library name.
       void* dyLibHandle = dlopen(dyLibName, RTLD_LAZY | RTLD_GLOBAL);
+#ifdef R__WIN32
+      if (!dyLibHandle) {
+         char dyLibError[1000];
+         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), dyLibError,
+                       sizeof(dyLibError), NULL);
+#else
       const char* dyLibError = dlerror();
       if (dyLibError) {
+#endif
          if (gDebug > 0) {
             ::Info("TCling::RegisterModule",
                    "Cannot open shared library %s for dictionary %s:\n  %s",

From 7d5eda6735ccba2aa65f6edf04e1cb939f4481ea Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 10:22:42 +0100
Subject: [PATCH 085/200] Fix compilation errors on Windows

- define dlsym() dlopen() dlclose() and dlerror() functions
- fix std::atomic<T*> operator bool issue with MSVC++
---
 core/base/src/TROOT.cxx  | 21 +++++++++++++++++----
 core/meta/src/TClass.cxx | 10 +++++-----
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index 8b94d8b27b144..ed29862869abf 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -71,6 +71,19 @@
 #include <stdlib.h>
 #ifdef WIN32
 #include <io.h>
+#include "Windows4Root.h"
+#include <Psapi.h>
+#define RTLD_DEFAULT ((void *) -2)
+#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
+#define dlopen(library_name, flags) ::LoadLibraryEx(library_name, NULL, DONT_RESOLVE_DLL_REFERENCES)
+#define dlclose(library) ::FreeLibrary((HMODULE)library)
+char *dlerror() {
+   static char Msg[1000];
+   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
+                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg,
+                 sizeof(Msg), NULL);
+   return Msg;
+}
 #else
 #include <dlfcn.h>
 #endif
@@ -1481,7 +1494,7 @@ void TROOT::Idle(UInt_t idleTimeInSec, const char *command)
 {
    // Execute command when system has been idle for idleTimeInSec seconds.
 
-   if (!fApplication)
+   if (!fApplication.load())
       TApplication::CreateApplication();
 
    if (idleTimeInSec <= 0)
@@ -1966,7 +1979,7 @@ Long_t TROOT::ProcessLine(const char *line, Int_t *error)
    TString sline = line;
    sline = sline.Strip(TString::kBoth);
 
-   if (!fApplication)
+   if (!fApplication.load())
       TApplication::CreateApplication();
 
    return (*fApplication).ProcessLine(sline, kFALSE, error);
@@ -1986,7 +1999,7 @@ Long_t TROOT::ProcessLineSync(const char *line, Int_t *error)
    TString sline = line;
    sline = sline.Strip(TString::kBoth);
 
-   if (!fApplication)
+   if (!fApplication.load())
       TApplication::CreateApplication();
 
    return (*fApplication).ProcessLine(sline, kTRUE, error);
@@ -2003,7 +2016,7 @@ Long_t TROOT::ProcessLineFast(const char *line, Int_t *error)
    TString sline = line;
    sline = sline.Strip(TString::kBoth);
 
-   if (!fApplication)
+   if (!fApplication.load())
       TApplication::CreateApplication();
 
    Long_t result = 0;
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 9930e2600f44a..40f262657e0f6 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -1557,7 +1557,7 @@ TClass::~TClass()
       fFuncTemplate->Delete();
    delete fFuncTemplate; fFuncTemplate = 0;
 
-   if (fMethod)
+   if (fMethod.load())
       (*fMethod).Delete();
    delete fMethod.load();   fMethod=0;
 
@@ -3391,7 +3391,7 @@ TList *TClass::GetListOfMethods(Bool_t load /* = kTRUE */)
 
    R__LOCKGUARD(gInterpreterMutex);
 
-   if (!fMethod) GetMethodList();
+   if (!fMethod.load()) GetMethodList();
    if (load) {
       if (gDebug>0) Info("GetListOfMethods","Header Parsing - Asking for all the methods of class %s: this can involve parsing.",GetName());
       (*fMethod).Load();
@@ -3756,7 +3756,7 @@ void TClass::ResetCaches()
       fData->Unload();
    if (fEnums)
       fEnums->Unload();
-   if (fMethod)
+   if (fMethod.load())
       (*fMethod).Unload();
 
    delete fAllPubData; fAllPubData = 0;
@@ -3886,7 +3886,7 @@ TListOfFunctions *TClass::GetMethodList()
    // the internal type of fMethod and thus can not be made public.
    // It also never 'loads' the content of the list.
 
-   if (!fMethod) {
+   if (!fMethod.load()) {
       std::unique_ptr<TListOfFunctions> temp{ new TListOfFunctions(this) };
       TListOfFunctions* expected = nullptr;
       if(fMethod.compare_exchange_strong(expected, temp.get()) ) {
@@ -5637,7 +5637,7 @@ void TClass::SetUnloaded()
    fImplFileLine = 0;
    fTypeInfo     = 0;
 
-   if (fMethod) {
+   if (fMethod.load()) {
       (*fMethod).Unload();
    }
    if (fData) {

From 6624774cc75f49c0915a20b2b364b60f50b7e00c Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 27 Feb 2015 08:35:04 +0100
Subject: [PATCH 086/200] jsroot: reduce usage of jQuery in JavaScript graphics

1. As much as possible reqduce usage of jQuery and jQuery-UI.
   Anyway SVG-based graphic implemented with d3.js.
   Only for user interface like menus or buttons or for complex
   UI interfaces keep usage of jquery
2. Introduce JSRootPainter.jquery.js script where all
   jquery-specific code is collected
3. Support usage of .min.js version of scripts
4. When JSROOT used without objects browser (nobrowser mode),
   total size of load scripts reduced from 960K to 335K

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/changes.md                      |   29 +-
 etc/http/files/draw.htm                  |    8 +-
 etc/http/files/online.htm                |    2 +-
 etc/http/index.htm                       |   12 +-
 etc/http/scripts/JSRoot3DPainter.js      |   41 +-
 etc/http/scripts/JSRootCore.js           |  206 ++-
 etc/http/scripts/JSRootInterface.js      |  118 +-
 etc/http/scripts/JSRootPainter.jquery.js |  860 +++++++++++
 etc/http/scripts/JSRootPainter.js        | 1658 +++++++---------------
 9 files changed, 1571 insertions(+), 1363 deletions(-)
 create mode 100644 etc/http/scripts/JSRootPainter.jquery.js

diff --git a/etc/http/changes.md b/etc/http/changes.md
index 13275228ab61e..740a7bcc43ff8 100644
--- a/etc/http/changes.md
+++ b/etc/http/changes.md
@@ -1,7 +1,16 @@
 # JSROOT changelog {#jsroot_changes}
 
-This is further development of JSRootIO project of Bertrand Bellenot. 
-Many old problems and errors are fixed, new functions are provided.  
+This is further development of JSRootIO project of Bertrand Bellenot.
+Many old problems and errors are fixed, new functions are provided.
+
+## Changes in v 3.4
+1. Support usage of minimized versions of .js and .css files.
+   Minimized scripts used by default on web servers.
+2. Implement JSROOT.extend instead of jQuery.extend, reduce
+   usage of jquery.js in core JSROOT classes
+3. Implement main graphics without jquery at all,
+   such mode used in `nobrowser` mode.
+
 
 ## Changes in v 3.3
 1. Use d3.time.scale for display of time scales
@@ -21,16 +30,16 @@ Many old problems and errors are fixed, new functions are provided.
     similar items from different files. Could be used in URL like:
       `...&files=[file1.root,file2.root]&items=[file1.root/hpx, file2.root/_same_]`
       `...&files=[file1.root,file2.root]&item=file1.root/hpx+file2.root/_same_`
-    Main limitation - file names should have similar length.   
+    Main limitation - file names should have similar length.
 11. When 'autozoom' specified in draw options, histogram zoomed into
-    non-empty content. Same command available via context menu. 
-12. Item of 'Text' kind can be created. It is displayed as 
+    non-empty content. Same command available via context menu.
+12. Item of 'Text' kind can be created. It is displayed as
     plain text in the browser. If property 'mathjax' specified,
     MathJax.js library will be loaded and used for rendering.
     See httpcontrol.C macro for example.
-13. When using foreignObject, provide workaround for absolute positioning 
+13. When using foreignObject, provide workaround for absolute positioning
     problem in Chrome/Safari, see <http://bit.ly/1wjqCQ9>
-   
+
 
 ## Changes in 3.2
 1. Support JSON objects embedding in html pages, produced by THttpServer
@@ -50,13 +59,13 @@ Many old problems and errors are fixed, new functions are provided.
 2. Implement JSROOT.Create() method to create supported
    in JavaScript ROOT classes like TH1 or TGraph
 3. Fix problem with JSROOT.draw in HTML element with zero width (display:none)
-4. Provide possibility to load user scripts with JSROOT.BuildSimpleGUI 
+4. Provide possibility to load user scripts with JSROOT.BuildSimpleGUI
    and JSROOT.AssertPrerequisites, also with main index.htm
 5. Support of TCutG drawing
 6. Implement hierarchy display (former dtree) with jQuery
 7. Fix several problems in drawing optimization
-8. Implement dragging objects from hierarchy browser into existing canvas 
-   to superimpose several objects 
+8. Implement dragging objects from hierarchy browser into existing canvas
+   to superimpose several objects
 9. Implement col2 and col3 draw options, using html5 canvas
 10. Support 'p' and 'p0' draw options for TH1 class
 
diff --git a/etc/http/files/draw.htm b/etc/http/files/draw.htm
index 758be937fcfc1..7afbbd461cd66 100644
--- a/etc/http/files/draw.htm
+++ b/etc/http/files/draw.htm
@@ -5,14 +5,14 @@
       <title>Draw of single element</title>
       <!--  this file used by THttpServer to display single element -->
       <meta http-equiv="X-UA-Compatible" content="IE=Edge; text/html">
-      <script type="text/javascript" src="/jsrootsys/scripts/JSRootCore.js?2d"></script>
+      <script type="text/javascript" src="/jsrootsys/scripts/JSRootCore.js?2d&jq2d&onload=CreateGui"></script>
    </head>
 
    <script type='text/javascript'>
 
       function GetCachedObject() { return "$$$root.json$$$"; }
 
-      function CreateDrawGui() {
+      function CreateGui() {
          // analyze URL options
          var drawopt = JSROOT.GetUrlOption("opt");
 
@@ -56,12 +56,12 @@
          if (monitor!=null)
             setInterval(get_function, monitor);
 
-         JSROOT.RegisterForResize(function() { if (objpainter) objpainter.CheckResize(); });
+         JSROOT.RegisterForResize('drawing');
       }
 
    </script>
 
-   <body onload="CreateDrawGui()">
+   <body>
       <div id="drawing" style="position:absolute; left:1px; top:1px; bottom:1px; right:1px">
          loading scripts...
       </div>
diff --git a/etc/http/files/online.htm b/etc/http/files/online.htm
index 68e7a8caf9361..7a0a3de28b0bb 100644
--- a/etc/http/files/online.htm
+++ b/etc/http/files/online.htm
@@ -10,7 +10,7 @@
    </head>
 
    <script type="text/javascript">
-      function GetCashedHierarchy() { return "$$$h.json$$$"; }
+      function GetCachedHierarchy() { return "$$$h.json$$$"; }
    </script>
 
    <body>
diff --git a/etc/http/index.htm b/etc/http/index.htm
index afe6ff9d73806..4b32be9c89c09 100644
--- a/etc/http/index.htm
+++ b/etc/http/index.htm
@@ -15,7 +15,6 @@
    </body>
 </html>
 
-
 <!--
 
 This is JSROOT main page, which aims to display content of ROOT files.
@@ -25,23 +24,22 @@
    opt       - draw option(s) for the item(s)
    layout    - can be 'collapsible', 'tabs' or gridNxM where N and M are integer values
    nobrowser - only file item(s) will be displayed, browser will be disabled
-   load      - name of JavaScript(s), automatically loaded at the beginning 
+   load      - name of JavaScript(s), automatically loaded at the beginning
 
 Example:
-   http://root.cern.ch/js/3.3/?file=../files/hsimple.root&layout=grid2x2&item=[hpx;1,hpxpy;1]&opts=[,colz]
+   https://root.cern.ch/js/3.4/?file=../files/hsimple.root&layout=grid2x2&item=[hpx;1,hpxpy;1]&opts=[,colz]
 
 Page can be used to open files from other web servers like:
-
-   http://web-docs.gsi.de/~linev/js/3.3/index.htm?file=http://root.cern.ch/js/files/hsimple.root
+   https://root.cern.ch/js/3.4/?file=https://web-docs.gsi.de/~linev/js/files/hsimple.root
 
 But one should be aware about Cross-Origin Request blocking.
 Read https://developer.mozilla.org/en/http_access_control for more details.
 
 To avoid problem at all, one can copy only index.htm on the web server where data files are located.
 And specify full path to the JSRootCore.js script like
-   <script type="text/javascript" src="http://root.cern.ch/js/3.3/scripts/JSRootCore.js?gui"></script>
+   <script type="text/javascript" src="https://root.cern.ch/js/3.4/scripts/JSRootCore.min.js?gui"></script>
 
 If necessary, complete JSROOT can be installed on the web server.
-Sources can be found in $ROOTSYS/etc/http/.
+All sources can be found in $ROOTSYS/etc/http/ directory.
 
 -->
diff --git a/etc/http/scripts/JSRoot3DPainter.js b/etc/http/scripts/JSRoot3DPainter.js
index eb102431db0c2..c4330058c087c 100644
--- a/etc/http/scripts/JSRoot3DPainter.js
+++ b/etc/http/scripts/JSRoot3DPainter.js
@@ -224,38 +224,37 @@
       });
 
       $(renderer.domElement).on('contextmenu', function(e) {
-
          e.preventDefault();
 
          if (JSROOT.gStyle.Tooltip) tooltip.hide();
 
-         var menu = JSROOT.createMenu();
-
-         if (painter)
-            menu.add("header:"+ painter.histo['fName']);
+         JSROOT.Painter.createMenu(function(menu) {
+            if (painter)
+               menu.add("header:"+ painter.histo['fName']);
 
-         menu.add(JSROOT.gStyle.Tooltip ? "Disable tooltip" : "Enable tooltip", function() {
-            JSROOT.gStyle.Tooltip = !JSROOT.gStyle.Tooltip;
-            tooltip.hide();
-         });
-
-         if (painter)
-            menu.add("Switch to 2D", function() {
-               $(painter.svg_pad()).show().parent().find(renderer.domElement).remove();
+            menu.add(JSROOT.gStyle.Tooltip ? "Disable tooltip" : "Enable tooltip", function() {
+               JSROOT.gStyle.Tooltip = !JSROOT.gStyle.Tooltip;
                tooltip.hide();
-               painter.Draw2D();
             });
-         menu.add("Close");
 
-         menu.show(e.originalEvent);
+            if (painter)
+               menu.add("Switch to 2D", function() {
+                  $(painter.svg_pad().node()).show().parent().find(renderer.domElement).remove();
+                  tooltip.hide();
+                  painter.Draw2D();
+               });
+            menu.add("Close");
+
+            menu.show(e.originalEvent);
+         });
 
       });
    }
 
    JSROOT.Painter.real_drawHistogram2D = function(painter) {
 
-      var w = Number(painter.svg_pad(true).attr("width")),
-          h = Number(painter.svg_pad(true).attr("height")), size = 100;
+      var w = Number(painter.svg_pad().attr("width")),
+          h = Number(painter.svg_pad().attr("height")), size = 100;
 
       var xmin = painter.xmin, xmax = painter.xmax;
       if (painter.zoom_xmin != painter.zoom_xmax) {
@@ -508,7 +507,7 @@
                                       new THREE.CanvasRenderer({ antialias : true });
       renderer.setClearColor(0xffffff, 1);
       renderer.setSize(w, h);
-      $(painter.svg_pad()).hide().parent().append(renderer.domElement);
+      $(painter.svg_pad().node()).hide().parent().append(renderer.domElement);
       renderer.render(scene, camera);
 
       JSROOT.Painter.add3DInteraction(renderer, scene, camera, toplevel, painter);
@@ -523,8 +522,8 @@
       var pad = painter.root_pad();
 
       var render_to;
-      if (painter.svg_pad())
-         render_to = $(painter.svg_pad()).hide().parent();
+      if (!painter.svg_pad().empty())
+         render_to = $(painter.svg_pad().node()).hide().parent();
       else
          render_to = $("#" + divid);
 
diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index a2cfcd82bd558..f3cef7197daf5 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,14 +14,10 @@
 
    JSROOT = {};
 
-   JSROOT.version = "3.3 25/02/2015";
+   JSROOT.version = "3.4 dev 26/02/2015";
 
    JSROOT.source_dir = "";
-
-   // TODO: all jQuery-related functions should go into extra script
-   JSROOT.clone = function(obj) {
-      return jQuery.extend(true, {}, obj);
-   }
+   JSROOT.source_min = false;
 
    JSROOT.id_counter = 0;
 
@@ -121,6 +117,52 @@
       return value;
    }
 
+   // This should be similar to the jQuery.extend method
+   // Major complication - when same object appears N times in the source,
+   // it should be cloned once and inserted N times in the target and not cloned N times
+   JSROOT.extend = function(tgt, src, map) {
+      if (!map) map = { obj:[], clones:[] };
+
+      if (typeof src != 'object') return src;
+
+      if (src == null) return null;
+
+      var i = map.obj.indexOf(src);
+      if (i>=0) return map.clones[i];
+
+      // process array
+      if (Object.prototype.toString.apply(src) === '[object Array]') {
+         if ((tgt==null) || (Object.prototype.toString.apply(tgt) != '[object Array]')) {
+            tgt = [];
+            map.obj.push(src);
+            map.clones.push(tgt);
+         }
+
+         for (i = 0; i < src.length; i++)
+            tgt.push(JSROOT.extend(null, src[i], map));
+
+         return tgt;
+      }
+
+      if ((tgt==null) || (typeof tgt != 'object')) {
+         tgt = {};
+         map.obj.push(src);
+         map.clones.push(tgt);
+      }
+
+      var k, ks = Object.keys(src);
+      for (i = 0; i < ks.length; i++) {
+         k = ks[i];
+         tgt[k] = JSROOT.extend(tgt[k], src[k], map);
+      }
+      return tgt;
+   }
+
+   // Instead of jquery use JSROOT.extend function
+   JSROOT.clone = function(obj) {
+      return JSROOT.extend(null, obj);
+   }
+
    JSROOT.parse = function(arg) {
       if ((arg==null) || (arg=="")) return null;
       var obj = JSON.parse(arg);
@@ -249,11 +291,13 @@
       // Result will be returned to the callback functions
       // If failed, request returns null
 
+      var xhr = new XMLHttpRequest();
+
       function callback(res) {
-         if (typeof user_call_back == 'function') user_call_back(res);
+         // we set pointer on request when calling callback
+         if (typeof user_call_back == 'function') user_call_back.call(xhr, res);
       }
 
-      var xhr = new XMLHttpRequest();
 
 //      if (typeof ActiveXObject == "function") {
       if (window.ActiveXObject) {
@@ -469,43 +513,62 @@
 
       if (typeof kind == 'function') { andThan = kind; kind = null; }
 
-      if (typeof kind != 'string') kind = "2d";
+      if ((typeof kind != 'string') || (kind == ''))
+         return JSROOT.CallBack(andThan);
+
       if (kind.charAt(kind.length-1)!=";") kind+=";";
+      var ext = JSROOT.source_min ? ".min" : "";
+
+      var need_jquery = false;
 
       // file names should be separated with ';'
-      var allfiles = '$$$scripts/jquery.min.js';
+      var allfiles = '';
 
       if (kind.indexOf('io;')>=0)
-         allfiles += ";$$$scripts/rawinflate.js" +
-                     ";$$$scripts/JSRootIOEvolution.js";
+         allfiles += "$$$scripts/rawinflate" + ext + ".js;" +
+                     "$$$scripts/JSRootIOEvolution" + ext + ".js;";
 
       if (kind.indexOf('2d;')>=0) {
-         allfiles += ';$$$style/jquery-ui.css' +
-                     ';$$$scripts/jquery-ui.min.js' +
-                     ';$$$scripts/d3.v3.min.js' +
-                     ';$$$scripts/JSRootPainter.js' +
-                     ';$$$style/JSRootPainter.css';
-         if (JSROOT.touches)
-            allfiles += ';$$$scripts/touch-punch.min.js';
+         allfiles += '$$$scripts/d3.v3.min.js;' +
+                     '$$$scripts/JSRootPainter' + ext + ".js;" +
+                     '$$$style/JSRootPainter' + ext + ".css;";
+      }
+
+      if (kind.indexOf('jq2d;')>=0) {
+         allfiles += '$$$scripts/JSRootPainter.jquery' + ext + ".js;";
+         need_jquery = true;
       }
 
-      if (kind.indexOf("3d;")>=0)
-         allfiles += ";$$$scripts/jquery.mousewheel.js" +
-                     ";$$$scripts/three.min.js" +
-                     ";$$$scripts/helvetiker_regular.typeface.js" +
-                     ";$$$scripts/helvetiker_bold.typeface.js" +
-                     ";$$$scripts/JSRoot3DPainter.js";
+      if (kind.indexOf("3d;")>=0) {
+         need_jquery = true;
+         allfiles += "$$$scripts/jquery.mousewheel" + ext + ".js;" +
+                     "$$$scripts/three.min.js;" +
+                     "$$$scripts/helvetiker_regular.typeface.js;" +
+                     "$$$scripts/helvetiker_bold.typeface.js;" +
+                     "$$$scripts/JSRoot3DPainter" + ext + ".js;";
+      }
 
       if (kind.indexOf("mathjax;")>=0)
-        allfiles += ";https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+        allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML;";
 
-      if (kind.indexOf("simple;")>=0)
-         allfiles += ';$$$scripts/JSRootInterface.js' +
-                     ';$$$style/JSRootInterface.css';
+      if (kind.indexOf("simple;")>=0) {
+         need_jquery = true;
+         allfiles += '$$$scripts/JSRootInterface' + ext + ".js;" +
+                     '$$$style/JSRootInterface' + ext + ".css;";
+      }
+
+      if (need_jquery) {
+         allfiles = '$$$scripts/jquery.min.js;' +
+                    '$$$style/jquery-ui.css;' +
+                    '$$$scripts/jquery-ui.min.js;' +
+                    allfiles;
+         if (JSROOT.touches)
+            allfiles += '$$$scripts/touch-punch.min.js;';
+      }
 
       var pos = kind.indexOf("user:");
       if (pos<0) pos = kind.indexOf("load:");
-      if (pos>=0) allfiles += ";" + kind.slice(pos+5);
+      if (pos>=0) allfiles += kind.slice(pos+5);
 
       JSROOT.loadScript(allfiles, andThan, debugout);
    }
@@ -517,11 +580,12 @@
       }
 
       var debugout = null;
+      var nobrowser = JSROOT.GetUrlOption('nobrowser')!=null;
+      var requirements = "io;2d;";
 
-      var requirements = "2d;io;simple;";
-
-      if (document.getElementById('simpleGUI')) debugout = 'simpleGUI'; else
-      if (document.getElementById('onlineGUI')) { debugout = 'onlineGUI'; requirements = "2d;simple;"; }
+      if (document.getElementById('simpleGUI')) { debugout = 'simpleGUI'; requirements = "io;2d;" } else
+      if (document.getElementById('onlineGUI')) { debugout = 'onlineGUI'; requirements = "2d;"; }
+      if (!nobrowser) requirements+='jq2d;simple;';
 
       if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("autoload");
       if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("load");
@@ -530,8 +594,9 @@
          requirements += "load:" + user_scripts + ";";
 
       JSROOT.AssertPrerequisites(requirements, function() {
-         if (typeof BuildSimpleGUI == 'function') BuildSimpleGUI();
-         if (typeof andThen == 'function') andThen();
+         var func = JSROOT.findFunction(nobrowser ? 'JSROOT.BuildNobrowserGUI' : 'BuildSimpleGUI');
+         JSROOT.CallBack(func);
+         JSROOT.CallBack(andThen);
       }, debugout);
    }
 
@@ -557,57 +622,57 @@
          obj = { _typename: typename };
 
       if (typename == 'TObject')
-         jQuery.extend(obj, { fUniqueID: 0, fBits: 0x3000008 });
+         JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008 });
       else
       if (typename == 'TNamed')
-         jQuery.extend(obj, { fUniqueID: 0, fBits: 0x3000008, fName: "", fTitle: "" });
+         JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008, fName: "", fTitle: "" });
       else
       if (typename == 'TList')
-         jQuery.extend(obj, { name: "TList", arr : [], opt : [] });
+         JSROOT.extend(obj, { name: "TList", arr : [], opt : [] });
       else
       if (typename == 'TAttAxis') {
-         jQuery.extend(obj, { fNdivisions: 510, fAxisColor: 1,
+         JSROOT.extend(obj, { fNdivisions: 510, fAxisColor: 1,
             fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.05, fLabelSize: 0.035, fTickLength: 0.03,
             fTitleOffset: 1, fTitleSize: 0.035, fTitleColor: 1, fTitleFont : 42 });
       } else
       if (typename == 'TAxis') {
          JSROOT.Create("TNamed", obj);
          JSROOT.Create("TAttAxis", obj);
-         jQuery.extend(obj, { fNbins: 0, fXmin: 0, fXmax: 0, fXbins : [], fFirst: 0, fLast: 0,
+         JSROOT.extend(obj, { fNbins: 0, fXmin: 0, fXmax: 0, fXbins : [], fFirst: 0, fLast: 0,
                               fBits2: 0, fTimeDisplay: false, fTimeFormat: "", fLabels: null });
       } else
       if (typename == 'TAttLine') {
-         jQuery.extend(obj, { fLineColor: 1, fLineStyle : 1, fLineWidth : 1 });
+         JSROOT.extend(obj, { fLineColor: 1, fLineStyle : 1, fLineWidth : 1 });
       } else
       if (typename == 'TAttFill') {
-         jQuery.extend(obj, { fFillColor: 0, fFillStyle : 0 } );
+         JSROOT.extend(obj, { fFillColor: 0, fFillStyle : 0 } );
       } else
       if (typename == 'TAttMarker') {
-         jQuery.extend(obj, { fMarkerColor: 1, fMarkerStyle : 1, fMarkerSize : 1. });
+         JSROOT.extend(obj, { fMarkerColor: 1, fMarkerStyle : 1, fMarkerSize : 1. });
       } else
       if (typename == 'TBox') {
          JSROOT.Create("TObject", obj);
          JSROOT.Create("TAttLine", obj);
          JSROOT.Create("TAttFill", obj);
-         jQuery.extend(obj, { fX1: 0, fY1: 0, fX2: 1, fY2: 1 });
+         JSROOT.extend(obj, { fX1: 0, fY1: 0, fX2: 1, fY2: 1 });
       } else
       if (typename == 'TPave') {
          JSROOT.Create("TBox", obj);
-         jQuery.extend(obj, { fX1NDC : 0., fY1NDC: 0, fX2NDC: 1, fY2NDC: 1,
+         JSROOT.extend(obj, { fX1NDC : 0., fY1NDC: 0, fX2NDC: 1, fY2NDC: 1,
                               fBorderSize: 0, fInit: 1, fShadowColor: 1,
                               fCornerRadius: 0, fOption: "blNDC", fName: "title" });
       } else
       if (typename == 'TAttText') {
-         jQuery.extend(obj, { fTextAngle: 0, fTextSize: 0, fTextAlign: 22, fTextColor: 1, fTextFont: 42});
+         JSROOT.extend(obj, { fTextAngle: 0, fTextSize: 0, fTextAlign: 22, fTextColor: 1, fTextFont: 42});
       } else
       if (typename == 'TPaveText') {
          JSROOT.Create("TPave", obj);
          JSROOT.Create("TAttText", obj);
-         jQuery.extend(obj, { fLabel: "", fLongest: 27, fMargin: 0.05, fLines: JSROOT.Create("TList") });
+         JSROOT.extend(obj, { fLabel: "", fLongest: 27, fMargin: 0.05, fLines: JSROOT.Create("TList") });
       } else
       if (typename == 'TPaveStats') {
          JSROOT.Create("TPaveText", obj);
-         jQuery.extend(obj, { fOptFit: 0, fOptStat: 0, fFitFormat: "", fStatFormat: "", fParent: null });
+         JSROOT.extend(obj, { fOptFit: 0, fOptStat: 0, fFitFormat: "", fStatFormat: "", fParent: null });
       } else
       if (typename == 'TH1') {
          JSROOT.Create("TNamed", obj);
@@ -615,7 +680,7 @@
          JSROOT.Create("TAttFill", obj);
          JSROOT.Create("TAttMarker", obj);
 
-         jQuery.extend(obj, {
+         JSROOT.extend(obj, {
             fNcells : 0,
             fXaxis: JSROOT.Create("TAxis"),
             fYaxis: JSROOT.Create("TAxis"),
@@ -629,22 +694,22 @@
       } else
       if (typename == 'TH1I' || typename == 'TH1F' || typename == 'TH1D' || typename == 'TH1S' || typename == 'TH1C') {
          JSROOT.Create("TH1", obj);
-         jQuery.extend(obj, { fArray: [] });
+         JSROOT.extend(obj, { fArray: [] });
       } else
       if (typename == 'TH2') {
          JSROOT.Create("TH1", obj);
-         jQuery.extend(obj, { fScalefactor: 1., fTsumwy: 0.,  fTsumwy2: 0, fTsumwxy : 0});
+         JSROOT.extend(obj, { fScalefactor: 1., fTsumwy: 0.,  fTsumwy2: 0, fTsumwxy : 0});
       } else
       if (typename == 'TH2I' || typename == 'TH2F' || typename == 'TH2D' || typename == 'TH2S' || typename == 'TH2C') {
          JSROOT.Create("TH2", obj);
-         jQuery.extend(obj, { fArray: [] });
+         JSROOT.extend(obj, { fArray: [] });
       } else
       if (typename == 'TGraph') {
          JSROOT.Create("TNamed", obj);
          JSROOT.Create("TAttLine", obj);
          JSROOT.Create("TAttFill", obj);
          JSROOT.Create("TAttMarker", obj);
-         jQuery.extend(obj, { fFunctions: JSROOT.Create("TList"), fHistogram: JSROOT.CreateTH1(),
+         JSROOT.extend(obj, { fFunctions: JSROOT.Create("TList"), fHistogram: JSROOT.CreateTH1(),
                               fMaxSize: 0, fMaximum:0, fMinimum:0, fNpoints: 0, fX: [], fY: [] });
       }
 
@@ -658,32 +723,32 @@
 
    JSROOT.CreateTH1 = function(nbinsx) {
       var histo = JSROOT.Create("TH1I");
-      jQuery.extend(histo, { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
+      JSROOT.extend(histo, { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
 
       if (nbinsx!=null) {
          histo['fNcells'] = nbinsx+2;
          for (var i=0;i<histo['fNcells'];i++) histo['fArray'].push(0);
-         jQuery.extend(histo['fXaxis'], { fNbins: nbinsx, fXmin: 0,  fXmax: nbinsx });
+         JSROOT.extend(histo['fXaxis'], { fNbins: nbinsx, fXmin: 0,  fXmax: nbinsx });
       }
       return histo;
    }
 
    JSROOT.CreateTH2 = function(nbinsx, nbinsy) {
       var histo = JSROOT.Create("TH2I");
-      jQuery.extend(histo, { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
+      JSROOT.extend(histo, { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" });
 
       if ((nbinsx!=null) && (nbinsy!=null)) {
          histo['fNcells'] = (nbinsx+2) * (nbinsy+2);
          for (var i=0;i<histo['fNcells'];i++) histo['fArray'].push(0);
-         jQuery.extend(histo['fXaxis'], { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
-         jQuery.extend(histo['fYaxis'], { fNbins: nbinsy, fXmin: 0, fXmax: nbinsy });
+         JSROOT.extend(histo['fXaxis'], { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx });
+         JSROOT.extend(histo['fYaxis'], { fNbins: nbinsy, fXmin: 0, fXmax: nbinsy });
       }
       return histo;
    }
 
    JSROOT.CreateTGraph = function(npoints) {
       var graph = JSROOT.Create("TGraph");
-      jQuery.extend(graph, { fBits: 0x3000408, fName: "dummy_graph_" + this.id_counter++, fTitle: "dummytitle" });
+      JSROOT.extend(graph, { fBits: 0x3000408, fName: "dummy_graph_" + this.id_counter++, fTitle: "dummytitle" });
 
       if (npoints>0) {
          graph['fMaxSize'] = graph['fNpoints'] = npoints;
@@ -2115,26 +2180,35 @@
          var src = scripts[n]['src'];
          if ((src == null) || (src.length == 0)) continue;
 
-         var pos = src.indexOf("scripts/JSRootCore.js");
+         var pos = src.indexOf("scripts/JSRootCore.");
          if (pos<0) continue;
 
          JSROOT.source_dir = src.substr(0, pos);
+         JSROOT.source_min = src.indexOf("scripts/JSRootCore.min.js")>=0;
 
          console.log("Set JSROOT.source_dir to " + JSROOT.source_dir);
 
-         if (JSROOT.GetUrlOption('gui', src)!=null) return JSROOT.BuildSimpleGUI();
+         if (JSROOT.GetUrlOption('gui', src)!=null) {
+            window.onload = function() { JSROOT.BuildSimpleGUI(); }
+            return;
+         }
 
          var prereq = "";
          if (JSROOT.GetUrlOption('io', src)!=null) prereq += "io;";
          if (JSROOT.GetUrlOption('2d', src)!=null) prereq += "2d;";
+         if (JSROOT.GetUrlOption('jq2d', src)!=null) prereq += "jq2d;";
          if (JSROOT.GetUrlOption('3d', src)!=null) prereq += "3d;";
          var user = JSROOT.GetUrlOption('load', src);
          if ((user!=null) && (user.length>0)) prereq += "load:" + user;
          var onload = JSROOT.GetUrlOption('onload', src);
-         if (prereq.length>0) JSROOT.AssertPrerequisites(prereq, onload); else
-         if (onload!=null) {
-            onload = JSROOT.findFunction(onload);
-            if (typeof onload == 'function') onload();
+
+         if ((prereq.length>0) || (onload!=null))
+            window.onload = function() {
+              if (prereq.length>0) JSROOT.AssertPrerequisites(prereq, onload); else
+              if (onload!=null) {
+                 onload = JSROOT.findFunction(onload);
+                 if (typeof onload == 'function') onload();
+              }
          }
 
          return;
diff --git a/etc/http/scripts/JSRootInterface.js b/etc/http/scripts/JSRootInterface.js
index c94877edbe3c7..57d668c9f6b34 100644
--- a/etc/http/scripts/JSRootInterface.js
+++ b/etc/http/scripts/JSRootInterface.js
@@ -62,6 +62,9 @@ function ReadFile() {
 
 function BuildSimpleGUI() {
 
+   if (JSROOT.GetUrlOption("nobrowser")!=null)
+      return JSROOT.BuildNobrowserGUI();
+
    var myDiv = $('#simpleGUI');
    var online = false;
 
@@ -73,8 +76,6 @@ function BuildSimpleGUI() {
 
    JSROOT.Painter.readStyleFromURL();
 
-   var nobrowser = JSROOT.GetUrlOption("nobrowser") != null;
-
    var guiCode = "<div id='left-div' class='column'>";
 
    if (online) {
@@ -127,50 +128,20 @@ function BuildSimpleGUI() {
 
    var drawDivId = 'right-div';
 
-   if (nobrowser) {
-      guiCode = "";
-      $('html').css('height','100%');
-      $('body').css('min-height','100%').css('margin','0px').css("overflow", "hidden");
-
-      drawDivId = myDiv.attr('id');
-
-      myDiv.css("position", "absolute")
-           .css("left", "1px")
-           .css("top", "1px")
-           .css("bottom", "1px")
-           .css("right", "1px");
-   }
-
    myDiv.empty().append(guiCode);
 
-   var filesarr = JSROOT.GetUrlOptionAsArray("file;files");
-   var filesdir = JSROOT.GetUrlOption("path");
-   if (filesdir!=null)
-      for (var i in filesarr) filesarr[i] = filesdir + filesarr[i];
-
-   var itemsarr = JSROOT.GetUrlOptionAsArray("item;items");
-
-   var optionsarr = JSROOT.GetUrlOptionAsArray("opt;opts");
-
-   var monitor = JSROOT.GetUrlOption("monitoring");
-
-   var ilayout = JSROOT.GetUrlOption("layout");
-   if (ilayout=="") ilayout = null;
-   var layout = ilayout;
+   var h0 = null;
 
-   hpainter = new JSROOT.HierarchyPainter('root', nobrowser ? null : 'browser');
+   if (online) {
+      if (typeof GetCachedHierarchy == 'function') h0 = GetCachedHierarchy();
+      if (typeof h0 != 'object') h0 = "";
+   }
 
-   if (JSROOT.GetUrlOption('files_monitoring')!=null) hpainter.files_monitoring = true;
+   hpainter = new JSROOT.HierarchyPainter('root', 'browser');
 
-   JSROOT.RegisterForResize(hpainter);
+   hpainter.SetDisplay(guiLayout(), drawDivId);
 
-   if (nobrowser) {
-      if (layout==null) layout= "simple";
-   } else {
-      if (layout==null)
-         layout = guiLayout();
-      else
-         setGuiLayout(layout);
+   hpainter.StartGUI(h0, function() {
 
       JSROOT.ConfigureVSeparator(hpainter);
 
@@ -179,63 +150,18 @@ function BuildSimpleGUI() {
       $("#layout").change(function() {
          if (hpainter) hpainter.SetDisplay(guiLayout(), drawDivId);
       });
-   }
-
-   hpainter.SetDisplay(layout, drawDivId);
 
-   hpainter.SetMonitoring(monitor);
-
-   var h0 = null;
-
-   if (online) {
-      if (!nobrowser)
+      if (online) {
          $("#monitoring")
-          .prop('checked', hpainter.IsMonitoring())
-          .click(function() {
-             hpainter.EnableMonitoring(this.checked);
-             if (this.checked) hpainter.updateAll();
-          });
-
-       if (typeof GetCashedHierarchy == 'function') h0 = GetCashedHierarchy();
-       if (typeof h0 != 'object') h0 = "";
-   } else {
-      if ((filesarr.length>0) && !nobrowser)
-         $("#urlToLoad").val(filesarr[0]);
-   }
-
-   function OpenAllFiles() {
-      if (filesarr.length>0)
-         hpainter.OpenRootFile(filesarr.shift(), OpenAllFiles);
-      else
-         hpainter.displayAll(itemsarr, optionsarr, function() { hpainter.RefreshHtml(); });
-   }
-
-   function AfterOnlineOpened() {
-      // check if server enables monitoring
-      if (('_monitoring' in hpainter.h) && (monitor==null)) {
-         hpainter.SetMonitoring(hpainter.h._monitoring);
-         if (!nobrowser) $("#monitoring").prop('checked', hpainter.IsMonitoring());
-      }
-
-      if (('_layout' in hpainter.h) && (ilayout==null)) {
-         setGuiLayout(hpainter.h._layout);
-         hpainter.SetDisplay(hpainter.h._layout, drawDivId);
+             .prop('checked', hpainter.IsMonitoring())
+             .click(function() {
+                hpainter.EnableMonitoring(this.checked);
+                if (this.checked) hpainter.updateAll();
+             });
+      } else {
+         var fname = "";
+         hpainter.ForEachRootFile(function(item) { if (fname=="") fname = item._fullurl; });
+         $("#urlToLoad").val(fname);
       }
-
-      if (('_loadfile' in hpainter.h) && (filesarr.length==0)) {
-         filesarr = JSROOT.ParseAsArray(hpainter.h._loadfile);
-      }
-
-      if (('_drawitem' in hpainter.h) && (itemsarr.length==0)) {
-         itemsarr = JSROOT.ParseAsArray(hpainter.h._drawitem);
-         optionsarr = JSROOT.ParseAsArray(hpainter.h['_drawopt']);
-      }
-
-      OpenAllFiles();
-   }
-
-   if (h0!=null) hpainter.OpenOnline(h0, AfterOnlineOpened);
-            else OpenAllFiles();
-
-   setInterval(function() { if (hpainter.IsMonitoring()) hpainter.updateAll(); }, hpainter.MonitoringInterval());
+   });
 }
diff --git a/etc/http/scripts/JSRootPainter.jquery.js b/etc/http/scripts/JSRootPainter.jquery.js
new file mode 100644
index 0000000000000..7e4460f5ad19e
--- /dev/null
+++ b/etc/http/scripts/JSRootPainter.jquery.js
@@ -0,0 +1,860 @@
+/// @file JSRootPainter.jquery.js
+/// Part of JavaScript ROOT graphics, dependent from jQuery functionality
+
+(function() {
+
+   if (typeof JSROOT != 'object') {
+      var e1 = new Error('JSROOT is not defined');
+      e1.source = 'JSRootPainter.jquery.js';
+      throw e1;
+   }
+
+   if (typeof d3 != 'object') {
+      var e1 = new Error('This extension requires d3.v3.js');
+      e1.source = 'JSRootPainter.jquery.js';
+      throw e1;
+   }
+
+   if (typeof JSROOT.Painter != 'object') {
+      var e1 = new Error('JSROOT.Painter not defined');
+      e1.source = 'JSRootPainter.jquery.js';
+      throw e1;
+   }
+
+   if (typeof jQuery == 'undefined') {
+      var e1 = new Error('jQuery not defined ');
+      e1.source = 'JSRootPainter.jquery.js';
+      throw e1;
+   }
+   
+   JSROOT.Painter.createMenu = function(maincallback, menuname) {
+      if (!menuname) menuname = "root_ctx_menu";
+
+      var menu = { divid: menuname, code:"", cnt: 1, funcs : {} };
+
+      menu.add = function(name, arg, func) {
+         if (name.indexOf("header:")==0) {
+            this.code += "<li class='ui-widget-header'>"+name.substr(7)+"</li>";
+            return;
+         }
+
+         if (name=="endsub:") { this.code += "</ul></li>"; return; }
+         var close_tag = "</li>";
+         if (name.indexOf("sub:")==0) { name = name.substr(4); close_tag="<ul>"; }
+
+         if (typeof arg == 'function') { func = arg; arg = name; }
+
+         if ((arg==null) || (typeof arg != 'string')) arg = name;
+         this.code += "<li cnt='" + this.cnt + "' arg='" + arg + "'>" + name + close_tag;
+         if (typeof func == 'function') this.funcs[this.cnt] = func; // keep call-back function
+
+         this.cnt++;
+      }
+
+      menu.size = function() { return this.cnt-1; }
+
+      menu.addDrawMenu = function(menu_name, opts, call_back) {
+         if (opts==null) opts = new Array;
+         if (opts.length==0) opts.push("");
+
+         this.add((opts.length > 1) ? ("sub:" + menu_name) : menu_name, opts[0], call_back);
+         if (opts.length<2) return;
+
+         for (var i=0;i<opts.length;i++) {
+            var name = opts[i];
+            if (name=="") name = '&lt;dflt&gt;';
+            this.add(name, opts[i], call_back);
+         }
+         this.add("endsub:");
+      }
+
+      menu.remove = function() { $("#"+menuname).remove(); }
+
+      menu.show = function(event) {
+         menu.remove();
+
+         document.body.onclick = function(e) { menu.remove(); }
+
+         $(document.body).append('<ul id="' + menuname + '">' + this.code + '</ul>');
+
+         $("#" + menuname)
+            .css('left', event.clientX + window.pageXOffset)
+            .css('top', event.clientY + window.pageYOffset)
+            .attr('class', 'ctxmenu')
+            .menu({
+               items: "> :not(.ui-widget-header)",
+               select: function( event, ui ) {
+                  var arg = ui.item.attr('arg');
+                  var cnt = ui.item.attr('cnt');
+                  var func = cnt ? menu.funcs[cnt] : null;
+                  menu.remove();
+                  if (typeof func == 'function') func(arg);
+              }
+         });
+      }
+
+      JSROOT.CallBack(maincallback, menu);
+      
+      return menu;
+   }
+   
+   JSROOT.HierarchyPainter.prototype.isLastSibling = function(hitem) {
+      if (!hitem || !hitem._parent || !hitem._parent._childs) return false;
+      var chlds = hitem._parent._childs;
+      var indx = chlds.indexOf(hitem);
+      if (indx<0) return false;
+      while (++indx < chlds.length)
+         if (!('_hidden' in chlds[indx])) return false;
+      return true;
+   }
+   
+   JSROOT.HierarchyPainter.prototype.addItemHtml = function(hitem, parent) {
+      var isroot = (parent == null);
+      var has_childs = '_childs' in hitem;
+
+      if ('_hidden' in hitem) return;
+
+      var cando = this.CheckCanDo(hitem);
+
+      if (!isroot) hitem._parent = parent;
+
+      var can_click = false;
+
+      if (!has_childs || !cando.scan) {
+         if (cando.expand) {
+            can_click = true;
+            if (cando.img1.length == 0) {
+               cando.img1 = 'img_folder';
+               cando.img2 = 'img_folderopen';
+            }
+         } else
+         if (cando.display || cando.execute) {
+            can_click = true;
+         } else
+         if (cando.html.length > 0) can_click = true;
+      }
+
+      hitem['_img1'] = cando.img1;
+      hitem['_img2'] = cando.img2;
+      if (hitem['_img2']=="") hitem['_img2'] = hitem['_img1'];
+
+      // assign root icon
+      if (isroot && (hitem['_img1'].length==0))
+         hitem['_img1'] = hitem['_img2'] = "img_base";
+
+      // assign node icons
+
+      if (hitem['_img1'].length==0)
+         hitem['_img1'] = has_childs ? "img_folder" : "img_page";
+
+      if (hitem['_img2'].length==0)
+         hitem['_img2'] = has_childs ? "img_folderopen" : "img_page";
+
+      var itemname = this.itemFullName(hitem);
+
+      this['html'] += '<div item="' + itemname + '">';
+
+      // build indent
+      var sindent = "";
+      var prnt = isroot ? null : hitem._parent;
+      while ((prnt != null) && (prnt != this.h)) {
+         sindent = '<div class="' + (this.isLastSibling(prnt) ? "img_empty" : "img_line") + '"/>' + sindent;
+         prnt = prnt._parent;
+      }
+      this['html'] += sindent;
+
+      var icon_class = "", plusminus = false;
+
+      if (isroot) {
+         // for root node no extra code
+      } else
+      if (has_childs) {
+         icon_class = hitem._isopen ? "img_minus" : "img_plus";
+         plusminus = true;
+      } else {
+         icon_class = "img_join";
+      }
+
+      if (icon_class.length > 0) {
+         this['html'] += '<div class="' + icon_class;
+         if (this.isLastSibling(hitem)) this['html'] += "bottom";
+         if (plusminus) this['html'] += ' plus_minus" style="cursor:pointer';
+         this['html'] += '"/>';
+      }
+
+      // make node icons
+
+      var icon_name = hitem._isopen ? hitem._img2 : hitem._img1;
+
+      if (icon_name.indexOf("img_")==0)
+         this['html'] += '<div class="' + icon_name + '"/>';
+      else
+         this['html'] += '<img src="' + icon_name + '" alt="" style="vertical-align:top"/>';
+
+      this['html'] += '<a';
+      if (can_click || has_childs) this['html'] +=' class="h_item"';
+
+      var element_name = hitem._name;
+
+      if ('_realname' in hitem)
+         element_name = hitem._realname;
+
+      var element_title = "";
+      if ('_title' in hitem) element_title = hitem._title;
+
+      if ('_fullname' in hitem)
+         element_title += "  fullname: " + hitem['_fullname'];
+
+      if (element_title.length == 0) element_title = element_name;
+
+      this['html'] += ' title="' + element_title + '"';
+      this['html'] += '>' + element_name + '</a>';
+
+      if (has_childs && (isroot || hitem._isopen)) {
+         this['html'] += '<div class="h_childs">';
+         for (var i in hitem._childs)
+            this.addItemHtml(hitem._childs[i], hitem);
+         this['html'] += '</div>';
+      }
+
+      this['html'] += '</div>';
+   }
+   
+   JSROOT.HierarchyPainter.prototype.RefreshHtml = function(callback) {
+      if (this.frameid == null) return JSROOT.CallBack(callback);
+      var elem = $("#" + this.frameid);
+      if ((this.h == null) || (elem.length == 0)) { 
+         elem.html("");
+         return JSROOT.CallBack(callback);
+      }
+
+      var factcmds = this.FindFastCommands();
+
+      this['html'] = "";
+      if (factcmds) {
+         for (var n in factcmds)
+            this['html'] += "<button class='fast_command'> </button>";
+      }
+      this['html'] += "<p>";
+      this['html'] += "<a href='#open_all'>open all</a>";
+      this['html'] += "| <a href='#close_all'>close all</a>";
+      if ('_online' in this.h)
+         this['html'] += "| <a href='#reload'>reload</a>";
+      else
+         this['html'] += "<a/>";
+
+      if ('disp_kind' in this)
+         this['html'] += "| <a href='#clear'>clear</a>";
+      else
+         this['html'] += "<a/>";
+
+      this['html'] += "</p>";
+
+      this['html'] += '<div class="h_tree">';
+      this.addItemHtml(this.h, null);
+      this['html'] += '</div>';
+
+      var h = this;
+
+      var items = elem.html(this['html'])
+          .find(".h_item")
+          .click(function() { h.tree_click($(this)); });
+
+      if ('disp_kind' in h) {
+         if (JSROOT.gStyle.DragAndDrop)
+            items.draggable({ revert: "invalid", appendTo: "body", helper: "clone" });
+
+         if (JSROOT.gStyle.ContextMenu)
+            items.on('contextmenu', function(e) { h.tree_contextmenu($(this), e); });
+      }
+
+      elem.find(".plus_minus").click(function() { h.tree_click($(this),true); });
+
+      elem.find("a").first().click(function() { h.toggle(true); return false; })
+                    .next().click(function() { h.toggle(false); return false; })
+                    .next().click(function() { h.reload(); return false; })
+                    .next().click(function() { h.clear(false); return false; });
+
+      if (factcmds)
+         elem.find('.fast_command').each(function(index) {
+            if ('_icon' in factcmds[index])
+               $(this).text("").append('<img src="' + factcmds[index]['_icon'] + '"/>');
+            $(this).button()
+                   .attr("item", h.itemFullName(factcmds[index]))
+                   .attr("title", factcmds[index]._title)
+                   .click(function() { h.ExecuteCommand($(this).attr("item"), $(this)); });
+         });
+      
+      JSROOT.CallBack(callback);
+   }
+   
+   JSROOT.HierarchyPainter.prototype.UpdateTreeNode = function(node, hitem) {
+      var has_childs = '_childs' in hitem;
+
+      var newname = hitem._isopen ? hitem._img2 : hitem._img1;
+      var oldname = hitem._isopen ? hitem._img1 : hitem._img2;
+
+      var img = node.find("a").first().prev();
+
+      if (newname.indexOf("img_")<0) {
+         img.attr("src", newname);
+      } else {
+         if (newname!=oldname)
+            img.switchClass(oldname, newname);
+      }
+
+      img = img.prev();
+
+      var h = this;
+
+      var new_class = hitem._isopen ? "img_minus" : "img_plus";
+      if (this.isLastSibling(hitem)) new_class += "bottom";
+
+      if (img.hasClass("plus_minus")) {
+         img.attr('class', new_class + " plus_minus");
+      } else
+      if (has_childs) {
+         img.attr('class', new_class + " plus_minus");
+         img.css('cursor', 'pointer');
+         img.click(function() { h.tree_click($(this), true); });
+      }
+
+      var childs = node.children().last();
+      if (childs.hasClass("h_childs")) childs.remove();
+
+      var display_childs = has_childs && hitem._isopen;
+      if (!display_childs) return;
+
+      this['html'] = '<div class="h_childs">';
+      for (var i in hitem._childs)
+         this.addItemHtml(hitem._childs[i], hitem);
+      this['html'] += '</div>';
+      node.append(this['html']);
+      childs = node.children().last();
+
+      var items = childs.find(".h_item")
+                   .click(function() { h.tree_click($(this)); });
+
+      if ('disp_kind' in h) {
+         if (JSROOT.gStyle.DragAndDrop)
+            items.draggable({ revert: "invalid", appendTo: "body", helper: "clone" });
+
+         if (JSROOT.gStyle.ContextMenu)
+            items.on('contextmenu', function(e) { h.tree_contextmenu($(this), e); })
+      }
+
+      childs.find(".plus_minus").click(function() { h.tree_click($(this), true); });
+   }
+
+   JSROOT.HierarchyPainter.prototype.tree_click = function(node, plusminus) {
+      var itemname = node.parent().attr('item');
+
+      if (itemname==null) return;
+
+      var hitem = this.Find(itemname);
+      if (hitem==null) return;
+
+      if (!plusminus) {
+         var cando = this.CheckCanDo(hitem);
+
+         if (cando.open && (cando.html.length>0))
+            return window.open(cando.html);
+
+         if (cando.expand && (hitem['_childs'] == null))
+            return this.expand(itemname, hitem, node.parent());
+
+         if (cando.display)
+            return this.display(itemname);
+
+         if (cando.execute)
+            return this.ExecuteCommand(itemname, node);
+
+         if (!('_childs' in hitem) || (hitem === this.h)) return;
+      }
+
+      if (hitem._isopen)
+         delete hitem._isopen;
+      else
+         hitem._isopen = true;
+
+      this.UpdateTreeNode(node.parent(), hitem);
+   }
+   
+   JSROOT.HierarchyPainter.prototype.tree_contextmenu = function(node, event) {
+      event.preventDefault();
+
+      var itemname = node.parent().attr('item');
+
+      var hitem = this.Find(itemname);
+      if (hitem==null) return;
+      
+      var cando = this.CheckCanDo(hitem);
+
+      // if (!cando.display && !cando.ctxt && (itemname!="")) return;
+
+      var painter = this;
+
+      var onlineprop = painter.GetOnlineProp(itemname);
+      var fileprop = painter.GetFileProp(itemname);
+      
+      function qualifyURL(url) {
+         function escapeHTML(s) {
+            return s.split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
+         }
+         var el = document.createElement('div');
+         el.innerHTML = '<a href="' + escapeHTML(url) + '">x</a>';
+         return el.firstChild.href;
+      }
+      
+      JSROOT.Painter.createMenu(function(menu) {
+
+         if (itemname == "") {
+            var addr = "", cnt = 0;
+            function separ() { return cnt++ > 0 ? "&" : "?"; }
+
+            var files = [];
+            painter.ForEachRootFile(function(item) { files.push(item._file.fFullURL); });
+
+            if (painter.GetTopOnlineItem()==null)
+               addr = JSROOT.source_dir + "index.htm";
+
+            if (painter.IsMonitoring())
+               addr += separ() + "monitoring=" + painter.MonitoringInterval();
+
+            if (files.length==1)
+               addr += separ() + "file=" + files[0];
+            else
+               if (files.length>1)
+                  addr += separ() + "files=" + JSON.stringify(files);
+
+            if (painter['disp_kind'])
+               addr += separ() + "layout=" + painter['disp_kind'].replace(/ /g, "");
+
+            var items = [];
+
+            if (painter['disp'] != null)
+               painter['disp'].ForEachPainter(function(p) {
+                  if (p.GetItemName()!=null)
+                     items.push(p.GetItemName());
+               });
+
+            if (items.length == 1) {
+               addr += separ() + "item=" + items[0];
+            } else if (items.length > 1) {
+               addr += separ() + "items=" + JSON.stringify(items);
+            }
+
+            menu.add("Direct link", function() { window.open(addr); });
+            menu.add("Only items", function() { window.open(addr + "&nobrowser"); });
+         } else
+         if (onlineprop != null) {
+            painter.FillOnlineMenu(menu, onlineprop, itemname);
+         } else
+         if (fileprop != null) {
+            var opts = JSROOT.getDrawOptions(cando.typename, 'nosame');
+
+            menu.addDrawMenu("Draw", opts, function(arg) { painter.display(itemname, arg); });
+
+            var filepath = qualifyURL(fileprop.fileurl);
+            if (filepath.indexOf(JSROOT.source_dir) == 0)
+               filepath = filepath.slice(JSROOT.source_dir.length);
+
+            menu.addDrawMenu("Draw in new window", opts, function(arg) {
+               window.open(JSROOT.source_dir + "index.htm?nobrowser&file=" + filepath + "&item=" + fileprop.itemname+"&opt="+arg);
+            });
+         }
+
+         if (menu.size()>0) {
+            menu['tree_node'] = node;
+            menu.add("Close");
+            menu.show(event);
+         }
+      
+      }); // end menu creation
+
+      return false;
+   }
+   
+   JSROOT.HierarchyPainter.prototype.expand = function(itemname, item0, node) {
+      var painter = this;
+
+      if (node==null)
+         node = $("#" + this.frameid).find("[item='" + itemname + "']");
+
+      if (node.length==0)
+         return console.log("Did not found node with item = " + itemname);
+
+      if (item0==null) item0 = this.Find(itemname);
+      if (item0==null) return;
+      item0['_doing_expand'] = true;
+
+      this.get(itemname, function(item, obj) {
+         delete item0['_doing_expand'];
+         if ((item == null) || (obj == null)) return;
+
+         var curr = item;
+         while (curr != null) {
+            if (('_expand' in curr) && (typeof (curr['_expand']) == 'function')) {
+                if (curr['_expand'](item, obj)) {
+                   var itemname = painter.itemFullName(item);
+                   node.attr('item', itemname);
+                   node.find("a").text(item._name);
+                   item._isopen = true;
+                   painter.UpdateTreeNode(node, item);
+                }
+                return;
+            }
+            curr = ('_parent' in curr) ? curr['_parent'] : null;
+         }
+      });
+   }
+   
+   JSROOT.HierarchyPainter.prototype.CreateDisplay = function(callback) {
+      if ('disp' in this) {
+         if (this['disp'].NumDraw() > 0) return JSROOT.CallBack(callback, this['disp']);
+         this['disp'].Reset();
+         delete this['disp'];
+      }
+      
+      // check that we can found frame where drawing should be done
+      if (document.getElementById(this['disp_frameid']) == null) 
+         return JSROOT.CallBack(callback, null);
+
+      if (this['disp_kind'] == "tabs")
+         this['disp'] = new JSROOT.TabsDisplay(this['disp_frameid']);
+      else
+      if (this['disp_kind'].search("grid") == 0)
+         this['disp'] = new JSROOT.GridDisplay(this['disp_frameid'], this['disp_kind']);
+      else
+      if (this['disp_kind'] == "simple")
+         this['disp'] = new JSROOT.SimpleDisplay(this['disp_frameid']);
+      else
+         this['disp'] = new JSROOT.CollapsibleDisplay(this['disp_frameid']);
+
+      JSROOT.CallBack(callback, this['disp']);
+   }
+
+   JSROOT.HierarchyPainter.prototype.enable_dropping = function(frame, itemname) {
+      var h = this;
+      if (JSROOT.gStyle.DragAndDrop)
+         $(frame).droppable({
+            hoverClass : "ui-state-active",
+            accept: function(ui) {
+               var dropname = ui.parent().attr('item');
+               if ((dropname == itemname) || (dropname==null)) return false;
+
+               var ditem = h.Find(dropname);
+               if ((ditem==null) || (!('_kind' in ditem))) return false;
+
+               return ditem._kind.indexOf("ROOT.")==0;
+            },
+            drop: function(event, ui) {
+               var dropname = ui.draggable.parent().attr('item');
+               if (dropname==null) return false;
+               return h.dropitem(dropname, $(this).attr("id"));
+            }
+         });
+   }
+   
+   // ==================================================
+
+   JSROOT.CollapsibleDisplay = function(frameid) {
+      JSROOT.MDIDisplay.call(this, frameid);
+      this.cnt = 0; // use to count newly created frames
+   }
+
+   JSROOT.CollapsibleDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
+
+   JSROOT.CollapsibleDisplay.prototype.ForEachFrame = function(userfunc,  only_visible) {
+      var topid = this.frameid + '_collapsible';
+
+      if (document.getElementById(topid) == null) return;
+
+      if (typeof userfunc != 'function') return;
+
+      $('#' + topid + ' .collapsible_draw').each(function() {
+
+         // check if only visible specified
+         if (only_visible && $(this).is(":hidden")) return;
+
+         userfunc($(this).get(0));
+      });
+   }
+
+   JSROOT.CollapsibleDisplay.prototype.ActivateFrame = function(frame) {
+      if ($(frame).is(":hidden")) {
+         $(frame).prev().toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
+                 .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
+                 .next().toggleClass("ui-accordion-content-active").slideDown(0);
+      }
+      $(frame).prev()[0].scrollIntoView();
+   }
+
+   JSROOT.CollapsibleDisplay.prototype.CreateFrame = function(title) {
+
+      var topid = this.frameid + '_collapsible';
+
+      if (document.getElementById(topid) == null)
+         $("#right-div").append('<div id="'+ topid  + '" class="ui-accordion ui-accordion-icons ui-widget ui-helper-reset" style="overflow:auto; overflow-y:scroll; height:100%; padding-left: 2px; padding-right: 2px"></div>');
+
+      var hid = topid + "_sub" + this.cnt++;
+      var uid = hid + "h";
+
+      var entryInfo = "<h5 id=\"" + uid + "\"><a> " + title + "</a>&nbsp; </h5>\n";
+      entryInfo += "<div class='collapsible_draw' id='" + hid + "'></div>\n";
+      $("#" + topid).append(entryInfo);
+
+      $('#' + uid)
+            .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
+            .hover(function() { $(this).toggleClass("ui-state-hover"); })
+            .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
+            .append('<button type="button" class="closeButton" title="close canvas" '+
+                    'onclick="javascript: $(this).parent().next().andSelf().remove();">'+
+                    '<img class="img_remove" src="" alt=""/></button>')
+            .click( function() {
+                     $(this).toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
+                           .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s")
+                           .end().next().toggleClass("ui-accordion-content-active").slideToggle(0);
+                     return false;
+                  })
+            .next()
+            .addClass("ui-accordion-content  ui-helper-reset ui-widget-content ui-corner-bottom")
+            .hide();
+
+      $('#' + uid)
+            .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
+            .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end().next()
+            .toggleClass("ui-accordion-content-active").slideToggle(0);
+
+      $("#" + hid).prop('title', title);
+
+      return $("#" + hid).get(0);
+   }
+
+   // ================================================
+
+   JSROOT.TabsDisplay = function(frameid) {
+      JSROOT.MDIDisplay.call(this, frameid);
+      this.cnt = 0;
+   }
+
+   JSROOT.TabsDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
+
+   JSROOT.TabsDisplay.prototype.ForEachFrame = function(userfunc, only_visible) {
+      var topid = this.frameid + '_tabs';
+
+      if (document.getElementById(topid) == null) return;
+
+      if (typeof userfunc != 'function') return;
+
+      var cnt = -1;
+      var active = $('#' + topid).tabs("option", "active");
+
+      $('#' + topid + ' .tabs_draw').each(function() {
+         // check if only_visible specified
+         if (only_visible && (cnt++ != active)) return;
+
+         userfunc($(this).get(0));
+      });
+   }
+
+   JSROOT.TabsDisplay.prototype.ActivateFrame = function(frame) {
+      var cnt = 0, id = -1;
+      this.ForEachFrame(function(fr) {
+         if ($(fr).attr('id') == $(frame).attr('id')) id = cnt;
+         cnt++;
+      });
+
+      $('#' + this.frameid + "_tabs").tabs("option", "active", id);
+   }
+
+   JSROOT.TabsDisplay.prototype.CreateFrame = function(title) {
+      var topid = this.frameid + '_tabs';
+
+      var hid = topid + "_sub" + this.cnt++;
+
+      var li = '<li><a href="#' + hid + '">' + title
+            + '</a><span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>';
+      var cont = '<div class="tabs_draw" id="' + hid + '"></div>';
+
+      if (document.getElementById(topid) == null) {
+         $("#" + this.frameid).append('<div id="' + topid + '">' + ' <ul>' + li + ' </ul>' + cont + '</div>');
+
+         var tabs = $("#" + topid)
+                       .css('overflow','hidden')
+                       .tabs({ heightStyle : "fill" });
+
+         tabs.delegate("span.ui-icon-close", "click", function() {
+            var panelId = $(this).closest("li").remove().attr("aria-controls");
+            $("#" + panelId).remove();
+            tabs.tabs("refresh");
+         });
+      } else {
+
+         // var tabs = $("#tabs").tabs();
+
+         $("#" + topid).find(".ui-tabs-nav").append(li);
+         $("#" + topid).append(cont);
+         $("#" + topid).tabs("refresh");
+         $("#" + topid).tabs("option", "active", -1);
+      }
+      $('#' + hid).empty();
+      $('#' + hid).prop('title', title);
+      return $('#' + hid).get(0);
+   }
+   
+   // ========== performs tree drawing on server ==================
+
+   JSROOT.TTreePlayer = function(itemname) {
+      JSROOT.TBasePainter.call(this);
+      this.SetItemName(itemname);
+      this.hpainter = null;
+      return this;
+   }
+
+   JSROOT.TTreePlayer.prototype = Object.create( JSROOT.TBasePainter.prototype );
+
+   JSROOT.TTreePlayer.prototype.Show = function(divid) {
+      this.drawid = divid + "_draw";
+
+      $("#" + divid)
+        .html("<div class='treedraw_buttons' style='padding-left:0.5em'>" +
+            "<button class='treedraw_exe'>Draw</button>" +
+            " Expr:<input class='treedraw_varexp' style='width:12em'></input> " +
+            "<button class='treedraw_more'>More</button>" +
+            "</div>" +
+            "<div id='" + this.drawid + "' style='width:100%'></div>");
+
+      var player = this;
+
+      $("#" + divid).find('.treedraw_exe').click(function() { player.PerformDraw(); });
+      $("#" + divid).find('.treedraw_varexp')
+           .val("px:py")
+           .keyup(function(e){
+               if(e.keyCode == 13) player.PerformDraw();
+            });
+
+      $("#" + divid).find('.treedraw_more').click(function() {
+         $(this).remove();
+         $("#" + divid).find(".treedraw_buttons")
+         .append(" Cut:<input class='treedraw_cut' style='width:8em'></input>"+
+                 " Opt:<input class='treedraw_opt' style='width:5em'></input>"+
+                 " Num:<input class='treedraw_number' style='width:7em'></input>" +
+                 " First:<input class='treedraw_first' style='width:7em'></input>");
+
+         $("#" + divid +" .treedraw_opt").val("");
+         $("#" + divid +" .treedraw_number").val("").spinner({ numberFormat: "n", min: 0, page: 1000});
+         $("#" + divid +" .treedraw_first").val("").spinner({ numberFormat: "n", min: 0, page: 1000});
+      });
+
+      this.CheckResize();
+
+      this.SetDivId(divid);
+   }
+
+   JSROOT.TTreePlayer.prototype.PerformDraw = function() {
+
+      var frame = $("#" + this.divid);
+
+      var url = this.GetItemName() + '/exe.json.gz?compact=3&method=Draw';
+      var expr = frame.find('.treedraw_varexp').val();
+      var hname = "h_tree_draw";
+
+      var pos = expr.indexOf(">>");
+      if (pos<0) {
+         expr += ">>" + hname;
+      } else {
+         hname = expr.substr(pos+2);
+         if (hname[0]=='+') hname = hname.substr(1);
+         var pos2 = hname.indexOf("(");
+         if (pos2>0) hname = hname.substr(0, pos2);
+      }
+
+      if (frame.find('.treedraw_more').length==0) {
+         var cut = frame.find('.treedraw_cut').val();
+         var option = frame.find('.treedraw_opt').val();
+         var nentries = frame.find('.treedraw_number').val();
+         var firstentry = frame.find('.treedraw_first').val();
+
+         url += '&prototype="const char*,const char*,Option_t*,Long64_t,Long64_t"&varexp="' + expr + '"&selection="' + cut + '"';
+
+         // if any of optional arguments specified, specify all of them
+         if ((option!="") || (nentries!="") || (firstentry!="")) {
+            if (nentries=="") nentries = "1000000000";
+            if (firstentry=="") firstentry = "0";
+            url += '&option="' + option + '"&nentries=' + nentries + '&firstentry=' + firstentry;
+         }
+      } else {
+         url += '&prototype="Option_t*"&opt="' + expr + '"';
+      }
+      url += '&_ret_object_=' + hname;
+
+      var player = this;
+
+      var req = JSROOT.NewHttpRequest(url, 'object', function(res) {
+         if (res==0) return;
+         $("#"+player.drawid).empty();
+         player.hpainter = JSROOT.draw(player.drawid, res)
+      });
+      req.send();
+   }
+
+   JSROOT.TTreePlayer.prototype.CheckResize = function(force) {
+      $("#" + this.drawid).width($("#" + this.divid).width());
+      var h = $("#" + this.divid).height();
+      var h0 = $("#" + this.divid +" .treedraw_buttons").height();
+      if (h>h0+30) $("#" + this.drawid).height(h - 1 - h0);
+
+      if (this.hpainter) {
+         this.hpainter.CheckResize(force);
+      }
+   }
+
+   JSROOT.drawTreePlayer = function(hpainter, itemname) {
+      var mdi = hpainter.GetDisplay();
+      if (mdi == null) return null;
+
+      var frame = mdi.FindFrame(itemname, true);
+      if (frame==null) return null;
+
+      var divid = d3.select(frame).attr('id');
+
+      var player = new JSROOT.TTreePlayer(itemname);
+      player.Show(divid);
+      return player;
+   }
+
+   // =======================================================================
+   
+   JSROOT.ConfigureVSeparator = function(handle, leftdiv, separdiv, rightdiv) {
+      if (!leftdiv) leftdiv = "left-div";
+      if (!separdiv) separdiv = "separator-div";
+      if (!rightdiv) rightdiv = "right-div";
+
+      function adjustSize(left, firsttime) {
+         var diff = $("#"+leftdiv).outerWidth() - $("#"+leftdiv).width();
+         var w = JSROOT.touches ? 10 : 4;
+
+         $("#"+separdiv).css('left', left.toString() + "px").width(w);
+         $("#"+leftdiv).width(left-diff-1);
+         $("#"+rightdiv).css('left',(left+w).toString() + "px");
+         if (firsttime || (handle==null)) return;
+
+         if (typeof handle == 'function') handle(); else
+         if ((typeof handle == 'object') && (typeof handle['CheckResize'] == 'function')) handle.CheckResize();
+      }
+
+      $("#"+separdiv).draggable({
+         axis: "x" , zIndex: 100, cursor: "ew-resize",
+         helper : function() { return $("#"+separdiv).clone().css('background-color','grey'); },
+         stop: function(event,ui) { event.stopPropagation(); adjustSize(ui.position.left, false); }
+      });
+
+      var w0 = Math.round($(window).width() * 0.2);
+      if (w0<300) w0 = Math.min(300, Math.round($(window).width() * 0.5));
+
+      adjustSize(w0, true);
+   }
+
+   
+})();
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index 23668086d728d..dc73bd0c4ff55 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -28,7 +28,10 @@
    // one could specify supported options list, separated with ';'
    // One could specify several draw functions for different draw options
    JSROOT.addDrawFunc = function(_name, _func, _opt) {
-      JSROOT.fDrawFunc.push({ name:_name, func:_func, opt:_opt });
+      if ((arguments.length == 1) && (typeof arguments[0] == 'object'))
+         JSROOT.fDrawFunc.push(arguments[0]);
+      else
+         JSROOT.fDrawFunc.push({ name:_name, func:_func, opt:_opt });
    }
 
    JSROOT.gStyle = {
@@ -55,6 +58,20 @@
     */
    JSROOT.Painter = {};
 
+
+   JSROOT.Painter.createMenu = function(maincallback, menuname) {
+      // dummy functions, forward call to the jquery function
+      JSROOT.AssertPrerequisites('jq2d', function() {
+         JSROOT.Painter.createMenu(maincallback, menuname);
+      });
+   }
+
+   JSROOT.Painter.closeMenu = function(menuname) {
+      if (!menuname) menuname = 'root_ctx_menu';
+      var x = document.getElementById(menuname);
+      if (x) x.parentNode.removeChild(x);
+   }
+
    JSROOT.Painter.readStyleFromURL = function(url) {
       var optimize = JSROOT.GetUrlOption("optimize", url);
       if (optimize=="") JSROOT.gStyle.OptimizeDraw = 2; else
@@ -88,75 +105,6 @@
       }
    }
 
-   JSROOT.createMenu = function(menuname) {
-      if (!menuname) menuname = "root_ctx_menu";
-
-      var menu = { divid: menuname, code:"", cnt: 1, funcs : {} };
-
-      menu.add = function(name, arg, func) {
-         if (name.indexOf("header:")==0) {
-            this.code += "<li class='ui-widget-header'>"+name.substr(7)+"</li>";
-            return;
-         }
-
-         if (name=="endsub:") { this.code += "</ul></li>"; return; }
-         var close_tag = "</li>";
-         if (name.indexOf("sub:")==0) { name = name.substr(4); close_tag="<ul>"; }
-
-         if (typeof arg == 'function') { func = arg; arg = name; }
-
-         if ((arg==null) || (typeof arg != 'string')) arg = name;
-         this.code += "<li cnt='" + this.cnt + "' arg='" + arg + "'>" + name + close_tag;
-         if (typeof func == 'function') this.funcs[this.cnt] = func; // keep call-back function
-
-         this.cnt++;
-      }
-
-      menu.size = function() { return this.cnt-1; }
-
-      menu.addDrawMenu = function(menu_name, opts, call_back) {
-         if (opts==null) opts = new Array;
-         if (opts.length==0) opts.push("");
-
-         this.add((opts.length > 1) ? ("sub:" + menu_name) : menu_name, opts[0], call_back);
-         if (opts.length<2) return;
-
-         for (var i=0;i<opts.length;i++) {
-            var name = opts[i];
-            if (name=="") name = '&lt;dflt&gt;';
-            this.add(name, opts[i], call_back);
-         }
-         this.add("endsub:");
-      }
-
-      menu.remove = function() { $("#"+menuname).remove(); }
-
-      menu.show = function(event) {
-         menu.remove();
-
-         document.body.onclick = function(e) { menu.remove(); }
-
-         $(document.body).append('<ul id="' + menuname + '">' + this.code + '</ul>');
-
-         $("#" + menuname)
-            .css('left', event.clientX + window.pageXOffset)
-            .css('top', event.clientY + window.pageYOffset)
-            .attr('class', 'ctxmenu')
-            .menu({
-               items: "> :not(.ui-widget-header)",
-               select: function( event, ui ) {
-                  var arg = ui.item.attr('arg');
-                  var cnt = ui.item.attr('cnt');
-                  var func = cnt ? menu.funcs[cnt] : null;
-                  menu.remove();
-                  if (typeof func == 'function') func(arg);
-              }
-         });
-      }
-
-      return menu;
-   }
-
    JSROOT.Painter.Coord = {
       kCARTESIAN : 1,
       kPOLAR : 2,
@@ -893,7 +841,9 @@
 
       this['divid'] = divid;
 
-      $("#" + divid).children().eq(0).prop('painter', this);
+      var main = d3.select("#" + divid);
+      if (main.node() && main.node().firstChild)
+         main.node().firstChild['painter'] = this;
    }
 
    JSROOT.TBasePainter.prototype.SetItemName = function(name) {
@@ -924,7 +874,7 @@
       // no canvas - no resize
       var can = this.svg_canvas();
 
-      var pad_painter = can ? can['pad_painter'] : null;
+      var pad_painter = can.empty() ? null : can.property('pad_painter');
 
       if (pad_painter) pad_painter.CheckCanvasResize();
    }
@@ -948,9 +898,9 @@
       if (take_pad) {
          if (layer==null) layer = ".text_layer"
          if (!this.draw_g)
-            this.draw_g = this.svg_pad(true).select(layer).append("svg:g");
+            this.draw_g = this.svg_pad().select(layer).append("svg:g");
       } else {
-         var frame = this.svg_frame(true);
+         var frame = this.svg_frame();
 
          var w = frame.attr("width");
          var h = frame.attr("height");
@@ -970,36 +920,34 @@
    }
 
    /** This is main graphical SVG element, where all Canvas drawing are performed */
-   JSROOT.TObjectPainter.prototype.svg_canvas = function(asselect) {
-      var res = d3.select("#" + this.divid + " .root_canvas");
-      return asselect ? res : res.node();
+   JSROOT.TObjectPainter.prototype.svg_canvas = function() {
+      return d3.select("#" + this.divid + " .root_canvas");
    }
 
    /** This is SVG element, correspondent to current pad */
-   JSROOT.TObjectPainter.prototype.svg_pad = function(asselect) {
-      var c = this.svg_canvas(true);
-      if (this.pad_name != '')
+   JSROOT.TObjectPainter.prototype.svg_pad = function() {
+      var c = this.svg_canvas();
+      if ((this.pad_name != '') && !c.empty())
          c = c.select("[pad=" + this.pad_name + ']');
-      return asselect ? c : c.node();
+      return c;
    }
 
    JSROOT.TObjectPainter.prototype.root_pad = function() {
       var p = this.svg_pad();
-      var pad_painter = p ? p['pad_painter'] : null;
+      var pad_painter = p.empty() ? null : p.property('pad_painter');
       return pad_painter ? pad_painter.pad : null;
    }
 
    /** This is SVG element with current frame */
-   JSROOT.TObjectPainter.prototype.svg_frame = function(asselect) {
-      var f = this.svg_pad(true).select(".root_frame");
-      return asselect ? f : f.node();
+   JSROOT.TObjectPainter.prototype.svg_frame = function() {
+      return this.svg_pad().select(".root_frame");
    }
 
    /** Returns main pad painter - normally TH1/TH2 painter, which draws all axis */
    JSROOT.TObjectPainter.prototype.main_painter = function() {
       if (!this.main) {
          var svg_p = this.svg_pad();
-         if (svg_p) this.main = svg_p['mainpainter'];
+         if (!svg_p.empty()) this.main = svg_p.property('mainpainter');
       }
       return this.main;
    }
@@ -1025,39 +973,43 @@
       // SVG element where canvas is drawn
       var svg_c = this.svg_canvas();
 
-      if ((svg_c==null) && (is_main>0)) {
+      if (svg_c.empty() && (is_main>0)) {
          JSROOT.Painter.drawCanvas(divid, null);
          svg_c = this.svg_canvas();
          this['create_canvas'] = true;
       }
 
-      if (svg_c == null) {
+      if (svg_c.empty()) {
          if ((is_main < 0) || (this.obj_typename=="TCanvas")) return;
 
          console.log("Special case for " + this.obj_typename + " assign painter to first DOM element");
-         $("#" + divid).children().eq(0).prop('painter', this);
+         var main = d3.select("#" + divid);
+         if (main.node() && main.node().firstChild)
+            main.node().firstChild['painter'] = this;
          return;
       }
 
       // SVG element where current pad is drawn (can be canvas itself)
-      this.pad_name = svg_c['current_pad'];
+      this.pad_name = svg_c.property('current_pad');
 
       if (is_main < 0) return;
 
       // create TFrame element if not exists when
-      if ((is_main > 0) && (this.svg_frame()==null)) {
+      if ((is_main > 0) && this.svg_frame().empty()) {
          JSROOT.Painter.drawFrame(divid, null);
-         if (this.svg_frame()==null) return alert("Fail to draw dummy TFrame");
+         if (this.svg_frame().empty()) return alert("Fail to draw dummy TFrame");
          this['create_canvas'] = true;
       }
 
       var svg_p = this.svg_pad();
-      if (svg_p['pad_painter'] != this)
-         svg_p['pad_painter'].painters.push(this);
+      if (svg_p.empty()) return;
+
+      if (svg_p.property('pad_painter') != this)
+         svg_p.property('pad_painter').painters.push(this);
 
-      if ((is_main > 0) && (svg_p['mainpainter']==null))
+      if ((is_main > 0) && (svg_p.property('mainpainter')==null))
          // when this is first main painter in the pad
-         svg_p['mainpainter'] = this;
+         svg_p.property('mainpainter', this);
    }
 
    JSROOT.TObjectPainter.prototype.SetForeignObjectPosition = function(fo, x, y) {
@@ -1068,7 +1020,7 @@
 
       if (JSROOT.browser.isWebKit) {
          // force canvas redraw when foreign object used - it is not correctly scaled
-         this.svg_canvas(true).property('redraw_by_resize', true);
+         this.svg_canvas().property('redraw_by_resize', true);
          while (sel && sel.attr('class') != 'root_canvas') {
             if ((sel.attr('class') == 'root_frame') || (sel.attr('class') == 'root_pad')) {
               x += parseInt(sel.attr("x"));
@@ -1105,7 +1057,7 @@
       fill.color = JSROOT.Painter.root_colors[color];
       if (typeof fill.color != 'string') fill.color = "none";
 
-      var svg = this.svg_canvas(true);
+      var svg = this.svg_canvas();
 
       if ((pattern < 3000) || (pattern>3025) || svg.empty()) return fill;
 
@@ -1197,20 +1149,21 @@
    JSROOT.TObjectPainter.prototype.ForEachPainter = function(userfunc) {
       // Iterate over all known painters
 
-      var painter = $("#" + this.divid).children().eq(0).prop('painter');
+      var main = d3.select("#" + this.divid);
+      var painter = (main.node() && main.node().firstChild) ? main.node().firstChild['painter'] : null;
       if (painter!=null) { userfunc(painter); return; }
 
       var svg_c = this.svg_canvas();
-      if (svg_c==null) return;
+      if (svg_c.empty()) return;
 
-      userfunc(svg_c['pad_painter']);
-      var painters = svg_c['pad_painter'].painters;
+      userfunc(svg_c.property('pad_painter'));
+      var painters = svg_c.property('pad_painter').painters;
       for (var k in painters) userfunc(painters[k]);
    }
 
    JSROOT.TObjectPainter.prototype.Cleanup = function() {
       // generic method to cleanup painters
-      $("#" + this.divid).empty();
+      d3.select("#" + this.divid).html("");
    }
 
    JSROOT.TObjectPainter.prototype.RedrawPad = function() {
@@ -1219,7 +1172,7 @@
 
       var pad = this.svg_pad();
 
-      var pad_painter = pad ? pad['pad_painter'] : null;
+      var pad_painter = pad.empty() ? null : pad.property('pad_painter');
 
       if (pad_painter) pad_painter.Redraw();
    }
@@ -1255,11 +1208,11 @@
             d3.event.sourceEvent.preventDefault();
 
             acc_x = 0; acc_y = 0;
-            pad_w = Number(pthis.svg_pad(true).attr("width")) - rect_width();
-            pad_h = Number(pthis.svg_pad(true).attr("height")) - rect_height();
+            pad_w = Number(pthis.svg_pad().attr("width")) - rect_width();
+            pad_h = Number(pthis.svg_pad().attr("height")) - rect_height();
 
             pthis[drag_rect_name] =
-               pthis.svg_pad(true)
+               pthis.svg_pad()
                  .append("rect")
                  .attr("class", "zoom")
                  .attr("id", drag_rect_name)
@@ -1316,10 +1269,10 @@
            d3.event.sourceEvent.preventDefault();
 
            acc_x = 0; acc_y = 0;
-           pad_w = Number(pthis.svg_pad(true).attr("width")) - Number(draw_g.attr("x"));
-           pad_h = Number(pthis.svg_pad(true).attr("height")) - Number(draw_g.attr("y"));
+           pad_w = Number(pthis.svg_pad().attr("width")) - Number(draw_g.attr("x"));
+           pad_h = Number(pthis.svg_pad().attr("height")) - Number(draw_g.attr("y"));
            pthis[drag_rect_name] =
-              pthis.svg_pad(true)
+              pthis.svg_pad()
                 .append("rect")
                 .attr("class", "zoom")
                 .attr("id", drag_rect_name)
@@ -1383,7 +1336,8 @@
       // can be used to find painter for some special objects, registered as
       // histogram functions
 
-      var painters = this.svg_pad() ? this.svg_pad().pad_painter.painters : null;
+      var ppp = this.svg_pad();
+      var painters = ppp.empty() ? null : ppp.property('pad_painter').painters;
       if (painters == null) return null;
 
       for (var n in painters) {
@@ -1418,7 +1372,7 @@
    }
 
    JSROOT.TFramePainter.prototype.Shrink = function(shrink_left, shrink_right) {
-      var ndc = this.svg_frame() ? this.svg_frame()['NDC'] : null;
+      var ndc = this.svg_frame().property('NDC');
       if (ndc) {
          ndc.x1 += shrink_left;
          ndc.x2 -= shrink_right;
@@ -1426,11 +1380,11 @@
    }
 
    JSROOT.TFramePainter.prototype.DrawFrameSvg = function() {
-      var width = Number(this.svg_pad(true).attr("width")),
-          height = Number(this.svg_pad(true).attr("height"));
+      var width = Number(this.svg_pad().attr("width")),
+          height = Number(this.svg_pad().attr("height"));
       var w = width, h = height;
 
-      var ndc = this.svg_frame() ? this.svg_frame()['NDC'] : null;
+      var ndc = this.svg_frame().empty() ? null : this.svg_frame().property('NDC');
       if (ndc == null) ndc = { x1 : 0.07, y1 : 0.12, x2 : 0.95, y2 : 0.88 };
 
       var root_pad = this.root_pad();
@@ -1487,12 +1441,12 @@
       if (framecolor.color == 'none') framecolor.color = 'white';
 
       // this is svg:g object - container for every other items belonging to frame
-      var frame_g = this.svg_pad(true).select(".root_frame");
+      var frame_g = this.svg_pad().select(".root_frame");
 
       var top_rect = null;
 
       if (frame_g.empty()) {
-         frame_g = this.svg_pad(true).select(".frame_layer").append("svg:g").attr("class", "root_frame");
+         frame_g = this.svg_pad().select(".frame_layer").append("svg:g").attr("class", "root_frame");
 
          top_rect = frame_g.append("svg:rect");
 
@@ -1505,15 +1459,15 @@
       }
 
       // calculate actual NDC coordinates, use them to properly locate PALETTE
-      frame_g.node()['NDC'] = {
+      frame_g.property('NDC', {
          x1 : lm / width,
          x2 : (lm + w) / width,
          y1 : tm / height,
          y2 : (tm + h) / height
-      };
+      });
 
       // simple workaround to access painter via frame container
-      frame_g.node()['frame_painter'] = this;
+      frame_g.property('frame_painter', this);
 
       lm = Math.round(lm); tm = Math.round(tm);
       w = Math.round(w); h = Math.round(h);
@@ -1672,8 +1626,8 @@
    }
 
    JSROOT.TF1Painter.prototype.DrawBins = function() {
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
       this.RecreateDrawG();
 
@@ -1921,8 +1875,8 @@
       this.lineatt.width = this.lineatt.width % 100; // line width
       if (this.lineatt.width > 0) this.optionLine = 1;
 
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
       var ratio = w / h;
 
@@ -2135,8 +2089,8 @@
 
    JSROOT.TGraphPainter.prototype.DrawBins = function() {
 
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
       this.RecreateDrawG();
 
@@ -2390,8 +2344,8 @@
    JSROOT.TPavePainter.prototype.DrawPaveText = function() {
       var pavetext = this.pavetext;
 
-      var w = Number(this.svg_pad(true).attr("width")),
-          h = Number(this.svg_pad(true).attr("height"));
+      var w = Number(this.svg_pad().attr("width")),
+          h = Number(this.svg_pad().attr("height"));
 
       var pos_x = Math.round(pavetext['fX1NDC'] * w);
 
@@ -2431,7 +2385,7 @@
       for (var j = 0; j < nlines; ++j) {
          var line = JSROOT.Painter.translateLaTeX(pavetext['fLines'].arr[j]['fTitle']);
          lines.push(line);
-         var lw = h_margin + font.stringWidth(this.svg_pad(true), line) + h_margin;
+         var lw = h_margin + font.stringWidth(this.svg_pad(), line) + h_margin;
          if (lw > maxlw) maxlw = lw;
          if ((j == 0) || (line.indexOf('|') < 0)) continue;
          if (first_stat === 0) first_stat = j;
@@ -2591,14 +2545,14 @@
          move : function(x, y, dx, dy) {
             pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
 
-            pthis.pavetext['fX1NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pthis.pavetext['fX2NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pthis.pavetext['fY1NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
-            pthis.pavetext['fY2NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
+            pthis.pavetext['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pthis.pavetext['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pthis.pavetext['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
+            pthis.pavetext['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
          },
          resize : function(width, height) {
-            pthis.pavetext['fX2NDC'] = pthis.pavetext['fX1NDC'] + width  / Number(pthis.svg_pad(true).attr("width"));
-            pthis.pavetext['fY1NDC'] = pthis.pavetext['fY2NDC'] - height / Number(pthis.svg_pad(true).attr("height"));
+            pthis.pavetext['fX2NDC'] = pthis.pavetext['fX1NDC'] + width  / Number(pthis.svg_pad().attr("width"));
+            pthis.pavetext['fY1NDC'] = pthis.pavetext['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
 
             pthis.DrawPaveText();
          }
@@ -2684,14 +2638,15 @@
 
    JSROOT.TPadPainter.prototype.CreateCanvasSvg = function(check_resize) {
 
-      var render_to = $("#" + this.divid);
+      var render_to = d3.select("#" + this.divid);
 
-      var w = render_to.width(), h = render_to.height(), factor = null;
+      var rect = render_to.node().getBoundingClientRect();
+      var w = rect.width, h = rect.height, factor = null;
 
       var svg = null;
 
       if (check_resize > 0) {
-         svg = this.svg_canvas(true);
+         svg = this.svg_canvas();
 
          var oldw = svg.property('last_width');
          var oldh = svg.property('last_height');
@@ -2706,7 +2661,7 @@
          if (factor!=null) {
             // if canvas was resize when created, resize height also now
             h = Math.round(w * factor);
-            render_to.height(h);
+            render_to.style('height', h+'px');
          }
 
          if ((check_resize==1) && (oldw>0) && (oldh>0) && !svg.property('redraw_by_resize'))
@@ -2733,7 +2688,7 @@
 
             h = Math.round(w * factor);
 
-            render_to.height(h);
+            render_to.style('height', h+'px');
          }
 
          var fill = null;
@@ -2743,7 +2698,7 @@
          else
             fill = this.createAttFill('white');
 
-         render_to.css("background-color", fill.color);
+         render_to.style("background-color", fill.color);
 
          svg = d3.select("#" + this.divid)
              .append("svg")
@@ -2771,8 +2726,8 @@
 
 
    JSROOT.TPadPainter.prototype.CreatePadSvg = function(only_resize) {
-      var width = Number(this.svg_canvas(true).attr("width")),
-          height = Number(this.svg_canvas(true).attr("height"));
+      var width = Number(this.svg_canvas().attr("width")),
+          height = Number(this.svg_canvas().attr("height"));
       var x = Math.round(this.pad['fAbsXlowNDC'] * width);
       var y = Math.round(height - this.pad['fAbsYlowNDC'] * height);
       var w = Math.round(this.pad['fAbsWNDC'] * width);
@@ -2786,10 +2741,10 @@
       var svg_pad = null, svg_rect = null;
 
       if (only_resize) {
-         svg_pad = this.svg_pad(true);
+         svg_pad = this.svg_pad();
          svg_rect = svg_pad.select(".root_pad_border");
       } else {
-         svg_pad = this.svg_canvas(true).append("g")
+         svg_pad = this.svg_canvas().append("g")
              .attr("class", "root_pad")
              .attr("pad", this.pad['fName']) // set extra attribute  to mark pad name
              .property('pad_painter', this) // this is custom property
@@ -2908,13 +2863,13 @@
       painter.pad_name = pad['fName'];
 
       // we select current pad, where all drawing is performed
-      var prev_name = painter.svg_canvas()['current_pad'];
-      painter.svg_canvas()['current_pad'] = pad['fName'];
+      var prev_name = painter.svg_canvas().property('current_pad');
+      painter.svg_canvas().property('current_pad', pad['fName']);
 
       painter.DrawPrimitives();
 
       // we restore previous pad name
-      painter.svg_canvas()['current_pad'] = prev_name;
+      painter.svg_canvas().property('current_pad', prev_name);
 
       return painter;
    }
@@ -2941,8 +2896,8 @@
       var nbr1 = axis['fNdiv'] % 100;
       if (nbr1<=0) nbr1 = 8;
 
-      var width = Number(this.svg_pad(true).attr("width")),
-          height = Number(this.svg_pad(true).attr("height"));
+      var width = Number(this.svg_pad().attr("width")),
+          height = Number(this.svg_pad().attr("height"));
 
       var s_height = Math.round(Math.abs(palette['fY2NDC'] - palette['fY1NDC']) * height);
 
@@ -3024,14 +2979,14 @@
 
             pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
 
-            pthis.palette['fX1NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pthis.palette['fX2NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pthis.palette['fY1NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
-            pthis.palette['fY2NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
+            pthis.palette['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pthis.palette['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pthis.palette['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
+            pthis.palette['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
          },
          resize : function(width, height) {
-            pthis.palette['fX2NDC'] = pthis.palette['fX1NDC'] + width / Number(pthis.svg_pad(true).attr("width"));
-            pthis.palette['fY1NDC'] = pthis.palette['fY2NDC'] - height / Number(pthis.svg_pad(true).attr("height"));
+            pthis.palette['fX2NDC'] = pthis.palette['fX1NDC'] + width / Number(pthis.svg_pad().attr("width"));
+            pthis.palette['fY1NDC'] = pthis.palette['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
 
             pthis.RemoveDrawG();
             pthis.DrawPalette();
@@ -3704,8 +3659,8 @@
          return;
       }
 
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
       if (this.histo['fXaxis']['fTimeDisplay']) {
          this.x_time = true;
@@ -3824,7 +3779,7 @@
       // grid can only be drawn by first painter
       if (!this.is_main_painter()) return;
 
-      var layer = this.svg_frame(true).select(".grid_layer");
+      var layer = this.svg_frame().select(".grid_layer");
 
       layer.selectAll(".xgrid").remove();
       layer.selectAll(".ygrid").remove();
@@ -3833,7 +3788,7 @@
       // add a grid on x axis, if the option is set
       if (this.options.Gridx) {
 
-         var h = Number(this.svg_frame(true).attr("height"));
+         var h = Number(this.svg_frame().attr("height"));
 
          var xticks = this.x.ticks(this.x_nticks);
 
@@ -3852,7 +3807,7 @@
 
       // add a grid on y axis, if the option is set
       if (this.options.Gridy) {
-         var w = Number(this.svg_frame(true).attr("width"));
+         var w = Number(this.svg_frame().attr("width"));
 
          var yticks = this.y.ticks(this.y_nticks);
 
@@ -3906,18 +3861,18 @@
 
       if (!this.is_main_painter()) return;
 
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
-      var xax_g = this.svg_frame(true).selectAll(".xaxis_container");
+      var xax_g = this.svg_frame().selectAll(".xaxis_container");
       if (xax_g.empty())
-         xax_g = this.svg_frame(true).select(".axis_layer").append("svg:g").attr("class","xaxis_container");
+         xax_g = this.svg_frame().select(".axis_layer").append("svg:g").attr("class","xaxis_container");
 
       xax_g.selectAll("*").remove();
       xax_g.attr("transform", "translate(0," + h + ")");
 
-      var yax_g = this.svg_frame(true).selectAll(".yaxis_container");
-      if (yax_g.empty()) yax_g = this.svg_frame(true).select(".axis_layer").append("svg:g").attr("class", "yaxis_container");
+      var yax_g = this.svg_frame().selectAll(".yaxis_container");
+      if (yax_g.empty()) yax_g = this.svg_frame().select(".axis_layer").append("svg:g").attr("class", "yaxis_container");
       yax_g.selectAll("*").remove();
 
       var ndivx = this.histo['fXaxis']['fNdivisions'];
@@ -4144,7 +4099,7 @@
       if ((shrink_forbidden==null) && typeof yax_g.node()['getBoundingClientRect'] == 'function') {
 
          var rect1 = yax_g.node().getBoundingClientRect();
-         var rect2 = this.svg_pad().getBoundingClientRect();
+         var rect2 = this.svg_pad().node().getBoundingClientRect();
          var position = rect1.left - rect2.left;
 
          var shrink = 0.;
@@ -4159,8 +4114,8 @@
          }
 
          if (shrink != 0) {
-            this.svg_frame()['frame_painter'].Shrink(shrink, 0);
-            this.svg_frame()['frame_painter'].Redraw();
+            this.svg_frame().property('frame_painter').Shrink(shrink, 0);
+            this.svg_frame().property('frame_painter').Redraw();
             this.CreateXY();
             this.DrawAxes(true);
          }
@@ -4178,7 +4133,7 @@
 
          var pavetext = JSROOT.Create("TPaveText");
 
-         jQuery.extend(pavetext, { fName: "title",
+         JSROOT.extend(pavetext, { fName: "title",
                                    fX1NDC: 0.2809483, fY1NDC: 0.9339831,
                                    fX2NDC: 0.7190517, fY2NDC: 0.995});
          pavetext.AddText(this.histo['fTitle']);
@@ -4276,13 +4231,13 @@
       if (this.FindStat() != null) return null;
 
       var stats = JSROOT.Create('TPaveStats');
-      jQuery.extend(stats, { _AutoCreated: true,
+      JSROOT.extend(stats, { _AutoCreated: true,
                              fName : 'stats',
                              fOptStat: JSROOT.gStyle.OptStat,
                              fBorderSize : 1} );
-      jQuery.extend(stats, JSROOT.gStyle.StatNDC);
-      jQuery.extend(stats, JSROOT.gStyle.StatText);
-      jQuery.extend(stats, JSROOT.gStyle.StatFill);
+      JSROOT.extend(stats, JSROOT.gStyle.StatNDC);
+      JSROOT.extend(stats, JSROOT.gStyle.StatText);
+      JSROOT.extend(stats, JSROOT.gStyle.StatFill);
 
       if (this.histo['_typename'] && (this.histo['_typename'].match(/^TProfile/) || this.histo['_typename'].match(/^TH2/)))
          stats['fY1NDC'] = 0.67;
@@ -4407,8 +4362,8 @@
 
       // if (!this.draw_content) return;
 
-      var width = Number(this.svg_frame(true).attr("width")),
-          height = Number(this.svg_frame(true).attr("height"));
+      var width = Number(this.svg_frame().attr("width")),
+          height = Number(this.svg_frame().attr("height"));
       var e, origin, curr = null, rect = null;
       var lasttouch = new Date(0);
 
@@ -4421,8 +4376,7 @@
       var pthis = this;
 
       function closeAllExtras() {
-         var x = document.getElementById('root_ctx_menu');
-         if (x) x.parentNode.removeChild(x);
+         JSROOT.Painter.closeMenu();
          if (rect != null) { rect.remove(); rect = null; }
          zoom_kind = 0;
          if (disable_tooltip) {
@@ -4438,18 +4392,19 @@
          // ignore context menu when touches zooming is ongoing
          if (zoom_kind > 100) return;
 
+         // one need to copy event, while after call back event may be changed
+         var evnt = d3.event;
+
          // suppress any running zomming
          closeAllExtras();
 
-         var menu = JSROOT.createMenu();
-
-         menu['painter'] = pthis;
-
-         menu.add("header:"+ pthis.histo['fName']);
-
-         pthis.FillContextMenu(menu);
+         JSROOT.Painter.createMenu(function(menu) {
+            menu['painter'] = pthis;
+            menu.add("header:"+ pthis.histo['fName']);
+            pthis.FillContextMenu(menu);
+            menu.show(evnt);
+         });
 
-         menu.show(d3.event)
       }
 
       function startTouchSel() {
@@ -4462,8 +4417,8 @@
          }
 
          // update frame dimensions while frame could be resized
-         width = Number(pthis.svg_frame(true).attr("width"));
-         height = Number(pthis.svg_frame(true).attr("height"));
+         width = Number(pthis.svg_frame().attr("width"));
+         height = Number(pthis.svg_frame().attr("height"));
 
          e = this;
          // var t = d3.event.changedTouches;
@@ -4522,7 +4477,7 @@
          // d3.select("body").classed("noselect", true);
          // d3.select("body").style("-webkit-user-select", "none");
 
-         rect = pthis.svg_frame(true).append("rect")
+         rect = pthis.svg_frame().append("rect")
                .attr("class", "zoom")
                .attr("id", "zoomRect")
                .attr("x", curr[0])
@@ -4530,7 +4485,7 @@
                .attr("width", origin[0] - curr[0])
                .attr("height", origin[1] - curr[1]);
 
-         // pthis.svg_frame(true).on("dblclick", unZoom);
+         // pthis.svg_frame().on("dblclick", unZoom);
 
          d3.select(window).on("touchmove.zoomRect", moveTouchSel)
                           .on("touchcancel.zoomRect", endTouchSel)
@@ -4634,8 +4589,8 @@
          d3.event.preventDefault();
 
          // update frame dimensions while frame could be resized
-         width = Number(pthis.svg_frame(true).attr("width"));
-         height = Number(pthis.svg_frame(true).attr("height"));
+         width = Number(pthis.svg_frame().attr("width"));
+         height = Number(pthis.svg_frame().attr("height"));
 
          closeAllExtras();
 
@@ -4667,12 +4622,12 @@
          // d3.select("body").classed("noselect", true);
          // d3.select("body").style("-webkit-user-select", "none");
 
-         rect = pthis.svg_frame(true)
+         rect = pthis.svg_frame()
                 .append("rect")
                 .attr("class", "zoom")
                 .attr("id", "zoomRect");
 
-         pthis.svg_frame(true).on("dblclick", unZoom);
+         pthis.svg_frame().on("dblclick", unZoom);
 
          d3.select(window).on("mousemove.zoomRect", moveRectSel)
                           .on("mouseup.zoomRect", endRectSel, true);
@@ -4687,7 +4642,7 @@
          if (m[0] < 0) pthis.Unzoom(false, true); else
          if (m[1] > height) pthis.Unzoom(true, false); else {
             pthis.Unzoom(true, true);
-            pthis.svg_frame(true).on("dblclick", null);
+            pthis.svg_frame().on("dblclick", null);
          }
       }
 
@@ -4769,9 +4724,9 @@
          if (isany) pthis.Zoom(xmin, xmax, ymin, ymax);
       }
 
-      this.svg_frame(true).on("mousedown", startRectSel);
-      this.svg_frame(true).on("touchstart", startTouchSel);
-      this.svg_frame(true).on("contextmenu", showContextMenu);
+      this.svg_frame().on("mousedown", startRectSel);
+      this.svg_frame().on("touchstart", startTouchSel);
+      this.svg_frame().on("contextmenu", showContextMenu);
 
    }
 
@@ -5106,7 +5061,7 @@
 
       // if we need to draw line or area, we need extra point for correct drawing
       if ((right == this.nbinsx) && (this.options.Error == 0) && (point!=null)) {
-         var extrapoint = jQuery.extend(true, {}, point);
+         var extrapoint = JSROOT.extend({}, point);
          extrapoint.x = grx2;
          draw_bins.push(extrapoint);
       }
@@ -5189,8 +5144,8 @@
 
    JSROOT.TH1Painter.prototype.DrawBins = function() {
 
-      var width = Number(this.svg_frame(true).attr("width")),
-          height = Number(this.svg_frame(true).attr("height"));
+      var width = Number(this.svg_frame().attr("width")),
+          height = Number(this.svg_frame().attr("height"));
 
       if (!this.draw_content || (width<=0) || (height<=0)) {
          this.RemoveDrawG();
@@ -5286,6 +5241,7 @@
 
       // create painter and add it to canvas
       var painter = new JSROOT.TH1Painter(histo);
+
       painter.SetDivId(divid, 1);
 
       // here we deciding how histogram will look like and how will be shown
@@ -5363,7 +5319,7 @@
    JSROOT.TH2Painter.prototype.ToggleColz = function() {
       if (this.FindPalette() == null) {
          var shrink = this.CreatePalette(0.04);
-         this.svg_frame()['frame_painter'].Shrink(0, shrink);
+         this.svg_frame().property('frame_painter').Shrink(0, shrink);
          this.options.Zscale = 1;
          // one should draw palette
          JSROOT.Painter.drawPaletteAxis(this.divid, this.FindPalette());
@@ -5430,10 +5386,12 @@
 
       pal['_AutoCreated'] = true;
 
-      pal['fX1NDC'] = this.svg_frame()['NDC'].x2 - rel_width;
-      pal['fY1NDC'] = this.svg_frame()['NDC'].y1;
-      pal['fX2NDC'] = this.svg_frame()['NDC'].x2;
-      pal['fY2NDC'] = this.svg_frame()['NDC'].y2;
+      var ndc = this.svg_frame().property('NDC');
+
+      pal['fX1NDC'] = ndc.x2 - rel_width;
+      pal['fY1NDC'] = ndc.y1;
+      pal['fX2NDC'] = ndc.x2;
+      pal['fY2NDC'] = ndc.y2;
       pal['fInit'] = 1;
       pal['fShadowColor'] = 1;
       pal['fCorenerRadius'] = 0;
@@ -5485,8 +5443,8 @@
       // and at the end try to check how much place will be used by the labels
       // in the palette
 
-      var width = Number(this.svg_frame(true).attr("width")),
-          height = Number(this.svg_frame(true).attr("height"));
+      var width = Number(this.svg_frame().attr("width")),
+          height = Number(this.svg_frame().attr("height"));
 
       var axisOffset = Math.round(axis['fLabelOffset'] * width);
       var tickSize = Math.round(axis['fTickSize'] * width);
@@ -5498,7 +5456,7 @@
 
       var maxlen = 0;
       for (var i in ticks) {
-         var len = axisfont.stringWidth(this.svg_frame(true), ticks[i]);
+         var len = axisfont.stringWidth(this.svg_frame(), ticks[i]);
          if (len > maxlen) maxlen = len;
       }
 
@@ -5879,8 +5837,8 @@
 
       this.RecreateDrawG();
 
-      var w = Number(this.svg_frame(true).attr("width")),
-          h = Number(this.svg_frame(true).attr("height"));
+      var w = Number(this.svg_frame().attr("width")),
+          h = Number(this.svg_frame().attr("height"));
 
       if ((this.options.Color==2) && !JSROOT.browser.isIE)
          return this.DrawSimpleCanvas(w,h);
@@ -5954,8 +5912,8 @@
       if ((this.FindPalette() == null) && this.create_canvas && (this.options.Zscale > 0)) {
          // create pallette
          var shrink = this.CreatePalette(0.04);
-         this.svg_frame()['frame_painter'].Shrink(0, shrink);
-         this.svg_frame()['frame_painter'].Redraw();
+         this.svg_frame().property('frame_painter').Shrink(0, shrink);
+         this.svg_frame().property('frame_painter').Redraw();
          this.CreateXY();
       } else if (this.options.Zscale == 0) {
          // delete palette - it may appear there due to previous draw options
@@ -6202,7 +6160,7 @@
    JSROOT.TLegendPainter.prototype.drawLegend = function() {
       this.RecreateDrawG(true, ".text_layer");
 
-      var svg = this.svg_pad(true);
+      var svg = this.svg_pad();
       var pave = this.legend;
 
       var x = 0, y = 0, w = 0, h = 0;
@@ -6355,8 +6313,6 @@
             JSROOT.AssertPrerequisites('mathjax', function() {
                if (typeof MathJax != 'object') return;
 
-               // MathJax.Hub.Queue(["Typeset", MathJax.Hub, body.node()]);
-
                MathJax.Hub.Queue(function() {
                   MathJax.Hub.Typeset(body.node());
                   // rescale one again
@@ -6393,14 +6349,14 @@
          move : function(x, y, dx, dy) {
             pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
 
-            pave['fX1NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pave['fX2NDC'] += dx / Number(pthis.svg_pad(true).attr("width"));
-            pave['fY1NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
-            pave['fY2NDC'] -= dy / Number(pthis.svg_pad(true).attr("height"));
+            pave['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pave['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
+            pave['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
+            pave['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
          },
          resize : function(width, height) {
-            pave['fX2NDC'] = pave['fX1NDC'] + width  / Number(pthis.svg_pad(true).attr("width"));
-            pave['fY1NDC'] = pave['fY2NDC'] - height / Number(pthis.svg_pad(true).attr("height"));
+            pave['fX2NDC'] = pave['fX1NDC'] + width  / Number(pthis.svg_pad().attr("width"));
+            pave['fY1NDC'] = pave['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
 
             pthis.drawLegend();
          }
@@ -6583,8 +6539,8 @@
 
       var pavelabel = this.text;
 
-      var w = Number(this.svg_pad(true).attr("width")),
-          h = Number(this.svg_pad(true).attr("height"));
+      var w = Number(this.svg_pad().attr("width")),
+          h = Number(this.svg_pad().attr("height"));
 
       var pos_x = pavelabel['fX1NDC'] * w;
       var pos_y = (1.0 - pavelabel['fY1NDC']) * h;
@@ -6633,7 +6589,7 @@
 
       var line = JSROOT.Painter.translateLaTeX(pavelabel['fLabel']);
 
-      var lw = font.stringWidth(this.svg_pad(true), line);
+      var lw = font.stringWidth(this.svg_pad(), line);
       if (lw > width) font.size = Math.floor(font.size * (width / lw));
 
       pave.append("text")
@@ -6666,8 +6622,8 @@
 
       var kTextNDC = JSROOT.BIT(14);
 
-      var w = Number(this.svg_pad(true).attr("width")),
-          h = Number(this.svg_pad(true).attr("height"));
+      var w = Number(this.svg_pad().attr("width")),
+          h = Number(this.svg_pad().attr("height"));
       var align = 'start', halign = Math.round(this.text['fTextAlign'] / 10);
       var baseline = 'bottom', valign = this.text['fTextAlign'] % 10;
       if (halign == 1) align = 'start';
@@ -6751,7 +6707,7 @@
    }
 
    JSROOT.Painter.drawStreamerInfo = function(divid, obj) {
-      $("#" + divid).css({ overflow : 'auto' });
+      d3.select("#" + divid).style( 'overflow' , 'auto' );
       var painter = new JSROOT.HierarchyPainter('sinfo', divid);
       painter.ShowStreamerInfo(obj);
       return painter;
@@ -6774,34 +6730,34 @@
    }
 
    JSROOT.RawTextPainter.prototype.Draw = function() {
-      var frame = $("#" + this.divid);
+      var frame = d3.select("#" + this.divid);
 
       var txt = this.txt.value;
       if (txt==null) txt = "<undefined>";
 
       var mathjax = 'mathjax' in this.txt;
 
-      if ('load' in this.txt) {
-         frame.html("<div style='overflow:hidden'></div>");
-         frame.find('div').load(this.txt.load);
-      } else {
-         if (!mathjax && !('as_is' in this.txt)) {
-            var arr = txt.split("\n"); txt = "";
-            for (var i in arr)
-               txt += "<pre>" + arr[i] + "</pre>";
-         }
-         frame.html("<div style='overflow:hidden'>" + txt + "</div>");
+      if (!mathjax && !('as_is' in this.txt)) {
+         var arr = txt.split("\n"); txt = "";
+         for (var i in arr)
+            txt += "<pre>" + arr[i] + "</pre>";
       }
+      frame.html("<div style='overflow:hidden'>" + txt + "</div>");
 
       // (re) set painter to first child element
       this.SetDivId(this.divid);
 
-      if (mathjax)
+      if (mathjax) {
+         if (this['loading_mathjax']) return;
+         this['loading_mathjax'] = true;
+         var painter = this;
          JSROOT.AssertPrerequisites('mathjax', function() {
+            painter['loading_mathjax'] = false;
             if (typeof MathJax == 'object') {
-               MathJax.Hub.Queue(["Typeset", MathJax.Hub, frame.get()]);
+               MathJax.Hub.Queue(["Typeset", MathJax.Hub, frame.node()]);
             }
          });
+      }
    }
 
    JSROOT.Painter.drawRawText = function(divid, txt, opt) {
@@ -6811,127 +6767,6 @@
       return painter;
    }
 
-   // ========== performs tree drawing on server ==================
-
-   JSROOT.TTreePlayer = function(itemname) {
-      JSROOT.TBasePainter.call(this);
-      this.SetItemName(itemname);
-      this.hpainter = null;
-      return this;
-   }
-
-   JSROOT.TTreePlayer.prototype = Object.create( JSROOT.TBasePainter.prototype );
-
-   JSROOT.TTreePlayer.prototype.Show = function(divid) {
-      this.drawid = divid + "_draw";
-
-      $("#" + divid)
-        .html("<div class='treedraw_buttons' style='padding-left:0.5em'>" +
-            "<button class='treedraw_exe'>Draw</button>" +
-            " Expr:<input class='treedraw_varexp' style='width:12em'></input> " +
-            "<button class='treedraw_more'>More</button>" +
-            "</div>" +
-            "<div id='" + this.drawid + "' style='width:100%'></div>");
-
-      var player = this;
-
-      $("#" + divid).find('.treedraw_exe').click(function() { player.PerformDraw(); });
-      $("#" + divid).find('.treedraw_varexp')
-           .val("px:py")
-           .keyup(function(e){
-               if(e.keyCode == 13) player.PerformDraw();
-            });
-
-      $("#" + divid).find('.treedraw_more').click(function() {
-         $(this).remove();
-         $("#" + divid).find(".treedraw_buttons")
-         .append(" Cut:<input class='treedraw_cut' style='width:8em'></input>"+
-                 " Opt:<input class='treedraw_opt' style='width:5em'></input>"+
-                 " Num:<input class='treedraw_number' style='width:7em'></input>" +
-                 " First:<input class='treedraw_first' style='width:7em'></input>");
-
-         $("#" + divid +" .treedraw_opt").val("");
-         $("#" + divid +" .treedraw_number").val("").spinner({ numberFormat: "n", min: 0, page: 1000});
-         $("#" + divid +" .treedraw_first").val("").spinner({ numberFormat: "n", min: 0, page: 1000});
-      });
-
-      this.CheckResize();
-
-      this.SetDivId(divid);
-   }
-
-   JSROOT.TTreePlayer.prototype.PerformDraw = function() {
-
-      var frame = $("#" + this.divid);
-
-      var url = this.GetItemName() + '/exe.json.gz?compact=3&method=Draw';
-      var expr = frame.find('.treedraw_varexp').val();
-      var hname = "h_tree_draw";
-
-      var pos = expr.indexOf(">>");
-      if (pos<0) {
-         expr += ">>" + hname;
-      } else {
-         hname = expr.substr(pos+2);
-         if (hname[0]=='+') hname = hname.substr(1);
-         var pos2 = hname.indexOf("(");
-         if (pos2>0) hname = hname.substr(0, pos2);
-      }
-
-      if (frame.find('.treedraw_more').length==0) {
-         var cut = frame.find('.treedraw_cut').val();
-         var option = frame.find('.treedraw_opt').val();
-         var nentries = frame.find('.treedraw_number').val();
-         var firstentry = frame.find('.treedraw_first').val();
-
-         url += '&prototype="const char*,const char*,Option_t*,Long64_t,Long64_t"&varexp="' + expr + '"&selection="' + cut + '"';
-
-         // if any of optional arguments specified, specify all of them
-         if ((option!="") || (nentries!="") || (firstentry!="")) {
-            if (nentries=="") nentries = "1000000000";
-            if (firstentry=="") firstentry = "0";
-            url += '&option="' + option + '"&nentries=' + nentries + '&firstentry=' + firstentry;
-         }
-      } else {
-         url += '&prototype="Option_t*"&opt="' + expr + '"';
-      }
-      url += '&_ret_object_=' + hname;
-
-      var player = this;
-
-      var req = JSROOT.NewHttpRequest(url, 'object', function(res) {
-         if (res==0) return;
-         $("#"+player.drawid).empty();
-         player.hpainter = JSROOT.draw(player.drawid, res)
-      });
-      req.send();
-   }
-
-   JSROOT.TTreePlayer.prototype.CheckResize = function(force) {
-      $("#" + this.drawid).width($("#" + this.divid).width());
-      var h = $("#" + this.divid).height();
-      var h0 = $("#" + this.divid +" .treedraw_buttons").height();
-      if (h>h0+30) $("#" + this.drawid).height(h - 1 - h0);
-
-      if (this.hpainter) {
-         this.hpainter.CheckResize(force);
-      }
-   }
-
-   JSROOT.drawTreePlayer = function(hpainter, itemname) {
-      var mdi = hpainter.CreateDisplay();
-      if (mdi == null) return null;
-
-      var frame = mdi.FindFrame(itemname, true);
-      if (frame==null) return null;
-
-      var divid = frame.attr('id');
-
-      var player = new JSROOT.TTreePlayer(itemname);
-      player.Show(divid);
-      return player;
-   }
-
    // =========== painter of hierarchical structures =================================
 
    JSROOT.HierarchyPainter = function(name, frameid) {
@@ -7365,288 +7200,12 @@
       req.send();
    }
 
-   JSROOT.HierarchyPainter.prototype.RefreshHtml = function(force) {
-      if (this.frameid == null) return;
-      var elem = $("#" + this.frameid);
-      if (elem.length == 0) return;
-
-      if (this.h == null) return elem.html("<h2>null</h2>");
-
-      var factcmds = this.FindFastCommands();
-
-      this['html'] = "";
-      if (factcmds) {
-         for (var n in factcmds)
-            this['html'] += "<button class='fast_command'> </button>";
-      }
-      this['html'] += "<p>";
-      this['html'] += "<a href='#open_all'>open all</a>";
-      this['html'] += "| <a href='#close_all'>close all</a>";
-      if ('_online' in this.h)
-         this['html'] += "| <a href='#reload'>reload</a>";
-      else
-         this['html'] += "<a/>";
-
-      if ('disp_kind' in this)
-         this['html'] += "| <a href='#clear'>clear</a>";
-      else
-         this['html'] += "<a/>";
-
-      this['html'] += "</p>";
-
-      this['html'] += '<div class="h_tree">';
-      this.addItemHtml(this.h, null);
-      this['html'] += '</div>';
-
-      var h = this;
-
-      var items = elem.html(this['html'])
-          .find(".h_item")
-          .click(function() { h.tree_click($(this)); });
-
-      if ('disp_kind' in h) {
-         if (JSROOT.gStyle.DragAndDrop)
-            items.draggable({ revert: "invalid", appendTo: "body", helper: "clone" });
-
-         if (JSROOT.gStyle.ContextMenu)
-            items.on('contextmenu', function(e) { h.tree_contextmenu($(this), e); });
-      }
-
-      elem.find(".plus_minus").click(function() { h.tree_click($(this),true); });
-
-      elem.find("a").first().click(function() { h.toggle(true); return false; })
-                    .next().click(function() { h.toggle(false); return false; })
-                    .next().click(function() { h.reload(); return false; })
-                    .next().click(function() { h.clear(false); return false; });
-
-      if (factcmds)
-         elem.find('.fast_command').each(function(index) {
-            if ('_icon' in factcmds[index])
-               $(this).text("").append('<img src="' + factcmds[index]['_icon'] + '"/>');
-            $(this).button()
-                   .attr("item", h.itemFullName(factcmds[index]))
-                   .attr("title", factcmds[index]._title)
-                   .click(function() { h.ExecuteCommand($(this).attr("item"), $(this)); });
-         });
-   }
-
-   JSROOT.HierarchyPainter.prototype.isLastSibling = function(hitem) {
-      if (!hitem || !hitem._parent || !hitem._parent._childs) return false;
-      var chlds = hitem._parent._childs;
-      var indx = chlds.indexOf(hitem);
-      if (indx<0) return false;
-      while (++indx < chlds.length)
-         if (!('_hidden' in chlds[indx])) return false;
-      return true;
-   }
-
-   JSROOT.HierarchyPainter.prototype.addItemHtml = function(hitem, parent) {
-      var isroot = (parent == null);
-      var has_childs = '_childs' in hitem;
-
-      if ('_hidden' in hitem) return;
-
-      var cando = this.CheckCanDo(hitem);
-
-      if (!isroot) hitem._parent = parent;
-
-      var can_click = false;
-
-      if (!has_childs || !cando.scan) {
-         if (cando.expand) {
-            can_click = true;
-            if (cando.img1.length == 0) {
-               cando.img1 = 'img_folder';
-               cando.img2 = 'img_folderopen';
-            }
-         } else
-         if (cando.display || cando.execute) {
-            can_click = true;
-         } else
-         if (cando.html.length > 0) can_click = true;
-      }
-
-      hitem['_img1'] = cando.img1;
-      hitem['_img2'] = cando.img2;
-      if (hitem['_img2']=="") hitem['_img2'] = hitem['_img1'];
-
-      // assign root icon
-      if (isroot && (hitem['_img1'].length==0))
-         hitem['_img1'] = hitem['_img2'] = "img_base";
-
-      // assign node icons
-
-      if (hitem['_img1'].length==0)
-         hitem['_img1'] = has_childs ? "img_folder" : "img_page";
-
-      if (hitem['_img2'].length==0)
-         hitem['_img2'] = has_childs ? "img_folderopen" : "img_page";
-
-      var itemname = this.itemFullName(hitem);
-
-      this['html'] += '<div item="' + itemname + '">';
-
-      // build indent
-      var sindent = "";
-      var prnt = isroot ? null : hitem._parent;
-      while ((prnt != null) && (prnt != this.h)) {
-         sindent = '<div class="' + (this.isLastSibling(prnt) ? "img_empty" : "img_line") + '"/>' + sindent;
-         prnt = prnt._parent;
-      }
-      this['html'] += sindent;
-
-      var icon_class = "", plusminus = false;
-
-      if (isroot) {
-         // for root node no extra code
-      } else
-      if (has_childs) {
-         icon_class = hitem._isopen ? "img_minus" : "img_plus";
-         plusminus = true;
-      } else {
-         icon_class = "img_join";
-      }
-
-      if (icon_class.length > 0) {
-         this['html'] += '<div class="' + icon_class;
-         if (this.isLastSibling(hitem)) this['html'] += "bottom";
-         if (plusminus) this['html'] += ' plus_minus" style="cursor:pointer';
-         this['html'] += '"/>';
-      }
-
-      // make node icons
-
-      var icon_name = hitem._isopen ? hitem._img2 : hitem._img1;
-
-      if (icon_name.indexOf("img_")==0)
-         this['html'] += '<div class="' + icon_name + '"/>';
-      else
-         this['html'] += '<img src="' + icon_name + '" alt="" style="vertical-align:top"/>';
-
-      this['html'] += '<a';
-      if (can_click || has_childs) this['html'] +=' class="h_item"';
-
-      var element_name = hitem._name;
-
-      if ('_realname' in hitem)
-         element_name = hitem._realname;
-
-      var element_title = "";
-      if ('_title' in hitem) element_title = hitem._title;
-
-      if ('_fullname' in hitem)
-         element_title += "  fullname: " + hitem['_fullname'];
-
-      if (element_title.length == 0) element_title = element_name;
-
-      this['html'] += ' title="' + element_title + '"';
-      this['html'] += '>' + element_name + '</a>';
-
-      if (has_childs && (isroot || hitem._isopen)) {
-         this['html'] += '<div class="h_childs">';
-         for (var i in hitem._childs)
-            this.addItemHtml(hitem._childs[i], hitem);
-         this['html'] += '</div>';
-      }
-
-      this['html'] += '</div>';
-   }
-
-   JSROOT.HierarchyPainter.prototype.tree_click = function(node, plusminus) {
-
-      var itemname = node.parent().attr('item');
-
-      if (itemname==null) return;
-
-      var hitem = this.Find(itemname);
-      if (hitem==null) return;
-
-      if (!plusminus) {
-         var cando = this.CheckCanDo(hitem);
-
-         if (cando.open && (cando.html.length>0))
-            return window.open(cando.html);
-
-         if (cando.expand && (hitem['_childs'] == null))
-            return this.expand(itemname, hitem, node.parent());
-
-         if (cando.display)
-            return this.display(itemname);
-
-         if (cando.execute)
-            return this.ExecuteCommand(itemname, node);
-
-         if (!('_childs' in hitem) || (hitem === this.h)) return;
-      }
-
-      if (hitem._isopen)
-         delete hitem._isopen;
-      else
-         hitem._isopen = true;
-
-      this.UpdateTreeNode(node.parent(), hitem);
-   }
-
-   JSROOT.HierarchyPainter.prototype.open = function(itemname) {
-      console.log("open() no longer available");
-   }
-
-   JSROOT.HierarchyPainter.prototype.UpdateTreeNode = function(node, hitem) {
-      var has_childs = '_childs' in hitem;
-
-      var newname = hitem._isopen ? hitem._img2 : hitem._img1;
-      var oldname = hitem._isopen ? hitem._img1 : hitem._img2;
-
-      var img = node.find("a").first().prev();
-
-      if (newname.indexOf("img_")<0) {
-         img.attr("src", newname);
-      } else {
-         if (newname!=oldname)
-            img.switchClass(oldname, newname);
-      }
-
-      img = img.prev();
-
-      var h = this;
-
-      var new_class = hitem._isopen ? "img_minus" : "img_plus";
-      if (this.isLastSibling(hitem)) new_class += "bottom";
-
-      if (img.hasClass("plus_minus")) {
-         img.attr('class', new_class + " plus_minus");
-      } else
-      if (has_childs) {
-         img.attr('class', new_class + " plus_minus");
-         img.css('cursor', 'pointer');
-         img.click(function() { h.tree_click($(this), true); });
-      }
-
-      var childs = node.children().last();
-      if (childs.hasClass("h_childs")) childs.remove();
-
-      var display_childs = has_childs && hitem._isopen;
-      if (!display_childs) return;
-
-      this['html'] = '<div class="h_childs">';
-      for (var i in hitem._childs)
-         this.addItemHtml(hitem._childs[i], hitem);
-      this['html'] += '</div>';
-      node.append(this['html']);
-      childs = node.children().last();
-
-      var items = childs.find(".h_item")
-                   .click(function() { h.tree_click($(this)); });
-
-      if ('disp_kind' in h) {
-         if (JSROOT.gStyle.DragAndDrop)
-            items.draggable({ revert: "invalid", appendTo: "body", helper: "clone" });
-
-         if (JSROOT.gStyle.ContextMenu)
-            items.on('contextmenu', function(e) { h.tree_contextmenu($(this), e); })
-      }
-
-      childs.find(".plus_minus").click(function() { h.tree_click($(this), true); });
+   JSROOT.HierarchyPainter.prototype.RefreshHtml = function(callback) {
+      if (this.frameid == null) return JSROOT.CallBack(callback);
+      var hpainter = this;
+      JSROOT.AssertPrerequisites('jq2d', function() {
+         hpainter.RefreshHtml(callback);
+      });
    }
 
    JSROOT.HierarchyPainter.prototype.toggle = function(status) {
@@ -7718,97 +7277,88 @@
    JSROOT.HierarchyPainter.prototype.player = function(itemname, option, call_back) {
       var item = this.Find(itemname);
 
-      var player_func = (item && ('_player' in item)) ?  JSROOT.findFunction(item._player) : null;
+      if (!item || !('_player' in item)) return JSROOT.CallBack(call_back, null);
 
-      var res = null;
+      var hpainter = this;
 
-      if (player_func && this.CreateDisplay())
-         res = player_func(this, itemname, option);
+      var prereq = ('_prereq' in item) ? item['_prereq'] : '';
 
-      JSROOT.CallBack(call_back, res);
-   }
+      JSROOT.AssertPrerequisites(prereq, function() {
 
-   JSROOT.HierarchyPainter.prototype.display = function(itemname, drawopt, call_back) {
+         var player_func = JSROOT.findFunction(item._player);
+         if (player_func == null) return JSROOT.CallBack(call_back, null);
 
-      if (!this.CreateDisplay()) return JSROOT.CallBack(call_back, null, itemname);
+         hpainter.CreateDisplay(function(mdi) {
+            var res = null;
+            if (mdi) res = player_func(hpainter, itemname, option);
+            JSROOT.CallBack(call_back, res);
+         });
+      });
+   }
 
+   JSROOT.HierarchyPainter.prototype.display = function(itemname, drawopt, call_back) {
       var h = this;
 
-      var mdi = h['disp'];
-
-      var updating = drawopt=="update";
+      h.CreateDisplay(function(mdi) {
+         if (!mdi) return JSROOT.CallBack(call_back, null, itemname);
 
-      var item = h.Find(itemname);
+         var updating = (drawopt=="update");
 
-      if (item!=null) {
-         var cando = this.CheckCanDo(item);
-         if (!cando.display || ('_player' in item))
-            return this.player(itemname, drawopt, function() { JSROOT.CallBack(call_back, null, itemname); });
-      }
-
-      if (updating) {
-         if ((item==null) || ('_doing_update' in item)) return JSROOT.CallBack(call_back, null, itemname);
-         item['_doing_update'] = true;
-      }
+         var item = h.Find(itemname);
 
-      h.get(itemname, function(item, obj) {
+         if (item!=null) {
+            var cando = h.CheckCanDo(item);
+            if (!cando.display || ('_player' in item))
+               return h.player(itemname, drawopt, function() { JSROOT.CallBack(call_back, null, itemname); });
+         }
 
-         if (updating && item) delete item['_doing_update'];
-         if (obj==null) return JSROOT.CallBack(call_back, null, itemname);
+         if (updating) {
+            if ((item==null) || ('_doing_update' in item)) return JSROOT.CallBack(call_back, null, itemname);
+            item['_doing_update'] = true;
+         }
 
-         var painter = null;
+         h.get(itemname, function(item, obj) {
+            if (updating && item) delete item['_doing_update'];
+            if (obj==null) return JSROOT.CallBack(call_back, null, itemname);
 
-         var pos = drawopt ? drawopt.indexOf("divid:") : -1;
-         if (pos>=0) {
-            var divid = drawopt.slice(pos+6);
-            drawopt = drawopt.slice(0, pos);
-            painter = h.draw(divid, obj, drawopt);
-         } else
-         mdi.ForEachPainter(function(p, frame) {
-            if (p.GetItemName() != itemname) return;
-            painter = p;
-            mdi.ActivateFrame(frame);
-            painter.RedrawObject(obj);
-         });
+            var painter = null;
 
-         if (painter==null) {
-            if (updating) {
-               console.log("something went wrong - did not found painter when doing update of " + itemname);
+            var pos = drawopt ? drawopt.indexOf("divid:") : -1;
+            if (pos>=0) {
+               var divid = drawopt.slice(pos+6);
+               drawopt = drawopt.slice(0, pos);
+               painter = h.draw(divid, obj, drawopt);
             } else {
-               var frame = mdi.FindFrame(itemname, true);
-               if (JSROOT.gStyle.DragAndDrop)
-                  frame.addClass("ui-state-default");
-               painter = h.draw(frame.attr("id"), obj, drawopt);
-
-               mdi.ActivateFrame(frame);
-
-               if (JSROOT.gStyle.DragAndDrop)
-                  frame.droppable({
-                     hoverClass : "ui-state-active",
-                     accept: function(ui) {
-                        var dropname = ui.parent().attr('item');
-                        if ((dropname == itemname) || (dropname==null)) return false;
-
-                        var ditem = h.Find(dropname);
-                        if ((ditem==null) || (!('_kind' in ditem))) return false;
-
-                        return ditem._kind.indexOf("ROOT.")==0;
-                     },
-                     drop: function(event, ui) {
-                        var dropname = ui.draggable.parent().attr('item');
-                        if (dropname==null) return false;
-                        return h.dropitem(dropname, frame.attr("id"));
-                     }
-                  }).removeClass('ui-state-default');
+               mdi.ForEachPainter(function(p, frame) {
+                  if (p.GetItemName() != itemname) return;
+                  painter = p;
+                  mdi.ActivateFrame(frame);
+                  painter.RedrawObject(obj);
+               });
+            }
+
+            if (painter==null) {
+               if (updating) {
+                  console.log("something went wrong - did not found painter when doing update of " + itemname);
+               } else {
+                  var frame = mdi.FindFrame(itemname, true);
+                  painter = h.draw(d3.select(frame).attr("id"), obj, drawopt);
+                  mdi.ActivateFrame(frame);
+                  h.enable_dropping(frame, itemname);
+               }
             }
-         }
 
-         if (painter) painter.SetItemName(itemname); // mark painter as created from hierarchy
+            if (painter) painter.SetItemName(itemname); // mark painter as created from hierarchy
 
-         JSROOT.CallBack(call_back, painter, itemname);
+            JSROOT.CallBack(call_back, painter, itemname);
+         });
       });
    }
 
+   JSROOT.HierarchyPainter.prototype.enable_dropping = function(frame, itemname) {
+      // here is not used - implemented with jquery
+   }
+
    JSROOT.HierarchyPainter.prototype.dropitem = function(itemname, divid, call_back) {
       var h = this;
       var mdi = h['disp'];
@@ -7825,7 +7375,6 @@
       return true;
    }
 
-
    JSROOT.HierarchyPainter.prototype.updateAll = function() {
       // method can be used to fetch new objects and update all existing drawings
 
@@ -7856,71 +7405,72 @@
 
    JSROOT.HierarchyPainter.prototype.displayAll = function(items, options, call_back) {
 
-      if ((items == null) || (items.length == 0) ||!this.CreateDisplay())
-         return JSROOT.CallBack(call_back);
-
-      if (options == null) options = [];
-      while (options.length < items.length)
-         options.push("");
+      if ((items == null) || (items.length == 0)) return JSROOT.CallBack(call_back);
 
-      var mdi = this['disp'];
+      var h = this;
 
-      var dropitems = new Array(items.length);
-
-      // First of all check that items are exists, look for cycle extension
-      for (var i in items) {
-         dropitems[i] = null;
-         if (this.Find(items[i])) continue;
-         if (this.Find(items[i] + ";1")) { items[i] += ";1"; continue; }
-
-         var pos = items[i].indexOf("+");
-         if (pos>0) {
-            dropitems[i] = items[i].split("+");
-            items[i] = dropitems[i].shift();
-            // allow to specify _same_ item in different file
-            for (var j in dropitems[i]) {
-               var pos = dropitems[i][j].indexOf("_same_");
-               if ((pos>0) && (this.Find(dropitems[i][j])==null))
-                  dropitems[i][j] = dropitems[i][j].substr(0,pos) + items[i].substr(pos);
+      h.CreateDisplay(function(mdi) {
+         if (!mdi) return JSROOT.CallBack(call_back);
+
+         if (options == null) options = [];
+         while (options.length < items.length)
+            options.push("");
+
+         var dropitems = new Array(items.length);
+
+         // First of all check that items are exists, look for cycle extension
+         for (var i in items) {
+            dropitems[i] = null;
+            if (h.Find(items[i])) continue;
+            if (h.Find(items[i] + ";1")) { items[i] += ";1"; continue; }
+
+            var pos = items[i].indexOf("+");
+            if (pos>0) {
+               dropitems[i] = items[i].split("+");
+               items[i] = dropitems[i].shift();
+               // allow to specify _same_ item in different file
+               for (var j in dropitems[i]) {
+                  var pos = dropitems[i][j].indexOf("_same_");
+                  if ((pos>0) && (h.Find(dropitems[i][j])==null))
+                     dropitems[i][j] = dropitems[i][j].substr(0,pos) + items[i].substr(pos);
+               }
             }
-         }
-
-         // also check if subsequent items has _same_, than use name from first item
-         var pos = items[i].indexOf("_same_");
-         if ((pos>0) && !this.Find(items[i]) && (i>0))
-            items[i] = items[i].substr(0,pos) + items[0].substr(pos);
-      }
 
-      // Than create empty frames for each item
-      for (var i in items)
-         if (options[i]!='update')
-            mdi.CreateFrame(items[i]);
+            // also check if subsequent items has _same_, than use name from first item
+            var pos = items[i].indexOf("_same_");
+            if ((pos>0) && !h.Find(items[i]) && (i>0))
+               items[i] = items[i].substr(0,pos) + items[0].substr(pos);
+         }
 
-      var h = this;
+         // Than create empty frames for each item
+         for (var i in items)
+            if (options[i]!='update')
+               mdi.CreateFrame(items[i]);
 
-      // We start display of all items parallel
-      for (var i in items)
-         this.display(items[i], options[i], function(painter, itemname) {
-            // one cannot use index i in callback - it is asynchron
-            var indx = items.indexOf(itemname);
-            if (indx<0) return console.log('did not found item ' + itemname);
+         // We start display of all items parallel
+         for (var i in items)
+            h.display(items[i], options[i], function(painter, itemname) {
+               // one cannot use index i in callback - it is asynchron
+               var indx = items.indexOf(itemname);
+               if (indx<0) return console.log('did not found item ' + itemname);
 
-            items[indx] = "---"; // mark item as ready
+               items[indx] = "---"; // mark item as ready
 
-            function DropNextItem() {
-               if ((painter!=null) && (dropitems[indx]!=null) && (dropitems[indx].length>0))
-                  return h.dropitem(dropitems[indx].shift(), painter.divid, DropNextItem);
+               function DropNextItem() {
+                  if ((painter!=null) && (dropitems[indx]!=null) && (dropitems[indx].length>0))
+                     return h.dropitem(dropitems[indx].shift(), painter.divid, DropNextItem);
 
-               var isany = false;
-               for (var cnt in items)
-                  if (items[cnt]!='---') isany = true;
+                  var isany = false;
+                  for (var cnt in items)
+                     if (items[cnt]!='---') isany = true;
 
-               // only when items drawn and all sub-items dropped, one could perform call-back
-               if (!isany) JSROOT.CallBack(call_back);
-            }
+                  // only when items drawn and all sub-items dropped, one could perform call-back
+                  if (!isany) JSROOT.CallBack(call_back);
+               }
 
-            DropNextItem();
-         });
+               DropNextItem();
+            });
+      });
    }
 
    JSROOT.HierarchyPainter.prototype.reload = function() {
@@ -7928,38 +7478,8 @@
          this.OpenOnline(this.h['_online']);
    }
 
-   JSROOT.HierarchyPainter.prototype.expand = function(itemname, item0, node) {
-      var painter = this;
-
-      if (node==null)
-         node = $("#" + this.frameid).find("[item='" + itemname + "']");
-
-      if (node.length==0)
-         return console.log("Did not found node with item = " + itemname);
-
-      if (item0==null) item0 = this.Find(itemname);
-      if (item0==null) return;
-      item0['_doing_expand'] = true;
-
-      this.get(itemname, function(item, obj) {
-         delete item0['_doing_expand'];
-         if ((item == null) || (obj == null)) return;
-
-         var curr = item;
-         while (curr != null) {
-            if (('_expand' in curr) && (typeof (curr['_expand']) == 'function')) {
-                if (curr['_expand'](item, obj)) {
-                   var itemname = painter.itemFullName(item);
-                   node.attr('item', itemname);
-                   node.find("a").text(item._name);
-                   item._isopen = true;
-                   painter.UpdateTreeNode(node, item);
-                }
-                return;
-            }
-            curr = ('_parent' in curr) ? curr['_parent'] : null;
-         }
-      });
+   JSROOT.HierarchyPainter.prototype.expand = function(itemname) {
+      alert('expand ' + itemname + ' can be used only jquery part loaded');
    }
 
    JSROOT.HierarchyPainter.prototype.GetTopOnlineItem = function() {
@@ -8006,9 +7526,7 @@
                pthis.h = { _name: topname, _kind: 'JSROOT.TopFolder', _childs : [h0, h1] };
             }
 
-            pthis.RefreshHtml();
-
-            JSROOT.CallBack(call_back);
+            pthis.RefreshHtml(call_back);
          });
       });
    }
@@ -8054,7 +7572,7 @@
             req  = 'h.json?compact=3';
          } else
          if (item._kind.indexOf("ROOT.")!=0)
-            req = 'get.json?compact=3';
+            req = 'get.json.gz?compact=3';
       }
 
       if (url.length > 0) url += "/";
@@ -8100,10 +7618,9 @@
          }
 
          painter.CompleteOnline(function() {
-            if (painter.h != null)
-               painter.RefreshHtml(true);
-
-            JSROOT.CallBack(user_callback, painter);
+            painter.RefreshHtml(function() {
+               JSROOT.CallBack(user_callback, painter);
+            });
          });
       }
 
@@ -8213,143 +7730,152 @@
       return this['_monitoring_on'];
    }
 
-   JSROOT.HierarchyPainter.prototype.tree_contextmenu = function(node, event) {
-      event.preventDefault();
-
-      var itemname = node.parent().attr('item');
+   JSROOT.HierarchyPainter.prototype.SetDisplay = function(kind, frameid) {
+      this['disp_kind'] = kind;
+      this['disp_frameid'] = frameid;
+   }
 
-      var hitem = this.Find(itemname);
-      if (hitem==null) return;
+   JSROOT.HierarchyPainter.prototype.clear = function(withbrowser) {
+      if ('disp' in this) {
+         this['disp'].Reset();
+         delete this['disp'];
+      }
 
-      var cando = this.CheckCanDo(hitem);
+      if (withbrowser) {
+         d3.select("#" + this.frameid).html("");
+         delete this.h;
+      }
+   }
 
-      // if (!cando.display && !cando.ctxt && (itemname!="")) return;
+   JSROOT.HierarchyPainter.prototype.GetDisplay = function() {
+      return ('disp' in this) ? this['disp'] : null;
+   }
 
-      var onlineprop = this.GetOnlineProp(itemname);
-      var fileprop = this.GetFileProp(itemname);
+   JSROOT.HierarchyPainter.prototype.CreateDisplay = function(callback) {
 
-      var menu = JSROOT.createMenu();
+      var h = this;
 
-      function qualifyURL(url) {
-         function escapeHTML(s) {
-            return s.split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
-         }
-         var el = document.createElement('div');
-         el.innerHTML = '<a href="' + escapeHTML(url) + '">x</a>';
-         return el.firstChild.href;
+      if ('disp' in this) {
+         if (h['disp'].NumDraw() > 0) return JSROOT.CallBack(callback, h['disp']);
+         h['disp'].Reset();
+         delete h['disp'];
       }
 
-      var painter = this;
+      // check that we can found frame where drawing should be done
+      if (document.getElementById(this['disp_frameid']) == null)
+         return JSROOT.CallBack(callback, null);
 
-      if (itemname == "") {
-         var addr = "", cnt = 0;
-         function separ() { return cnt++ > 0 ? "&" : "?"; }
+      if (h['disp_kind'] == "simple")
+         h['disp'] = new JSROOT.SimpleDisplay(h['disp_frameid']);
+      else
+      if (h['disp_kind'].search("grid") == 0)
+         h['disp'] = new JSROOT.GridDisplay(h['disp_frameid'], h['disp_kind']);
 
-         var files = [];
-         this.ForEachRootFile(function(item) { files.push(item._file.fFullURL); });
+      if (h['disp'] != null)
+         JSROOT.CallBack(callback, h['disp']);
+      else
+         JSROOT.AssertPrerequisites('jq2d', function() {
+            h.CreateDisplay(callback);
+         });
+   }
 
-         if (this.GetTopOnlineItem()==null)
-            addr = JSROOT.source_dir + "index.htm";
+   JSROOT.HierarchyPainter.prototype.CheckResize = function(force) {
+      if ('disp' in this)
+         this['disp'].CheckResize();
+   }
 
-         if (this.IsMonitoring())
-            addr += separ() + "monitoring=" + this.MonitoringInterval();
+   JSROOT.HierarchyPainter.prototype.StartGUI = function(h0, call_back) {
+      var hpainter = this;
+      var filesarr = JSROOT.GetUrlOptionAsArray("file;files");
+      var filesdir = JSROOT.GetUrlOption("path");
+      if (filesdir!=null)
+         for (var i in filesarr) filesarr[i] = filesdir + filesarr[i];
 
-         if (files.length==1)
-            addr += separ() + "file=" + files[0];
-         else
-         if (files.length>1)
-            addr += separ() + "files=" + JSON.stringify(files);
+      var itemsarr = JSROOT.GetUrlOptionAsArray("item;items");
 
-         if (this['disp_kind'])
-            addr += separ() + "layout=" + this['disp_kind'].replace(/ /g, "");
+      var optionsarr = JSROOT.GetUrlOptionAsArray("opt;opts");
 
-         var items = [];
+      var monitor = JSROOT.GetUrlOption("monitoring");
 
-         if (this['disp'] != null)
-            this['disp'].ForEachPainter(function(painter) {
-               if (painter.GetItemName()!=null)
-                  items.push(painter.GetItemName());
-            });
+      var layout = JSROOT.GetUrlOption("layout");
+      if (!this['disp_kind'] || (layout!=null))
+         this['disp_kind'] = (layout && layout.length>0) ? layout : 'simple';
 
-         if (items.length == 1) {
-            addr += separ() + "item=" + items[0];
-         } else if (items.length > 1) {
-            addr += separ() + "items=" + JSON.stringify(items);
-         }
+      if (JSROOT.GetUrlOption('files_monitoring')!=null) this.files_monitoring = true;
 
-         menu.add("Direct link", function() { window.open(addr); });
-         menu.add("Only items", function() { window.open(addr + "&nobrowser"); });
-      } else
-      if (onlineprop != null) {
-         this.FillOnlineMenu(menu, onlineprop, itemname);
-      } else
-      if (fileprop != null) {
+      JSROOT.RegisterForResize(this);
 
-         var opts = JSROOT.getDrawOptions(cando.typename, 'nosame');
+      this.SetMonitoring(monitor);
 
-         menu.addDrawMenu("Draw", opts, function(arg) { painter.display(itemname, arg); });
+      function OpenAllFiles() {
+         if (filesarr.length>0)
+            hpainter.OpenRootFile(filesarr.shift(), OpenAllFiles);
+         else
+            hpainter.displayAll(itemsarr, optionsarr, function() {
+               hpainter.RefreshHtml();
 
-         var filepath = qualifyURL(fileprop.fileurl);
-         if (filepath.indexOf(JSROOT.source_dir) == 0)
-            filepath = filepath.slice(JSROOT.source_dir.length);
+               JSROOT.RegisterForResize(hpainter);
 
-         menu.addDrawMenu("Draw in new window", opts, function(arg) {
-            window.open(JSROOT.source_dir + "index.htm?nobrowser&file=" + filepath + "&item=" + fileprop.itemname+"&opt="+arg);
-         });
-      }
+               setInterval(function() { if (hpainter.IsMonitoring()) hpainter.updateAll(); }, hpainter.MonitoringInterval());
 
-      if (menu.size()>0) {
-         menu['tree_node'] = node;
-         menu.add("Close");
-         menu.show(event);
+               JSROOT.CallBack(call_back);
+            });
       }
 
-      return false;
-   }
+      function AfterOnlineOpened() {
+         // check if server enables monitoring
+         if (('_monitoring' in hpainter.h) && (monitor==null)) {
+            hpainter.SetMonitoring(hpainter.h._monitoring);
+         }
 
-   JSROOT.HierarchyPainter.prototype.SetDisplay = function(kind, frameid) {
-      this['disp_kind'] = kind;
-      this['disp_frameid'] = frameid;
-   }
+         if (('_layout' in hpainter.h) && (layout==null)) {
+            hpainter['disp_kind'] = hpainter.h._layout;
+         }
 
-   JSROOT.HierarchyPainter.prototype.clear = function(withbrowser) {
-      if ('disp' in this)
-         this['disp'].Reset();
+         if (('_loadfile' in hpainter.h) && (filesarr.length==0)) {
+            filesarr = JSROOT.ParseAsArray(hpainter.h._loadfile);
+         }
 
-      if (withbrowser) {
-         delete this['disp'];
-         $("#" + this.frameid).empty();
-         delete this.h;
+         if (('_drawitem' in hpainter.h) && (itemsarr.length==0)) {
+            itemsarr = JSROOT.ParseAsArray(hpainter.h._drawitem);
+            optionsarr = JSROOT.ParseAsArray(hpainter.h['_drawopt']);
+         }
+
+         OpenAllFiles();
       }
+
+      if (h0!=null) hpainter.OpenOnline(h0, AfterOnlineOpened);
+               else OpenAllFiles();
    }
 
-   JSROOT.HierarchyPainter.prototype.CreateDisplay = function(force) {
-      if ('disp' in this) {
-         if (!force && this['disp'].NumDraw() > 0) return this['disp'];
-         this['disp'].Reset();
-         delete this['disp'];
+   JSROOT.BuildNobrowserGUI = function() {
+      var myDiv = d3.select('#simpleGUI');
+      var online = false;
+
+      if (myDiv.empty()) {
+         myDiv = d3.select('#onlineGUI');
+         if (myDiv.empty()) return alert('no div for simple nobrowser gui found');
+         online = true;
       }
 
-      // check that we can found frame where drawing should be done
-      if (document.getElementById(this['disp_frameid']) == null) return null;
+      JSROOT.Painter.readStyleFromURL();
 
-      if (this['disp_kind'] == "tabs")
-         this['disp'] = new JSROOT.TabsDisplay(this['disp_frameid']);
-      else
-      if (this['disp_kind'].search("grid") == 0)
-         this['disp'] = new JSROOT.GridDisplay(this['disp_frameid'], this['disp_kind']);
-      else
-      if (this['disp_kind'] == "simple")
-         this['disp'] = new JSROOT.SimpleDisplay(this['disp_frameid']);
-      else
-         this['disp'] = new JSROOT.CollapsibleDisplay(this['disp_frameid']);
+      d3.select('html').style('height','100%');
+      d3.select('body').style({ 'min-height':'100%', 'margin':'0px', "overflow": "hidden"});
 
-      return this['disp'];
-   }
+      myDiv.style({"position":"absolute", "left":"1px", "top" :"1px", "bottom" :"1px", "right": "1px"});
 
-   JSROOT.HierarchyPainter.prototype.CheckResize = function(force) {
-      if ('disp' in this)
-         this['disp'].CheckResize();
+      var hpainter = new JSROOT.HierarchyPainter('root', null);
+      hpainter.SetDisplay('simple', myDiv.attr('id'));
+
+      var h0 = null;
+      if (online) {
+         var func = JSROOT.findFunction('GetCachedHierarchy');
+         if (typeof func == 'function') h0 = func();
+         if (typeof h0 != 'object') h0 = "";
+      }
+
+      hpainter.StartGUI(h0, function() {});
    }
 
    // ================================================================
@@ -8358,10 +7884,11 @@
 
    JSROOT.MDIDisplay = function(frameid) {
       this.frameid = frameid;
+      d3.select("#"+this.frameid).property('mdi', this);
    }
 
    JSROOT.MDIDisplay.prototype.ForEachFrame = function(userfunc, only_visible) {
-      // method dedicated to iterate over existing panles
+      // method dedicated to iterate over existing panels
       // provided userfunc is called with arguemnts (frame)
 
       alert("ForEachFrame not implemented");
@@ -8373,7 +7900,7 @@
 
       this.ForEachFrame(function(frame) {
          var dummy = new JSROOT.TObjectPainter();
-         dummy.SetDivId($(frame).attr('id'), -1);
+         dummy.SetDivId(d3.select(frame).attr('id'), -1);
          dummy.ForEachPainter(function(painter) { userfunc(painter, frame); });
       }, only_visible);
    }
@@ -8388,7 +7915,7 @@
       var found_frame = null;
 
       this.ForEachFrame(function(frame) {
-         if (frame.prop('title') == searchtitle)
+         if (d3.select(frame).attr('title') == searchtitle)
             found_frame = frame;
       });
 
@@ -8422,23 +7949,20 @@
             painter.Clenaup();
       });
 
-      document.getElementById(this.frameid).innerHTML = '';
+      d3.select("#"+this.frameid).html('').property('mdi', null);
    }
 
    JSROOT.MDIDisplay.prototype.Draw = function(title, obj, drawopt) {
       // draw object with specified options
       if (!obj) return;
 
-      var frame = this.FindFrame(title);
-
       if (!JSROOT.canDraw(obj['_typename'], drawopt)) return;
 
-      if (frame == null)
-         frame = this.CreateFrame(title);
+      var frame = this.FindFrame(title, true);
 
       this.ActivateFrame(frame);
 
-      return JSROOT.redraw($(frame).attr("id"), obj, drawopt);
+      return JSROOT.redraw(d3.select(frame).attr("id"), obj, drawopt);
    }
 
 
@@ -8451,169 +7975,22 @@
    JSROOT.SimpleDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
 
    JSROOT.SimpleDisplay.prototype.ForEachFrame = function(userfunc,  only_visible) {
-      if (typeof userfunc != 'function') return;
-      if ($("#"+this.frameid).prop('title')!='')
-         userfunc($("#"+this.frameid));
+      var node = d3.select("#"+this.frameid);
+      if (!node.empty() && node.property('title') != '')
+         JSROOT.CallBack(userfunc, node.node());
    }
 
    JSROOT.SimpleDisplay.prototype.CreateFrame = function(title) {
-      return $("#"+this.frameid).empty().prop('title', title);
+      return d3.select("#"+this.frameid).html("").property('title', title).node();
    }
 
    JSROOT.SimpleDisplay.prototype.Reset = function() {
       JSROOT.MDIDisplay.prototype.Reset.call(this);
       // try to remove different properties from the div
-      $("#"+this.frameid).prop('title','').css('background','')
-                         .removeClass('ui-droppable ui-state-default');
-   }
-
-   // ==================================================
-
-   JSROOT.CollapsibleDisplay = function(frameid) {
-      JSROOT.MDIDisplay.call(this, frameid);
-      this.cnt = 0; // use to count newly created frames
-   }
-
-   JSROOT.CollapsibleDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
-
-   JSROOT.CollapsibleDisplay.prototype.ForEachFrame = function(userfunc,  only_visible) {
-      var topid = this.frameid + '_collapsible';
-
-      if (document.getElementById(topid) == null) return;
-
-      if (typeof userfunc != 'function') return;
-
-      $('#' + topid + ' .collapsible_draw').each(function() {
-
-         // check if only visible specified
-         if (only_visible && $(this).is(":hidden")) return;
-
-         userfunc($(this));
-      });
-   }
-
-   JSROOT.CollapsibleDisplay.prototype.ActivateFrame = function(frame) {
-      if ($(frame).is(":hidden")) {
-         $(frame).prev().toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
-                 .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
-                 .next().toggleClass("ui-accordion-content-active").slideDown(0);
-      }
-      $(frame).prev()[0].scrollIntoView();
-   }
-
-   JSROOT.CollapsibleDisplay.prototype.CreateFrame = function(title) {
-
-      var topid = this.frameid + '_collapsible';
-
-      if (document.getElementById(topid) == null)
-         $("#right-div").append('<div id="'+ topid  + '" class="ui-accordion ui-accordion-icons ui-widget ui-helper-reset" style="overflow:auto; overflow-y:scroll; height:100%; padding-left: 2px; padding-right: 2px"></div>');
-
-      var hid = topid + "_sub" + this.cnt++;
-      var uid = hid + "h";
-
-      var entryInfo = "<h5 id=\"" + uid + "\"><a> " + title + "</a>&nbsp; </h5>\n";
-      entryInfo += "<div class='collapsible_draw' id='" + hid + "'></div>\n";
-      $("#" + topid).append(entryInfo);
-
-      $('#' + uid)
-            .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
-            .hover(function() { $(this).toggleClass("ui-state-hover"); })
-            .prepend('<span class="ui-icon ui-icon-triangle-1-e"></span>')
-            .append('<button type="button" class="closeButton" title="close canvas" '+
-                    'onclick="javascript: $(this).parent().next().andSelf().remove();">'+
-                    '<img class="img_remove" src="" alt=""/></button>')
-            .click( function() {
-                     $(this).toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
-                           .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s")
-                           .end().next().toggleClass("ui-accordion-content-active").slideToggle(0);
-                     return false;
-                  })
-            .next()
-            .addClass("ui-accordion-content  ui-helper-reset ui-widget-content ui-corner-bottom")
-            .hide();
-
-      $('#' + uid)
-            .toggleClass("ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
-            .find("> .ui-icon").toggleClass("ui-icon-triangle-1-e ui-icon-triangle-1-s").end().next()
-            .toggleClass("ui-accordion-content-active").slideToggle(0);
-
-      // $('#'+uid)[0].scrollIntoView();
-
-      $("#" + hid).prop('title', title);
-
-      return $("#" + hid);
-   }
-
-   // ================================================
-
-   JSROOT.TabsDisplay = function(frameid) {
-      JSROOT.MDIDisplay.call(this, frameid);
-      this.cnt = 0;
-   }
-
-   JSROOT.TabsDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
-
-   JSROOT.TabsDisplay.prototype.ForEachFrame = function(userfunc, only_visible) {
-      var topid = this.frameid + '_tabs';
-
-      if (document.getElementById(topid) == null) return;
-
-      if (typeof userfunc != 'function') return;
-
-      var cnt = -1;
-      var active = $('#' + topid).tabs("option", "active");
-
-      $('#' + topid + ' .tabs_draw').each(function() {
-         // check if only_visible specified
-         if (only_visible && (cnt++ != active)) return;
-
-         userfunc($(this));
-      });
-   }
-
-   JSROOT.TabsDisplay.prototype.ActivateFrame = function(frame) {
-      var cnt = 0, id = -1;
-      this.ForEachFrame(function(fr) {
-         if ($(fr).attr('id') == frame.attr('id'))  id = cnt;
-         cnt++;
-      });
-
-      $('#' + this.frameid + "_tabs").tabs("option", "active", id);
-   }
-
-   JSROOT.TabsDisplay.prototype.CreateFrame = function(title) {
-      var topid = this.frameid + '_tabs';
-
-      var hid = topid + "_sub" + this.cnt++;
-
-      var li = '<li><a href="#' + hid + '">' + title
-            + '</a><span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>';
-      var cont = '<div class="tabs_draw" id="' + hid + '"></div>';
-
-      if (document.getElementById(topid) == null) {
-         $("#" + this.frameid).append('<div id="' + topid + '">' + ' <ul>' + li + ' </ul>' + cont + '</div>');
-
-         var tabs = $("#" + topid)
-                       .css('overflow','hidden')
-                       .tabs({ heightStyle : "fill" });
-
-         tabs.delegate("span.ui-icon-close", "click", function() {
-            var panelId = $(this).closest("li").remove().attr("aria-controls");
-            $("#" + panelId).remove();
-            tabs.tabs("refresh");
-         });
-      } else {
-
-         // var tabs = $("#tabs").tabs();
-
-         $("#" + topid).find(".ui-tabs-nav").append(li);
-         $("#" + topid).append(cont);
-         $("#" + topid).tabs("refresh");
-         $("#" + topid).tabs("option", "active", -1);
-      }
-      $('#' + hid).empty();
-      $('#' + hid).prop('title', title);
-      return $('#' + hid);
+      d3.select("#"+this.frameid)
+              .property('title','')
+              .style('background','')
+              .classed({'ui-droppable':false, 'ui-state-default':false});
    }
 
    // ================================================
@@ -8641,16 +8018,12 @@
             sizey = sizex;
          }
 
-         if (sizex == NaN)
-            sizex = 3;
-         if (sizey == NaN)
-            sizey = 3;
+         if (sizex == NaN) sizex = 3;
+         if (sizey == NaN) sizey = 3;
       }
 
-      if (!sizex)
-         sizex = 3;
-      if (!sizey)
-         sizey = sizex;
+      if (!sizex) sizex = 3;
+      if (!sizey) sizey = sizex;
       this.sizex = sizex;
       this.sizey = sizey;
    }
@@ -8658,44 +8031,29 @@
    JSROOT.GridDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
 
    JSROOT.GridDisplay.prototype.IsSingle = function() {
-      return (this.sizex <= 1) && (this.sizey <= 1);
+      return (this.sizex == 1) && (this.sizey == 1);
    }
 
    JSROOT.GridDisplay.prototype.ForEachFrame = function(userfunc, only_visible) {
-      if (typeof userfunc != 'function') return;
-
-      if (this.IsSingle()) {
-         var elem = $("#"+this.frameid);
-         if (elem.prop('title')!=null)
-            userfunc(elem);
-         return;
-      }
-
-      var topid = this.frameid + '_grid';
-
-      if (document.getElementById(topid) == null) return;
-
       for (var cnt = 0; cnt < this.sizex * this.sizey; cnt++) {
+         var elem = this.IsSingle() ? d3.select("#"+this.frameid) : d3.select("#" + this.frameid + "_grid_" + cnt);
 
-         var elem = $( "#" + topid + "_" + cnt);
-
-         if (elem.prop('title')!="")
-            userfunc(elem);
+         if (!elem.empty() && elem.property('title') != '')
+            JSROOT.CallBack(userfunc, elem.node());
       }
    }
 
    JSROOT.GridDisplay.prototype.CreateFrame = function(title) {
 
-      var hid = this.frameid;
+      var main = d3.select("#" + this.frameid);
+      if (main.empty()) return null;
 
       if (!this.IsSingle()) {
          var topid = this.frameid + '_grid';
-         if (document.getElementById(topid) == null) {
-
-            var main = $("#" + this.frameid);
-
-            var h = Math.floor(main.height() / this.sizey) - 1;
-            var w = Math.floor(main.width() / this.sizex) - 1;
+         if (d3.select("#" + topid).empty()) {
+            var rect = main.node().getBoundingClientRect();
+            var h = Math.floor(rect.height / this.sizey) - 1;
+            var w = Math.floor(rect.width / this.sizex) - 1;
 
             var content = "<div style='width:100%; height:100%; margin:0; padding:0; border:0; overflow:hidden'>";
                content += "<table id='" + topid + "' style='width:100%; height:100%; table-layout:fixed; border-collapse: collapse;'>";
@@ -8703,79 +8061,44 @@
             for (var i = 0; i < this.sizey; i++) {
                content += "<tr>";
                for (var j = 0; j < this.sizex; j++)
-                  content += "<td><div id='" + topid + "_" + cnt++ + "'></div></td>";
+                  content += "<td><div id='" + topid + "_" + cnt++ + "' class='grid_cell'></div></td>";
                content += "</tr>";
             }
             content += "</table></div>";
 
-            main.empty();
-            main.append(content);
-
-            main.find("[id^=" + this.frameid + "_grid_]").width(w).height(h);
-//              .droppable({ accepted: ".h_item", drop: function(event, ui) { console.log("drop!"); } });
+            main.html(content);
+            main.selectAll('.grid_cell').style({ 'width':  w + 'px', 'height': h + 'px'});
          }
 
-         hid = topid + "_" + this.cnt;
+         main = d3.select( "#" + topid + "_" + this.cnt);
          if (++this.cnt >= this.sizex * this.sizey) this.cnt = 0;
       }
 
-      $("#" + hid).empty();
-      $("#" + hid).prop('title', title);
-
-      return $('#' + hid);
+      return main.html("").property('title', title).node();
    }
 
    JSROOT.GridDisplay.prototype.Reset = function() {
       JSROOT.MDIDisplay.prototype.Reset.call(this);
       if (this.IsSingle())
-         $("#" + this.frameid).prop('title', null);
+         d3.select("#" + this.frameid).property('title', null);
       this.cnt = 0;
    }
 
    JSROOT.GridDisplay.prototype.CheckResize = function() {
 
-      var main = $("#" + this.frameid);
-
-      var h = Math.floor(main.height() / this.sizey) - 1;
-      var w = Math.floor(main.width() / this.sizex) - 1;
-
-      main.find("[id^=" + this.frameid + "_grid_]").height(h).width(w);
+      if (!this.IsSingle()) {
+         var main = d3.select("#" + this.frameid);
+         var rect = main.node().getBoundingClientRect();
+         var h = Math.floor(rect.height / this.sizey) - 1;
+         var w = Math.floor(rect.width / this.sizex) - 1;
+         main.selectAll('.grid_cell').style({ 'width':  w + 'px', 'height': h + 'px'});
+      }
 
       JSROOT.MDIDisplay.prototype.CheckResize.call(this);
    }
 
    // =========================================================================
 
-   JSROOT.ConfigureVSeparator = function(handle, leftdiv, separdiv, rightdiv) {
-      if (!leftdiv) leftdiv = "left-div";
-      if (!separdiv) separdiv = "separator-div";
-      if (!rightdiv) rightdiv = "right-div";
-
-      function adjustSize(left, firsttime) {
-         var diff = $("#"+leftdiv).outerWidth() - $("#"+leftdiv).width();
-         var w = JSROOT.touches ? 10 : 4;
-
-         $("#"+separdiv).css('left', left.toString() + "px").width(w);
-         $("#"+leftdiv).width(left-diff-1);
-         $("#"+rightdiv).css('left',(left+w).toString() + "px");
-         if (firsttime || (handle==null)) return;
-
-         if (typeof handle == 'function') handle(); else
-         if ((typeof handle == 'object') && (typeof handle['CheckResize'] == 'function')) handle.CheckResize();
-      }
-
-      $("#"+separdiv).draggable({
-         axis: "x" , zIndex: 100, cursor: "ew-resize",
-         helper : function() { return $("#"+separdiv).clone().css('background-color','grey'); },
-         stop: function(event,ui) { event.stopPropagation(); adjustSize(ui.position.left, false); }
-      });
-
-      var w0 = Math.round($(window).width() * 0.2);
-      if (w0<300) w0 = Math.min(300, Math.round($(window).width() * 0.5));
-
-      adjustSize(w0, true);
-   }
-
    JSROOT.RegisterForResize = function(handle, delay) {
       // function used to react on browser window resize event
       // While many resize events could come in short time,
@@ -8803,7 +8126,26 @@
 
          document.body.style.cursor = 'wait';
          if (typeof handle == 'function') handle(); else
-         if ((typeof handle == 'object') && (typeof handle['CheckResize'] == 'function')) handle.CheckResize();
+         if ((typeof handle == 'object') && (typeof handle['CheckResize'] == 'function')) handle.CheckResize(); else
+         if (typeof handle == 'string') {
+            var node = d3.select('#'+handle);
+            if (!node.empty()) {
+               var mdi = node.property('mdi');
+               if (mdi) {
+                  mdi.CheckResize();
+               } else {
+                  var dummy = new JSROOT.TObjectPainter();
+                  var first = true;
+                  dummy.SetDivId(handle, -1);
+                  dummy.ForEachPainter(function(painter) {
+                     if (first && (typeof painter['CheckResize'] == 'function')) {
+                        first = false;
+                        painter.CheckResize();
+                     }
+                  });
+               }
+            }
+         }
          document.body.style.cursor = 'auto';
       }
 
@@ -8926,7 +8268,7 @@
       if (obj==null) return;
 
       var can = d3.select("#" + divid + " .root_canvas");
-      var can_painter = can.node() ? can.node()['pad_painter'] : null;
+      var can_painter = can.empty() ? null : can.property('pad_painter');
 
       if (can_painter != null) {
          if (obj._typename=="TCanvas") {
@@ -8948,7 +8290,7 @@
       if (can_painter)
           console.log("Cannot find painter to update object of type " + obj._typename);
 
-      $("#"+divid).empty();
+      d3.select("#"+divid).html("");
       return JSROOT.draw(divid, obj, opt);
    }
 

From 7229a27231a4447fd18d70564a4f290e43d40cc6 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Fri, 27 Feb 2015 08:36:30 +0100
Subject: [PATCH 087/200] http: sync with JSROOT changes

Specify prerequisities for tree player.
It is jquery-based, therefore JSROOT
should load appropriate scripts before

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 net/http/src/TRootSniffer.cxx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/http/src/TRootSniffer.cxx b/net/http/src/TRootSniffer.cxx
index 6a388af2ad597..8b6782a28c0eb 100644
--- a/net/http/src/TRootSniffer.cxx
+++ b/net/http/src/TRootSniffer.cxx
@@ -480,7 +480,10 @@ void TRootSniffer::ScanObjectChilds(TRootSnifferScanRec &rec, TObject *obj)
       TDirectory *dir = (TDirectory *) obj;
       ScanCollection(rec, dir->GetList(), 0, dir->GetListOfKeys());
    } else if (obj->InheritsFrom(TTree::Class())) {
-      if (!fReadOnly) rec.SetField("_player", "JSROOT.drawTreePlayer");
+      if (!fReadOnly) {
+         rec.SetField("_player", "JSROOT.drawTreePlayer");
+         rec.SetField("_prereq", "jq2d");
+      }
       ScanCollection(rec, ((TTree *) obj)->GetListOfLeaves());
    } else if (obj->InheritsFrom(TBranch::Class())) {
       ScanCollection(rec, ((TBranch *) obj)->GetListOfLeaves());

From 71e133dd0391deac1cf3761d2c5c253b3cb247ff Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Fri, 27 Feb 2015 10:57:02 +0100
Subject: [PATCH 088/200] Survive #pragma once from virtual file.

---
 interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp b/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp
index 41f0cf21f0d4f..39282323bfb41 100644
--- a/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp
+++ b/interpreter/llvm/src/tools/clang/lib/Lex/Pragma.cpp
@@ -354,9 +354,11 @@ void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
     return;
   }
 
-  // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
-  // Mark the file as a once-only file now.
-  HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
+  if (getCurrentFileLexer()->getFileEntry()) {
+    // Get the current file lexer we're looking at.  Ignore _Pragma 'files' etc.
+    // Mark the file as a once-only file now.
+    HeaderInfo.MarkFileIncludeOnce(getCurrentFileLexer()->getFileEntry());
+  }
 }
 
 void Preprocessor::HandlePragmaMark() {

From e530c2e33703859058f0594082932a17da195bfc Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Fri, 27 Feb 2015 10:58:35 +0100
Subject: [PATCH 089/200] Test for ROOT-7113: pragma once on prompt.

---
 interpreter/cling/test/Prompt/cppmacros.C | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/interpreter/cling/test/Prompt/cppmacros.C b/interpreter/cling/test/Prompt/cppmacros.C
index 670b2ab0a6c11..cc1aa0195c479 100644
--- a/interpreter/cling/test/Prompt/cppmacros.C
+++ b/interpreter/cling/test/Prompt/cppmacros.C
@@ -18,3 +18,5 @@ void cppmacros() {
 }
 
 #pragma clang diagnostic ignored "-Wkeyword-compat" // ROOT-6531
+
+#pragma once // ROOT-7113

From 629a497680c04fa269bd85a9605f6a6171faaa88 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 27 Feb 2015 13:30:29 +0100
Subject: [PATCH 090/200] Support IO of forward_list as a proxied collection

---
 core/cont/inc/TCollectionProxyInfo.h     | 54 +++++++++++++++++++++++-
 core/meta/inc/TDictionary.h              | 19 +++++----
 core/meta/inc/TStreamerElement.h         | 21 ++++-----
 core/meta/src/TBaseClass.cxx             | 19 +++++----
 core/meta/src/TCling.cxx                 |  9 ++--
 core/meta/src/TStreamerElement.cxx       | 34 ++++++++-------
 core/metautils/CMakeLists.txt            |  2 +-
 core/metautils/Module.mk                 |  3 +-
 core/metautils/inc/ESTLType.h            | 25 +++++------
 core/metautils/inc/TClassEdit.h          | 21 ++++-----
 core/metautils/src/TClassEdit.cxx        | 11 +++--
 core/metautils/src/TMetaUtils.cxx        | 10 +++--
 core/metautils/src/forward_listLinkdef.h | 15 +++++++
 core/metautils/src/listLinkdef.h         |  1 +
 core/utils/src/rootcling.cxx             |  4 +-
 io/io/src/TGenCollectionProxy.cxx        |  2 +
 io/io/src/TGenCollectionStreamer.cxx     |  6 +++
 io/io/src/TMakeProject.cxx               |  4 ++
 io/xml/src/TXMLPlayer.cxx                | 15 ++++---
 net/http/src/TBufferJSON.cxx             |  4 +-
 20 files changed, 189 insertions(+), 90 deletions(-)
 create mode 100644 core/metautils/src/forward_listLinkdef.h

diff --git a/core/cont/inc/TCollectionProxyInfo.h b/core/cont/inc/TCollectionProxyInfo.h
index 350b73e218ab1..1c7abe57c2ac2 100644
--- a/core/cont/inc/TCollectionProxyInfo.h
+++ b/core/cont/inc/TCollectionProxyInfo.h
@@ -23,6 +23,7 @@
 #include "TError.h"
 #endif
 #include <vector>
+#include <forward_list>
 
 #if defined(_WIN32)
    #if _MSC_VER<1300
@@ -250,6 +251,19 @@ namespace ROOT {
       }
    };
 
+   struct SfinaeHelper {
+      // Use SFINAE to get the size of the container
+
+      // In general we get the size of the container with the size method
+      template <class T>
+      static size_t GetContainerSize(const T& c) {return c.size();}
+
+      // Since forward_list does not provide a size operator, we have to
+      // use an alternative. This has a cost of course.
+      template <class T, class ALLOCATOR>
+      static size_t GetContainerSize(const std::forward_list<T,ALLOCATOR>& c) {return std::distance(c.begin(),c.end());}
+   };
+
    /** @class TCollectionProxyInfo::Type TCollectionProxyInfo.h TCollectionProxyInfo.h
     *
     * Small helper to encapsulate basic data accesses for
@@ -277,7 +291,7 @@ namespace ROOT {
       }
       static void* size(void* env)  {
          PEnv_t  e = PEnv_t(env);
-         e->fSize   = PCont_t(e->fObject)->size();
+         e->fSize   = SfinaeHelper::GetContainerSize(*PCont_t(e->fObject));
          return &e->fSize;
       }
       static void* clear(void* env)  {
@@ -292,7 +306,7 @@ namespace ROOT {
          ::new(e->buff) Iter_t(c->begin());
 #endif
          e->fIterator = c->begin();
-         e->fSize  = c->size();
+         e->fSize  = SfinaeHelper::GetContainerSize(*c);
          if ( 0 == e->fSize ) return e->fStart = 0;
          TYPENAME T::const_reference ref = *(e->iter());
          return e->fStart = Type<T>::address(ref);
@@ -363,6 +377,42 @@ namespace ROOT {
       }
    };
 
+   /** @class TCollectionProxyInfo::Pushfront TCollectionProxyInfo.h TCollectionProxyInfo.h
+    *
+    * Small helper to encapsulate all necessary data accesses for
+    * containers like forward_list
+    *
+    * @author  D.Piparo
+    * @version 1.0
+    * @date    26/02/2015
+    */
+   template <class T> struct Pushfront : public Type<T> {
+      typedef T                      Cont_t;
+      typedef typename T::iterator   Iter_t;
+      typedef typename T::value_type Value_t;
+      typedef Environ<Iter_t>        Env_t;
+      typedef Env_t                 *PEnv_t;
+      typedef Cont_t                *PCont_t;
+      typedef Value_t               *PValue_t;
+      static void resize(void* obj, size_t n) {
+         PCont_t c = PCont_t(obj);
+         c->resize(n);
+      }
+      static void* feed(void *from, void *to, size_t size)  {
+         PCont_t  c = PCont_t(to);
+         if (size==0) return 0;
+         PValue_t m = &(PValue_t(from)[size-1]); // Take the last item
+         // Iterate backwards not to revert ordering
+         for (size_t i=0; i<size; ++i, --m){
+            c->push_front(*m);
+         }
+         return 0;
+      }
+      static int value_offset()  {
+         return 0;
+      }
+   };
+
    /** @class TCollectionProxyInfo::Map TCollectionProxyInfo.h TCollectionProxyInfo.h
     *
     * Small helper to encapsulate all necessary data accesses for
diff --git a/core/meta/inc/TDictionary.h b/core/meta/inc/TDictionary.h
index 9e5f8c7bb79ba..911d52c65cae3 100644
--- a/core/meta/inc/TDictionary.h
+++ b/core/meta/inc/TDictionary.h
@@ -190,15 +190,16 @@ class TDictionary : public TNamed {
 
    // Type of STL container (returned by IsSTLContainer).
    enum ESTLType {
-      kNone      = ROOT::kNotSTL,
-      kVector    = ROOT::kSTLvector,
-      kList      = ROOT::kSTLlist,
-      kDeque     = ROOT::kSTLdeque,
-      kMap       = ROOT::kSTLmap,
-      kMultimap  = ROOT::kSTLmultimap,
-      kSet       = ROOT::kSTLset,
-      kMultiset  = ROOT::kSTLmultiset,
-      kBitset    = ROOT::kSTLbitset
+      kNone        = ROOT::kNotSTL,
+      kVector      = ROOT::kSTLvector,
+      kList        = ROOT::kSTLlist,
+      kForwardlist = ROOT::kSTLforwardlist,
+      kDeque       = ROOT::kSTLdeque,
+      kMap         = ROOT::kSTLmap,
+      kMultimap    = ROOT::kSTLmultimap,
+      kSet         = ROOT::kSTLset,
+      kMultiset    = ROOT::kSTLmultiset,
+      kBitset      = ROOT::kSTLbitset
    };
 
    typedef const void *DeclId_t;
diff --git a/core/meta/inc/TStreamerElement.h b/core/meta/inc/TStreamerElement.h
index 982b1431a6cb9..3b6f5ca572537 100644
--- a/core/meta/inc/TStreamerElement.h
+++ b/core/meta/inc/TStreamerElement.h
@@ -59,16 +59,17 @@ class TStreamerElement : public TNamed {
 public:
 
    enum ESTLtype {
-      kSTL         = ROOT::kSTLany,
-      kSTLstring   = ROOT::kSTLstring,
-      kSTLvector   = ROOT::kSTLvector,
-      kSTLlist     = ROOT::kSTLlist,
-      kSTLdeque    = ROOT::kSTLdeque,
-      kSTLmap      = ROOT::kSTLmap,
-      kSTLmultimap = ROOT::kSTLmultimap,
-      kSTLset      = ROOT::kSTLset,
-      kSTLmultiset = ROOT::kSTLmultiset,
-      kSTLbitset   = ROOT::kSTLbitset
+      kSTL            = ROOT::kSTLany,
+      kSTLstring      = ROOT::kSTLstring,
+      kSTLvector      = ROOT::kSTLvector,
+      kSTLlist        = ROOT::kSTLlist,
+      kSTLforwardlist = ROOT::kSTLforwardlist,
+      kSTLdeque       = ROOT::kSTLdeque,
+      kSTLmap         = ROOT::kSTLmap,
+      kSTLmultimap    = ROOT::kSTLmultimap,
+      kSTLset         = ROOT::kSTLset,
+      kSTLmultiset    = ROOT::kSTLmultiset,
+      kSTLbitset      = ROOT::kSTLbitset
    };
    // TStreamerElement status bits
    enum {
diff --git a/core/meta/src/TBaseClass.cxx b/core/meta/src/TBaseClass.cxx
index 2d09842b6d7f3..89428be6dfe7f 100644
--- a/core/meta/src/TBaseClass.cxx
+++ b/core/meta/src/TBaseClass.cxx
@@ -110,15 +110,16 @@ ROOT::ESTLType TBaseClass::IsSTLContainer()
          fSTLType = -2;
       } else {
          const char *type = gCling->BaseClassInfo_TmpltName(fInfo);
-         if (!type)                          fSTLType = ROOT::kNotSTL;
-         else if (!strcmp(type, "vector"))   fSTLType = ROOT::kSTLvector;
-         else if (!strcmp(type, "list"))     fSTLType = ROOT::kSTLlist;
-         else if (!strcmp(type, "deque"))    fSTLType = ROOT::kSTLdeque;
-         else if (!strcmp(type, "map"))      fSTLType = ROOT::kSTLmap;
-         else if (!strcmp(type, "multimap")) fSTLType = ROOT::kSTLmultimap;
-         else if (!strcmp(type, "set"))      fSTLType = ROOT::kSTLset;
-         else if (!strcmp(type, "multiset")) fSTLType = ROOT::kSTLmultiset;
-         else                                fSTLType = ROOT::kNotSTL;
+         if (!type)                             fSTLType = ROOT::kNotSTL;
+         else if (!strcmp(type, "vector"))      fSTLType = ROOT::kSTLvector;
+         else if (!strcmp(type, "list"))        fSTLType = ROOT::kSTLlist;
+         else if (!strcmp(type, "forward_list"))fSTLType = ROOT::kSTLforwardlist;
+         else if (!strcmp(type, "deque"))       fSTLType = ROOT::kSTLdeque;
+         else if (!strcmp(type, "map"))         fSTLType = ROOT::kSTLmap;
+         else if (!strcmp(type, "multimap"))    fSTLType = ROOT::kSTLmultimap;
+         else if (!strcmp(type, "set"))         fSTLType = ROOT::kSTLset;
+         else if (!strcmp(type, "multiset"))    fSTLType = ROOT::kSTLmultiset;
+         else                                   fSTLType = ROOT::kNotSTL;
       }
    }
    if (fSTLType == -2) return ROOT::kNotSTL;
diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index 9aae2599fa237..ff8f6d25e495d 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -1214,7 +1214,7 @@ bool TCling::LoadPCM(TString pcmFileName,
       }
 
       TDirectory::TContext ctxt(0);
-      
+
       TFile *pcmFile = new TFile(pcmFileName+"?filetype=pcm","READ");
 
       auto listOfKeys = pcmFile->GetListOfKeys();
@@ -1227,9 +1227,9 @@ bool TCling::LoadPCM(TString pcmFileName,
       }
 
       TObjArray *protoClasses;
-      if (gDebug > 1) 
+      if (gDebug > 1)
             ::Info("TCling::LoadPCM","reading protoclasses for %s \n",pcmFileName.Data());
-      
+
       pcmFile->GetObject("__ProtoClasses", protoClasses);
 
       if (protoClasses) {
@@ -1607,7 +1607,8 @@ void TCling::RegisterModule(const char* modulename,
    if (strcmp(modulename,"libCore")!=0 && strcmp(modulename,"libRint")!=0
        && strcmp(modulename,"libThread")!=0 && strcmp(modulename,"libRIO")!=0
        && strcmp(modulename,"libcomplexDict")!=0 && strcmp(modulename,"libdequeDict")!=0
-       && strcmp(modulename,"liblistDict")!=0 && strcmp(modulename,"libvectorDict")!=0
+       && strcmp(modulename,"liblistDict")!=0 && strcmp(modulename,"libforward_listDict")!=0
+       && strcmp(modulename,"libvectorDict")!=0
        && strcmp(modulename,"libmapDict")!=0 && strcmp(modulename,"libmultimap2Dict")!=0
        && strcmp(modulename,"libmap2Dict")!=0 && strcmp(modulename,"libmultimapDict")!=0
        && strcmp(modulename,"libsetDict")!=0 && strcmp(modulename,"libmultisetDict")!=0
diff --git a/core/meta/src/TStreamerElement.cxx b/core/meta/src/TStreamerElement.cxx
index 506b45864cb9f..198792fd62cca 100644
--- a/core/meta/src/TStreamerElement.cxx
+++ b/core/meta/src/TStreamerElement.cxx
@@ -1693,14 +1693,15 @@ TStreamerSTL::TStreamerSTL(const char *name, const char *title, Int_t offset,
    fCtype   = 0;
    // Any class name that 'contains' the word will be counted
    // as a STL container. Is that really what we want.
-   if      (strstr(s,"vector"))   fSTLtype = ROOT::kSTLvector;
-   else if (strstr(s,"list"))     fSTLtype = ROOT::kSTLlist;
-   else if (strstr(s,"deque"))    fSTLtype = ROOT::kSTLdeque;
-   else if (strstr(s,"multimap")) fSTLtype = ROOT::kSTLmultimap;
-   else if (strstr(s,"multiset")) fSTLtype = ROOT::kSTLmultiset;
-   else if (strstr(s,"bitset"))   fSTLtype = ROOT::kSTLbitset;
-   else if (strstr(s,"map"))      fSTLtype = ROOT::kSTLmap;
-   else if (strstr(s,"set"))      fSTLtype = ROOT::kSTLset;
+   if      (strstr(s,"vector"))            fSTLtype = ROOT::kSTLvector;
+   else if (strstr(s,"list"))              fSTLtype = ROOT::kSTLlist;
+   else if (strstr(s,"forward_list"))      fSTLtype = ROOT::kSTLforwardlist;
+   else if (strstr(s,"deque"))             fSTLtype = ROOT::kSTLdeque;
+   else if (strstr(s,"multimap"))          fSTLtype = ROOT::kSTLmultimap;
+   else if (strstr(s,"multiset"))          fSTLtype = ROOT::kSTLmultiset;
+   else if (strstr(s,"bitset"))            fSTLtype = ROOT::kSTLbitset;
+   else if (strstr(s,"map"))               fSTLtype = ROOT::kSTLmap;
+   else if (strstr(s,"set"))               fSTLtype = ROOT::kSTLset;
    if (fSTLtype == 0) { delete [] s; return;}
    if (dmPointer) fSTLtype += TVirtualStreamerInfo::kOffsetP;
 
@@ -1852,14 +1853,15 @@ const char *TStreamerSTL::GetInclude() const
 {
    // Return the proper include for this element.
 
-   if      (fSTLtype == ROOT::kSTLvector)   IncludeNameBuffer().Form("<%s>","vector");
-   else if (fSTLtype == ROOT::kSTLlist)     IncludeNameBuffer().Form("<%s>","list");
-   else if (fSTLtype == ROOT::kSTLdeque)    IncludeNameBuffer().Form("<%s>","deque");
-   else if (fSTLtype == ROOT::kSTLmap)      IncludeNameBuffer().Form("<%s>","map");
-   else if (fSTLtype == ROOT::kSTLset)      IncludeNameBuffer().Form("<%s>","set");
-   else if (fSTLtype == ROOT::kSTLmultimap) IncludeNameBuffer().Form("<%s>","map");
-   else if (fSTLtype == ROOT::kSTLmultiset) IncludeNameBuffer().Form("<%s>","set");
-   else if (fSTLtype == ROOT::kSTLbitset)   IncludeNameBuffer().Form("<%s>","bitset");
+   if      (fSTLtype == ROOT::kSTLvector)      IncludeNameBuffer().Form("<%s>","vector");
+   else if (fSTLtype == ROOT::kSTLlist)        IncludeNameBuffer().Form("<%s>","list");
+   else if (fSTLtype == ROOT::kSTLforwardlist) IncludeNameBuffer().Form("<%s>","forward_list");
+   else if (fSTLtype == ROOT::kSTLdeque)       IncludeNameBuffer().Form("<%s>","deque");
+   else if (fSTLtype == ROOT::kSTLmap)         IncludeNameBuffer().Form("<%s>","map");
+   else if (fSTLtype == ROOT::kSTLset)         IncludeNameBuffer().Form("<%s>","set");
+   else if (fSTLtype == ROOT::kSTLmultimap)    IncludeNameBuffer().Form("<%s>","map");
+   else if (fSTLtype == ROOT::kSTLmultiset)    IncludeNameBuffer().Form("<%s>","set");
+   else if (fSTLtype == ROOT::kSTLbitset)      IncludeNameBuffer().Form("<%s>","bitset");
    return IncludeNameBuffer();
 }
 
diff --git a/core/metautils/CMakeLists.txt b/core/metautils/CMakeLists.txt
index 4162fa9421d31..202872c9d0e8b 100644
--- a/core/metautils/CMakeLists.txt
+++ b/core/metautils/CMakeLists.txt
@@ -30,7 +30,7 @@ ROOT_INSTALL_HEADERS()
 
 #### STL dictionary (replacement for cintdlls)##############################
 
-set(stldicts vector list deque map map2 set multimap multimap2 multiset complex)
+set(stldicts vector list forward_list deque map map2 set multimap multimap2 multiset complex)
 if(NOT WIN32)
   list(APPEND stldicts valarray)
 endif()
diff --git a/core/metautils/Module.mk b/core/metautils/Module.mk
index d9e3db691505d..3647bd47dece5 100644
--- a/core/metautils/Module.mk
+++ b/core/metautils/Module.mk
@@ -54,6 +54,7 @@ INCLUDEFILES += $(METAUTILSDEP)
 STLDICTS =
 STLDICTS += lib/libvectorDict.$(SOEXT)
 STLDICTS += lib/liblistDict.$(SOEXT)
+STLDICTS += lib/libforward_listDict.$(SOEXT)
 STLDICTS += lib/libdequeDict.$(SOEXT)
 STLDICTS += lib/libmapDict.$(SOEXT)
 STLDICTS += lib/libmap2Dict.$(SOEXT)
@@ -91,7 +92,7 @@ STLDICTSMAPS = $(STLDICTS:.$(SOEXT)=.rootmap)
 # used in the main Makefile
 ALLLIBS    += $(STLDICTS)
 ALLMAPS    += $(STLDICTSMAPS)
-   
+
 ##### local rules #####
 .PHONY:         all-$(MODNAME) clean-$(MODNAME) distclean-$(MODNAME)
 
diff --git a/core/metautils/inc/ESTLType.h b/core/metautils/inc/ESTLType.h
index fdc4ad43e3d0e..a9c491ca77f48 100644
--- a/core/metautils/inc/ESTLType.h
+++ b/core/metautils/inc/ESTLType.h
@@ -26,18 +26,19 @@
 namespace ROOT {
 
    enum ESTLType {
-      kNotSTL      = 0,
-      kSTLvector   = 1,
-      kSTLlist     = 2,
-      kSTLdeque    = 3,
-      kSTLmap      = 4,
-      kSTLmultimap = 5,
-      kSTLset      = 6,
-      kSTLmultiset = 7,
-      kSTLbitset   = 8,
-      kSTLend      = 9,
-      kSTLany      = 300 /* TVirtualStreamerInfo::kSTL */,
-      kSTLstring   = 365 /* TVirtualStreamerInfo::kSTLstring */
+      kNotSTL         = 0,
+      kSTLvector      = 1,
+      kSTLlist        = 2,
+      kSTLforwardlist = 3,
+      kSTLdeque       = 4,
+      kSTLmap         = 5,
+      kSTLmultimap    = 6,
+      kSTLset         = 7,
+      kSTLmultiset    = 8,
+      kSTLbitset      = 9,
+      kSTLend         = 10,
+      kSTLany         = 300 /* TVirtualStreamerInfo::kSTL */,
+      kSTLstring      = 365 /* TVirtualStreamerInfo::kSTLstring */
    };
 
 }
diff --git a/core/metautils/inc/TClassEdit.h b/core/metautils/inc/TClassEdit.h
index 44ec920b6b4b6..08838346ef069 100644
--- a/core/metautils/inc/TClassEdit.h
+++ b/core/metautils/inc/TClassEdit.h
@@ -88,16 +88,17 @@ namespace TClassEdit {
    };
 
    enum ESTLType {
-      kNotSTL   = ROOT::kNotSTL,
-      kVector   = ROOT::kSTLvector,
-      kList     = ROOT::kSTLlist,
-      kDeque    = ROOT::kSTLdeque,
-      kMap      = ROOT::kSTLmap,
-      kMultiMap = ROOT::kSTLmultimap,
-      kSet      = ROOT::kSTLset,
-      kMultiSet = ROOT::kSTLmultiset,
-      kBitSet   = ROOT::kSTLbitset,
-      kEnd      = ROOT::kSTLend
+      kNotSTL     = ROOT::kNotSTL,
+      kVector     = ROOT::kSTLvector,
+      kList       = ROOT::kSTLlist,
+      kForwardist = ROOT::kSTLforwardlist,
+      kDeque      = ROOT::kSTLdeque,
+      kMap        = ROOT::kSTLmap,
+      kMultiMap   = ROOT::kSTLmultimap,
+      kSet        = ROOT::kSTLset,
+      kMultiSet   = ROOT::kSTLmultiset,
+      kBitSet     = ROOT::kSTLbitset,
+      kEnd        = ROOT::kSTLend
    };
 
    class TInterpreterLookupHelper {
diff --git a/core/metautils/src/TClassEdit.cxx b/core/metautils/src/TClassEdit.cxx
index c8939ea756ddf..e2a70fb9e6305 100644
--- a/core/metautils/src/TClassEdit.cxx
+++ b/core/metautils/src/TClassEdit.cxx
@@ -138,7 +138,7 @@ int TClassEdit::TSplitType::IsSTLCont(int testAlloc) const
 
    int kind = STLKind(fElements[0].c_str());
 
-   if (kind==ROOT::kSTLvector || kind==ROOT::kSTLlist ) {
+   if (kind==ROOT::kSTLvector || kind==ROOT::kSTLlist || kind==ROOT::kSTLforwardlist) {
 
       int nargs = STLArgs(kind);
       if (testAlloc && (numb-1 > nargs) && !IsDefAlloc(fElements[numb-1].c_str(),fElements[1].c_str())) {
@@ -244,6 +244,7 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
                switch (kind) {
                   case ROOT::kSTLvector:
                   case ROOT::kSTLlist:
+                  case ROOT::kSTLforwardlist:
                   case ROOT::kSTLdeque:
                   case ROOT::kSTLset:
                   case ROOT::kSTLmultiset:
@@ -277,6 +278,7 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
          switch (kind) {
             case ROOT::kSTLvector:
             case ROOT::kSTLlist:
+            case ROOT::kSTLforwardlist:
             case ROOT::kSTLdeque:
                break;
             case ROOT::kSTLset:
@@ -410,12 +412,13 @@ ROOT::ESTLType TClassEdit::STLKind(const char *type, size_t len)
 
    //container names
    static const char *stls[] =
-      { "any", "vector", "list", "deque", "map", "multimap", "set", "multiset", "bitset", 0};
+      { "any", "vector", "list", "forward_list", "deque", "map", "multimap", "set", "multiset", "bitset", 0};
    static const size_t stllen[] =
-      { 3, 6, 4, 5, 3, 8, 3, 8, 6, 0};
+      { 3, 6, 4, 12, 5, 3, 8, 3, 8, 6, 0};
    static const ROOT::ESTLType values[] =
       {  ROOT::kNotSTL, ROOT::kSTLvector,
-         ROOT::kSTLlist, ROOT::kSTLdeque,
+         ROOT::kSTLlist, ROOT::kSTLforwardlist,
+         ROOT::kSTLdeque,
          ROOT::kSTLmap, ROOT::kSTLmultimap,
          ROOT::kSTLset, ROOT::kSTLmultiset,
          ROOT::kSTLbitset, ROOT::kNotSTL
diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx
index 54e61407d8915..928ebee10a291 100644
--- a/core/metautils/src/TMetaUtils.cxx
+++ b/core/metautils/src/TMetaUtils.cxx
@@ -1835,7 +1835,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
       finalString << "      instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << "Pushback" << "<TStdBitsetHelper< " << classname.c_str() << " > >()));" << "\n";
 
       needCollectionProxy = true;
-   } else if (stl != 0 && ((stl>0 && stl<8) || (stl<0 && stl>-8)) )  {
+   } else if (stl != 0 && ((stl>0 && stl<9) || (stl<0 && stl>-9)) )  {
       int idx = classname.find("<");
       int stlType = (idx!=(int)std::string::npos) ? TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
       const char* methodTCP=0;
@@ -1845,6 +1845,9 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
          case ROOT::kSTLdeque:
             methodTCP="Pushback";
             break;
+         case ROOT::kSTLforwardlist:
+            methodTCP="Pushfront";
+            break;
          case ROOT::kSTLmap:
          case ROOT::kSTLmultimap:
             methodTCP="MapInsert";
@@ -4578,10 +4581,11 @@ ROOT::ESTLType ROOT::TMetaUtils::STLKind(const llvm::StringRef type)
    // Converts STL container name to number. vector -> 1, etc..
 
    static const char *stls[] =                  //container names
-      {"any","vector","list","deque","map","multimap","set","multiset","bitset",0};
+      {"any","vector","list", "forward_list", "deque","map","multimap","set","multiset","bitset",0};
    static const ROOT::ESTLType values[] =
       {ROOT::kNotSTL, ROOT::kSTLvector,
-       ROOT::kSTLlist, ROOT::kSTLdeque,
+       ROOT::kSTLlist, ROOT::kSTLforwardlist,
+       ROOT::kSTLdeque,
        ROOT::kSTLmap, ROOT::kSTLmultimap,
        ROOT::kSTLset, ROOT::kSTLmultiset,
        ROOT::kSTLbitset, ROOT::kNotSTL
diff --git a/core/metautils/src/forward_listLinkdef.h b/core/metautils/src/forward_listLinkdef.h
new file mode 100644
index 0000000000000..e38f1930394c2
--- /dev/null
+++ b/core/metautils/src/forward_listLinkdef.h
@@ -0,0 +1,15 @@
+#include <forward_list>
+#include <string>
+#ifndef __hpux
+using namespace std;
+#endif
+
+#pragma create TClass forward_list<int>;
+#pragma create TClass forward_list<long>;
+#pragma create TClass forward_list<float>;
+#pragma create TClass forward_list<double>;
+#pragma create TClass forward_list<void*>;
+#pragma create TClass forward_list<char*>;
+#pragma create TClass forward_list<string>;
+
+// 
diff --git a/core/metautils/src/listLinkdef.h b/core/metautils/src/listLinkdef.h
index d46e8ad772e1e..71a18467e90fb 100644
--- a/core/metautils/src/listLinkdef.h
+++ b/core/metautils/src/listLinkdef.h
@@ -12,3 +12,4 @@ using namespace std;
 #pragma create TClass list<char*>;
 #pragma create TClass list<string>;
 
+// 
diff --git a/core/utils/src/rootcling.cxx b/core/utils/src/rootcling.cxx
index 3043342965961..6a4d871e55411 100644
--- a/core/utils/src/rootcling.cxx
+++ b/core/utils/src/rootcling.cxx
@@ -1200,7 +1200,9 @@ int STLContainerStreamer(const clang::FieldDecl &m,
          case kSTLdeque:
             dictStream << "            R__stl.push_back(R__t);" << std::endl;
             break;
-
+         case kSTLforwardlist:
+            dictStream << "            R__stl.push_front(R__t);" << std::endl;
+            break;
          default:
             assert(0);
       }
diff --git a/io/io/src/TGenCollectionProxy.cxx b/io/io/src/TGenCollectionProxy.cxx
index b6fc8b5939d6f..bd5d6dced6c5e 100644
--- a/io/io/src/TGenCollectionProxy.cxx
+++ b/io/io/src/TGenCollectionProxy.cxx
@@ -747,6 +747,7 @@ TVirtualCollectionProxy* TGenCollectionProxy::Generate() const
          }
       }
       case ROOT::kSTLlist:
+      case ROOT::kSTLforwardlist:
          return new TGenListProxy(*this);
       case ROOT::kSTLmap:
       case ROOT::kSTLmultimap:
@@ -1117,6 +1118,7 @@ void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t /* forceDelete */ )
          }
          case ROOT::kSTLvector:
          case ROOT::kSTLlist:
+         case ROOT::kSTLforwardlist:
          case ROOT::kSTLdeque:
             if( (fProperties & kNeedDelete) ) {
                Clear("force");
diff --git a/io/io/src/TGenCollectionStreamer.cxx b/io/io/src/TGenCollectionStreamer.cxx
index 5e977bcd71cad..599b9589ada7a 100644
--- a/io/io/src/TGenCollectionStreamer.cxx
+++ b/io/io/src/TGenCollectionStreamer.cxx
@@ -414,6 +414,7 @@ void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b, const TClass
          // No contiguous memory, but resize is possible
          // Hence accessing objects using At(i) should be not too much an overhead
       case ROOT::kSTLlist:
+      case ROOT::kSTLforwardlist:
       case ROOT::kSTLdeque:
 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
          fResize(fEnv->fObject,fEnv->fSize);
@@ -523,6 +524,7 @@ void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b)
          // No contiguous memory, but resize is possible
          // Hence accessing objects using At(i) should be not too much an overhead
       case ROOT::kSTLlist:
+      case ROOT::kSTLforwardlist:
       case ROOT::kSTLdeque:
 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
          fResize(fEnv->fObject,fEnv->fSize);
@@ -1016,6 +1018,7 @@ void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b)
          // No contiguous memory, but resize is possible
          // Hence accessing objects using At(i) should be not too much an overhead
       case ROOT::kSTLlist:
+      case ROOT::kSTLforwardlist:
       case ROOT::kSTLdeque:
       case ROOT::kSTLmultiset:
       case ROOT::kSTLset:
@@ -1368,6 +1371,7 @@ void TGenCollectionStreamer::ReadBufferGeneric(TBuffer &b, void *obj, const TCla
             }
             break;
          case ROOT::kSTLlist:
+         case ROOT::kSTLforwardlist:
          case ROOT::kSTLdeque:
          case ROOT::kSTLmultiset:
          case ROOT::kSTLset:
@@ -1448,6 +1452,7 @@ void TGenCollectionStreamer::Streamer(TBuffer &b)
                return;
             case ROOT::kSTLvector:
             case ROOT::kSTLlist:
+            case ROOT::kSTLforwardlist:
             case ROOT::kSTLdeque:
             case ROOT::kSTLmultiset:
             case ROOT::kSTLset:
@@ -1487,6 +1492,7 @@ void TGenCollectionStreamer::StreamerAsMap(TBuffer &b)
                break;
             case ROOT::kSTLvector:
             case ROOT::kSTLlist:
+            case ROOT::kSTLforwardlist:
             case ROOT::kSTLdeque:
             case ROOT::kSTLmultiset:
             case ROOT::kSTLset: {
diff --git a/io/io/src/TMakeProject.cxx b/io/io/src/TMakeProject.cxx
index 6f8d4d643c110..f4918d3d54c25 100644
--- a/io/io/src/TMakeProject.cxx
+++ b/io/io/src/TMakeProject.cxx
@@ -463,6 +463,9 @@ UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, ch
                      case ROOT::kSTLlist:
                         what = "list";
                         break;
+                     case ROOT::kSTLforwardlist:
+                        what = "forward_list";
+                        break;
                      case ROOT::kSTLdeque:
                         what = "deque";
                         break;
@@ -638,6 +641,7 @@ TString TMakeProject::UpdateAssociativeToVector(const char *name)
       switch (stlkind) {
          case ROOT::kSTLvector:
          case ROOT::kSTLlist:
+         case ROOT::kSTLforwardlist:
          case ROOT::kSTLdeque:
             if (narg>2 && strncmp(inside[2].c_str(),"std::allocator<",strlen("std::allocator<"))==0) {
                --narg;
diff --git a/io/xml/src/TXMLPlayer.cxx b/io/xml/src/TXMLPlayer.cxx
index 7fe31f159f91e..1a4096d45f840 100644
--- a/io/xml/src/TXMLPlayer.cxx
+++ b/io/xml/src/TXMLPlayer.cxx
@@ -968,13 +968,14 @@ Bool_t TXMLPlayer::ProduceSTLstreamer(std::ostream& fs, TClass* cl, TStreamerSTL
 
          stltyp = TClassEdit::STLKind(splitName[0].c_str());
          switch (stltyp) {
-            case ROOT::kSTLvector   : narg = 1; break;
-            case ROOT::kSTLlist     : narg = 1; break;
-            case ROOT::kSTLdeque    : narg = 1; break;
-            case ROOT::kSTLmap      : narg = 2; break;
-            case ROOT::kSTLmultimap : narg = 2; break;
-            case ROOT::kSTLset      : narg = 1; break;
-            case ROOT::kSTLmultiset : narg = 1; break;
+            case ROOT::kSTLvector      : narg = 1; break;
+            case ROOT::kSTLlist        : narg = 1; break;
+            case ROOT::kSTLforwardlist : narg = 1; break;
+            case ROOT::kSTLdeque       : narg = 1; break;
+            case ROOT::kSTLmap         : narg = 2; break;
+            case ROOT::kSTLmultimap    : narg = 2; break;
+            case ROOT::kSTLset         : narg = 1; break;
+            case ROOT::kSTLmultiset    : narg = 1; break;
             default: return false;
          }
 
diff --git a/net/http/src/TBufferJSON.cxx b/net/http/src/TBufferJSON.cxx
index 374bfc073bab8..a600d0f065f38 100644
--- a/net/http/src/TBufferJSON.cxx
+++ b/net/http/src/TBufferJSON.cxx
@@ -489,7 +489,9 @@ TString TBufferJSON::JsonWriteMember(const void *ptr, TDataMember *member,
       fValue.Append("\"");
       if (str != 0) fValue.Append(*str);
       fValue.Append("\"");
-   } else if ((member->IsSTLContainer() == ROOT::kSTLvector) || (member->IsSTLContainer() == ROOT::kSTLlist)) {
+   } else if ((member->IsSTLContainer() == ROOT::kSTLvector) ||
+              (member->IsSTLContainer() == ROOT::kSTLlist) ||
+              (member->IsSTLContainer() == ROOT::kSTLforwardlist)) {
 
       if (memberClass)
          ((TClass *)memberClass)->Streamer((void *)ptr, *this);

From ada2a8067a052abd775faff178fe213ab076043e Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 12:53:35 -0600
Subject: [PATCH 091/200] Add direct constructor from TClingMethodInfo to
 TClingCallFunc

---
 core/meta/src/TClingCallFunc.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/core/meta/src/TClingCallFunc.h b/core/meta/src/TClingCallFunc.h
index 833ef3f23bfbf..9298c7d8c5627 100644
--- a/core/meta/src/TClingCallFunc.h
+++ b/core/meta/src/TClingCallFunc.h
@@ -134,6 +134,12 @@ class TClingCallFunc {
       fMethod = new TClingMethodInfo(interp);
    }
 
+   explicit TClingCallFunc(TClingMethodInfo &minfo, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
+   : fInterp(minfo.GetInterpreter()), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false)
+   {
+      fMethod = new TClingMethodInfo(minfo);
+   }
+
    TClingCallFunc(const TClingCallFunc &rhs)
       : fInterp(rhs.fInterp), fNormCtxt(rhs.fNormCtxt), fWrapper(rhs.fWrapper), fArgVals(rhs.fArgVals),
         fIgnoreExtraArgs(rhs.fIgnoreExtraArgs)

From 276abbd23226f99e77c46bb4ed8b4c72ea98b1d1 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 12:53:54 -0600
Subject: [PATCH 092/200] Add TClingMethodInfo::GetInterpreter

---
 core/meta/src/TClingMethodInfo.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/meta/src/TClingMethodInfo.h b/core/meta/src/TClingMethodInfo.h
index 33488be7ee797..cf946d86bdb87 100644
--- a/core/meta/src/TClingMethodInfo.h
+++ b/core/meta/src/TClingMethodInfo.h
@@ -77,6 +77,7 @@ class TClingMethodInfo {
 
    const clang::FunctionDecl                   *GetMethodDecl() const;
    TDictionary::DeclId_t                        GetDeclId() const;
+   cling::Interpreter                          *GetInterpreter() const { return fInterp; }
    void                                         CreateSignature(TString &signature) const;
    void                                         Init(const clang::FunctionDecl *);
    void                                        *InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const;

From b89178c2d26267e4963ebc13a0aa6f54837776dd Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 12:54:18 -0600
Subject: [PATCH 093/200] Add lock ass needed in
 TClingMethodInfo::TClingMethodInfo(const TClingMethodInfo &rhs)

---
 core/meta/src/TClingMethodInfo.cxx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index df52a866658b1..ac6d958adf22a 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -87,9 +87,14 @@ TClingMethodInfo::TClingMethodInfo(const TClingMethodInfo &rhs) :
    fContextIdx(rhs.fContextIdx),
    fIter(rhs.fIter),
    fTitle(rhs.fTitle),
-   fTemplateSpecIter(rhs.fTemplateSpecIter ? new SpecIterator(*rhs.fTemplateSpecIter) : 0),
+   fTemplateSpecIter(nulltpr),
    fSingleDecl(rhs.fSingleDecl)
 {
+   if (rhs.fTemplateSpecIter) {
+      // The SpecIterator query the decl.
+      R__LOCKGUARD(gInterpreterMutex);
+      fTemplateSpecIter = new SpecIterator(*rhs.fTemplateSpecIter);
+   }
 }
 
 

From d77b8ba6ed11ccde842c4d92a65901817fb0b452 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 12:54:56 -0600
Subject: [PATCH 094/200] Use direct constructor from TClingMethodInfo to
 TClingCallFunc

---
 core/meta/src/TCling.cxx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index f5912e715e02b..6edf77029e443 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -4099,9 +4099,8 @@ void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
       return;
    }
    R__LOCKGUARD2(gInterpreterMutex);
-   TClingCallFunc func(fInterpreter,*fNormalizedCtxt);
    TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
-   func.Init(minfo);
+   TClingCallFunc func(*minfo,*fNormalizedCtxt);
    func.ExecWithArgsAndReturn(address, args, nargs, ret);
 }
 

From 0bd3d9d1d513463f6b1f24ab0bb387dc32141953 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 12:56:29 -0600
Subject: [PATCH 095/200] Coding convention (global names)

---
 core/meta/src/TClingCallFunc.cxx | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 20f3e2f7822f4..5a4e066121a6f 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -83,9 +83,9 @@ using namespace std;
 static unsigned long long wrapper_serial = 0LL;
 static const string indent_string("   ");
 
-static map<const FunctionDecl *, void *> wrapper_store;
-static map<const Decl *, void *> ctor_wrapper_store;
-static map<const Decl *, void *> dtor_wrapper_store;
+static map<const FunctionDecl *, void *> gWrapperStore;
+static map<const Decl *, void *> gCtorWrapperStore;
+static map<const Decl *, void *> gDtorWrapperStore;
 
 static
 inline
@@ -1062,7 +1062,7 @@ tcling_callfunc_Wrapper_t TClingCallFunc::make_wrapper()
    //
    void *F = compile_wrapper(wrapper_name, wrapper);
    if (F) {
-      wrapper_store.insert(make_pair(FD, F));
+      gWrapperStore.insert(make_pair(FD, F));
    } else {
       Error("TClingCallFunc::make_wrapper",
             "Failed to compile\n  ==== SOURCE BEGIN ====\n%s\n  ==== SOURCE END ====",
@@ -1227,7 +1227,7 @@ tcling_callfunc_ctor_Wrapper_t TClingCallFunc::make_ctor_wrapper(const TClingCla
    void *F = compile_wrapper(wrapper_name, wrapper,
                              /*withAccessControl=*/false);
    if (F) {
-      ctor_wrapper_store.insert(make_pair(info->GetDecl(), F));
+      gCtorWrapperStore.insert(make_pair(info->GetDecl(), F));
    } else {
       Error("TClingCallFunc::make_ctor_wrapper",
             "Failed to compile\n  ==== SOURCE BEGIN ====\n%s\n  ==== SOURCE END ====",
@@ -1391,7 +1391,7 @@ TClingCallFunc::make_dtor_wrapper(const TClingClassInfo *info)
    void *F = compile_wrapper(wrapper_name, wrapper,
                              /*withAccessControl=*/false);
    if (F) {
-      dtor_wrapper_store.insert(make_pair(info->GetDecl(), F));
+      gDtorWrapperStore.insert(make_pair(info->GetDecl(), F));
    } else {
       Error("TClingCallFunc::make_dtor_wrapper",
             "Failed to compile\n  ==== SOURCE BEGIN ====\n%s\n  ==== SOURCE END ====",
@@ -2192,9 +2192,9 @@ void *TClingCallFunc::ExecDefaultConstructor(const TClingClassInfo *info, void *
    //         info->Name());
    //   return 0;
    //}
-   map<const Decl *, void *>::iterator I = ctor_wrapper_store.find(D);
+   map<const Decl *, void *>::iterator I = gCtorWrapperStore.find(D);
    tcling_callfunc_ctor_Wrapper_t wrapper = 0;
-   if (I != ctor_wrapper_store.end()) {
+   if (I != gCtorWrapperStore.end()) {
       wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
    } else {
       wrapper = make_ctor_wrapper(info);
@@ -2217,9 +2217,9 @@ void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /
       return;
    }
    const Decl *D = info->GetDecl();
-   map<const Decl *, void *>::iterator I = dtor_wrapper_store.find(D);
+   map<const Decl *, void *>::iterator I = gDtorWrapperStore.find(D);
    tcling_callfunc_dtor_Wrapper_t wrapper = 0;
-   if (I != dtor_wrapper_store.end()) {
+   if (I != gDtorWrapperStore.end()) {
       wrapper = (tcling_callfunc_dtor_Wrapper_t) I->second;
    } else {
       wrapper = make_dtor_wrapper(info);
@@ -2260,8 +2260,8 @@ void *TClingCallFunc::InterfaceMethod()
       return 0;
    }
    const FunctionDecl *decl = fMethod->GetMethodDecl();
-   map<const FunctionDecl *, void *>::iterator I = wrapper_store.find(decl);
-   if (I != wrapper_store.end()) {
+   map<const FunctionDecl *, void *>::iterator I = gWrapperStore.find(decl);
+   if (I != gWrapperStore.end()) {
       fWrapper = (tcling_callfunc_Wrapper_t) I->second;
    } else {
       fWrapper = make_wrapper();
@@ -2286,8 +2286,8 @@ TInterpreter::CallFuncIFacePtr_t TClingCallFunc::IFacePtr()
    }
    const FunctionDecl *decl = fMethod->GetMethodDecl();
    map<const FunctionDecl *, void *>::iterator I =
-      wrapper_store.find(decl);
-   if (I != wrapper_store.end()) {
+      gWrapperStore.find(decl);
+   if (I != gWrapperStore.end()) {
       fWrapper = (tcling_callfunc_Wrapper_t) I->second;
    } else {
       fWrapper = make_wrapper();

From f724a5a762842f8c1c01b2a1e0ef720e9b150ab2 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 13:02:13 -0600
Subject: [PATCH 096/200] Add lock when access global wrapper cache (and
 make_wrapper)

---
 core/meta/src/TClingCallFunc.cxx | 33 +++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 5a4e066121a6f..dc50503cf9d21 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -2192,12 +2192,15 @@ void *TClingCallFunc::ExecDefaultConstructor(const TClingClassInfo *info, void *
    //         info->Name());
    //   return 0;
    //}
-   map<const Decl *, void *>::iterator I = gCtorWrapperStore.find(D);
    tcling_callfunc_ctor_Wrapper_t wrapper = 0;
-   if (I != gCtorWrapperStore.end()) {
-      wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
-   } else {
-      wrapper = make_ctor_wrapper(info);
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      map<const Decl *, void *>::iterator I = gCtorWrapperStore.find(D);
+      if (I != gCtorWrapperStore.end()) {
+         wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
+      } else {
+         wrapper = make_ctor_wrapper(info);
+      }
    }
    if (!wrapper) {
       Error("TClingCallFunc::ExecDefaultConstructor",
@@ -2216,13 +2219,17 @@ void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /
       Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
       return;
    }
-   const Decl *D = info->GetDecl();
-   map<const Decl *, void *>::iterator I = gDtorWrapperStore.find(D);
+
    tcling_callfunc_dtor_Wrapper_t wrapper = 0;
-   if (I != gDtorWrapperStore.end()) {
-      wrapper = (tcling_callfunc_dtor_Wrapper_t) I->second;
-   } else {
-      wrapper = make_dtor_wrapper(info);
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      const Decl *D = info->GetDecl();
+      map<const Decl *, void *>::iterator I = gDtorWrapperStore.find(D);
+      if (I != gDtorWrapperStore.end()) {
+         wrapper = (tcling_callfunc_dtor_Wrapper_t) I->second;
+      } else {
+         wrapper = make_dtor_wrapper(info);
+      }
    }
    if (!wrapper) {
       Error("TClingCallFunc::ExecDestructor",
@@ -2260,6 +2267,8 @@ void *TClingCallFunc::InterfaceMethod()
       return 0;
    }
    const FunctionDecl *decl = fMethod->GetMethodDecl();
+
+   R__LOCKGUARD(gInterpreterMutex);
    map<const FunctionDecl *, void *>::iterator I = gWrapperStore.find(decl);
    if (I != gWrapperStore.end()) {
       fWrapper = (tcling_callfunc_Wrapper_t) I->second;
@@ -2285,6 +2294,8 @@ TInterpreter::CallFuncIFacePtr_t TClingCallFunc::IFacePtr()
       return TInterpreter::CallFuncIFacePtr_t();
    }
    const FunctionDecl *decl = fMethod->GetMethodDecl();
+
+   R__LOCKGUARD(gInterpreterMutex);
    map<const FunctionDecl *, void *>::iterator I =
       gWrapperStore.find(decl);
    if (I != gWrapperStore.end()) {

From 81db9dfad7bff787282df178c12ec678c77f3172 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 13:04:45 -0600
Subject: [PATCH 097/200] Remove superseeded lock from
 TCling::ExecuteWithArgsAndReturn.

Now TClingCallFunc contructor and TClingCallFunc::ExecWithArgsAndReturn take the lock as needed.
Most importantly, it no longer hold the lock during user code execution
---
 core/meta/src/TCling.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index 6edf77029e443..ed41ed317f518 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -4098,7 +4098,7 @@ void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
       Error("ExecuteWithArgsAndReturn", "No method was defined");
       return;
    }
-   R__LOCKGUARD2(gInterpreterMutex);
+
    TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
    TClingCallFunc func(*minfo,*fNormalizedCtxt);
    func.ExecWithArgsAndReturn(address, args, nargs, ret);

From 491a2400a82f90dfac335a6d0974e982a608fae4 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 13:06:15 -0600
Subject: [PATCH 098/200] Oups 5a2e28b7

---
 core/meta/src/TClingMethodInfo.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index ac6d958adf22a..6a447ed99bd60 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -87,7 +87,7 @@ TClingMethodInfo::TClingMethodInfo(const TClingMethodInfo &rhs) :
    fContextIdx(rhs.fContextIdx),
    fIter(rhs.fIter),
    fTitle(rhs.fTitle),
-   fTemplateSpecIter(nulltpr),
+   fTemplateSpecIter(nullptr),
    fSingleDecl(rhs.fSingleDecl)
 {
    if (rhs.fTemplateSpecIter) {

From 1a7023c5e5fd7ca4e64e01e61c8ce80c43654db2 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 13:21:49 -0600
Subject: [PATCH 099/200] More migration of lock from outside to inside
 TClingMethodInfo ctor

---
 core/meta/src/TClingMethodInfo.cxx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index 6a447ed99bd60..f78464df3b4e4 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -103,6 +103,8 @@ TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp,
    : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""),
      fTemplateSpecIter(0), fSingleDecl(0)
 {
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (!ci || !ci->IsValid()) {
       return;
    }

From 3ef0420a102e8e928f24260ba3b2f80338c5e193 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 13:39:52 -0600
Subject: [PATCH 100/200] Migrate lock for New and Delete from TClass to
 TClingCallFunc

---
 core/meta/src/TClass.cxx          |   7 --
 core/meta/src/TClingClassInfo.cxx | 117 ++++++++++++++++++------------
 2 files changed, 70 insertions(+), 54 deletions(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 13eef200b6501..acdabe48db3b0 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -4470,7 +4470,6 @@ void *TClass::New(ENewType defConstructor, Bool_t quiet) const
       // constructor we can call.
       // [This is very unlikely to work, but who knows!]
       TClass__GetCallingNew() = defConstructor;
-      R__LOCKGUARD2(gInterpreterMutex);
       p = gCling->ClassInfo_New(GetClassInfo());
       TClass__GetCallingNew() = kRealNew;
       if (!p && !quiet) {
@@ -4565,7 +4564,6 @@ void *TClass::New(void *arena, ENewType defConstructor) const
       // constructor we can call.
       // [This is very unlikely to work, but who knows!]
       TClass__GetCallingNew() = defConstructor;
-      R__LOCKGUARD2(gInterpreterMutex);
       p = gCling->ClassInfo_New(GetClassInfo(),arena);
       TClass__GetCallingNew() = kRealNew;
       if (!p) {
@@ -4653,7 +4651,6 @@ void *TClass::NewArray(Long_t nElements, ENewType defConstructor) const
       // constructor we can call.
       // [This is very unlikely to work, but who knows!]
       TClass__GetCallingNew() = defConstructor;
-      R__LOCKGUARD2(gInterpreterMutex);
       p = gCling->ClassInfo_New(GetClassInfo(),nElements);
       TClass__GetCallingNew() = kRealNew;
       if (!p) {
@@ -4740,7 +4737,6 @@ void *TClass::NewArray(Long_t nElements, void *arena, ENewType defConstructor) c
       // constructor that way, or no default constructor is available and
       // we fail.
       TClass__GetCallingNew() = defConstructor;
-      R__LOCKGUARD2(gInterpreterMutex);
       p = gCling->ClassInfo_New(GetClassInfo(),nElements, arena);
       TClass__GetCallingNew() = kRealNew;
       if (!p) {
@@ -4828,10 +4824,8 @@ void TClass::Destructor(void *obj, Bool_t dtorOnly)
       // or it will be interpreted, otherwise we fail
       // because there is no destructor code at all.
       if (dtorOnly) {
-         R__LOCKGUARD2(gInterpreterMutex);
          gCling->ClassInfo_Destruct(fClassInfo,p);
       } else {
-         R__LOCKGUARD2(gInterpreterMutex);
          gCling->ClassInfo_Delete(fClassInfo,p);
       }
    } else if (!HasInterpreterInfo() && fCollectionProxy) {
@@ -4947,7 +4941,6 @@ void TClass::DeleteArray(void *ary, Bool_t dtorOnly)
       // call the array delete operator, hopefully
       // the class library is loaded and there will be
       // a destructor we can call.
-      R__LOCKGUARD2(gInterpreterMutex);
       gCling->ClassInfo_DeleteArray(GetClassInfo(),ary, dtorOnly);
    } else if (!HasInterpreterInfo() && fCollectionProxy) {
       // There is no dictionary at all, so this is an emulated
diff --git a/core/meta/src/TClingClassInfo.cxx b/core/meta/src/TClingClassInfo.cxx
index 6e61d66acc73f..dc77faf4b01f4 100644
--- a/core/meta/src/TClingClassInfo.cxx
+++ b/core/meta/src/TClingClassInfo.cxx
@@ -301,6 +301,7 @@ TClingMethodInfo TClingClassInfo::GetMethod(const char *fname) const
       return tmi;
    }
 
+   R__LOCKGUARD(gInterpreterMutex);
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -349,6 +350,8 @@ TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
       TClingMethodInfo tmi(fInterp);
       return tmi;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -440,6 +443,9 @@ TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
       TClingMethodInfo tmi(fInterp);
       return tmi;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -503,6 +509,9 @@ TClingMethodInfo TClingClassInfo::GetMethodWithArgs(const char *fname,
       long *poffset, EFunctionMatchMode /*mode = kConversionMatch*/,
       EInheritanceMode /* imode = kWithInheritance*/) const
 {
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -686,6 +695,7 @@ bool TClingClassInfo::HasDefaultConstructor() const
 
 bool TClingClassInfo::HasMethod(const char *name) const
 {
+   R__LOCKGUARD(gInterpreterMutex);
    if (IsLoaded() && !llvm::isa<EnumDecl>(fDecl)) {
       return fInterp->getLookupHelper()
          .hasFunction(fDecl, name,
@@ -961,17 +971,20 @@ void *TClingClassInfo::New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) co
             FullyQualifiedName(fDecl).c_str());
       return 0;
    }
-   const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
-   if (!RD) {
-      Error("TClingClassInfo::New()", "This is a namespace!: %s",
-            FullyQualifiedName(fDecl).c_str());
-      return 0;
-   }
-   if (!HasDefaultConstructor()) {
-      // FIXME: We fail roottest root/io/newdelete if we issue this message!
-      //Error("TClingClassInfo::New()", "Class has no default constructor: %s",
-      //      FullyQualifiedName(fDecl).c_str());
-      return 0;
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
+      if (!RD) {
+         Error("TClingClassInfo::New()", "This is a namespace!: %s",
+               FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
+      if (!HasDefaultConstructor()) {
+         // FIXME: We fail roottest root/io/newdelete if we issue this message!
+         //Error("TClingClassInfo::New()", "Class has no default constructor: %s",
+         //      FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
    }
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
@@ -999,18 +1012,21 @@ void *TClingClassInfo::New(int n, const ROOT::TMetaUtils::TNormalizedCtxt &normC
             FullyQualifiedName(fDecl).c_str());
       return 0;
    }
-   const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
-   if (!RD) {
-      Error("TClingClassInfo::New(n)", "This is a namespace!: %s",
-            FullyQualifiedName(fDecl).c_str());
-      return 0;
-   }
-   if (!HasDefaultConstructor()) {
-      // FIXME: We fail roottest root/io/newdelete if we issue this message!
-      //Error("TClingClassInfo::New(n)",
-      //      "Class has no default constructor: %s",
-      //      FullyQualifiedName(fDecl).c_str());
-      return 0;
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
+      if (!RD) {
+         Error("TClingClassInfo::New(n)", "This is a namespace!: %s",
+               FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
+      if (!HasDefaultConstructor()) {
+         // FIXME: We fail roottest root/io/newdelete if we issue this message!
+         //Error("TClingClassInfo::New(n)",
+         //      "Class has no default constructor: %s",
+         //      FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
    }
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
@@ -1040,18 +1056,22 @@ void *TClingClassInfo::New(int n, void *arena, const ROOT::TMetaUtils::TNormaliz
             FullyQualifiedName(fDecl).c_str());
       return 0;
    }
-   const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
-   if (!RD) {
-      Error("TClingClassInfo::New(n, arena)", "This is a namespace!: %s",
-            FullyQualifiedName(fDecl).c_str());
-      return 0;
-   }
-   if (!HasDefaultConstructor()) {
-      // FIXME: We fail roottest root/io/newdelete if we issue this message!
-      //Error("TClingClassInfo::New(n, arena)",
-      //      "Class has no default constructor: %s",
-      //      FullyQualifiedName(fDecl).c_str());
-      return 0;
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+
+      const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
+      if (!RD) {
+         Error("TClingClassInfo::New(n, arena)", "This is a namespace!: %s",
+               FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
+      if (!HasDefaultConstructor()) {
+         // FIXME: We fail roottest root/io/newdelete if we issue this message!
+         //Error("TClingClassInfo::New(n, arena)",
+         //      "Class has no default constructor: %s",
+         //      FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
    }
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
@@ -1075,18 +1095,21 @@ void *TClingClassInfo::New(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt
             FullyQualifiedName(fDecl).c_str());
       return 0;
    }
-   const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
-   if (!RD) {
-      Error("TClingClassInfo::New(arena)", "This is a namespace!: %s",
-            FullyQualifiedName(fDecl).c_str());
-      return 0;
-   }
-   if (!HasDefaultConstructor()) {
-      // FIXME: We fail roottest root/io/newdelete if we issue this message!
-      //Error("TClingClassInfo::New(arena)",
-      //      "Class has no default constructor: %s",
-      //      FullyQualifiedName(fDecl).c_str());
-      return 0;
+   {
+      R__LOCKGUARD(gInterpreterMutex);
+      const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
+      if (!RD) {
+         Error("TClingClassInfo::New(arena)", "This is a namespace!: %s",
+               FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
+      if (!HasDefaultConstructor()) {
+         // FIXME: We fail roottest root/io/newdelete if we issue this message!
+         //Error("TClingClassInfo::New(arena)",
+         //      "Class has no default constructor: %s",
+         //      FullyQualifiedName(fDecl).c_str());
+         return 0;
+      }
    }
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);

From 186a410c7ce54eef2709e62854ce0e66441179cf Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 14:01:47 -0600
Subject: [PATCH 101/200] Use cached fWrapper value when available

---
 core/meta/src/TClingCallFunc.cxx | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index dc50503cf9d21..75c365b4fd0b2 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -2266,14 +2266,16 @@ void *TClingCallFunc::InterfaceMethod()
    if (!IsValid()) {
       return 0;
    }
-   const FunctionDecl *decl = fMethod->GetMethodDecl();
+   if (!fWrapper) {
+      const FunctionDecl *decl = fMethod->GetMethodDecl();
 
-   R__LOCKGUARD(gInterpreterMutex);
-   map<const FunctionDecl *, void *>::iterator I = gWrapperStore.find(decl);
-   if (I != gWrapperStore.end()) {
-      fWrapper = (tcling_callfunc_Wrapper_t) I->second;
-   } else {
-      fWrapper = make_wrapper();
+      R__LOCKGUARD(gInterpreterMutex);
+      map<const FunctionDecl *, void *>::iterator I = gWrapperStore.find(decl);
+      if (I != gWrapperStore.end()) {
+         fWrapper = (tcling_callfunc_Wrapper_t) I->second;
+      } else {
+         fWrapper = make_wrapper();
+      }
    }
    return (void *)fWrapper;
 }
@@ -2293,15 +2295,17 @@ TInterpreter::CallFuncIFacePtr_t TClingCallFunc::IFacePtr()
             "Attempt to get interface while invalid.");
       return TInterpreter::CallFuncIFacePtr_t();
    }
-   const FunctionDecl *decl = fMethod->GetMethodDecl();
+   if (!fWrapper) {
+      const FunctionDecl *decl = fMethod->GetMethodDecl();
 
-   R__LOCKGUARD(gInterpreterMutex);
-   map<const FunctionDecl *, void *>::iterator I =
+      R__LOCKGUARD(gInterpreterMutex);
+      map<const FunctionDecl *, void *>::iterator I =
       gWrapperStore.find(decl);
-   if (I != gWrapperStore.end()) {
-      fWrapper = (tcling_callfunc_Wrapper_t) I->second;
-   } else {
-      fWrapper = make_wrapper();
+      if (I != gWrapperStore.end()) {
+         fWrapper = (tcling_callfunc_Wrapper_t) I->second;
+      } else {
+         fWrapper = make_wrapper();
+      }
    }
    return TInterpreter::CallFuncIFacePtr_t(fWrapper);
 }

From 4077ca3e5a562861d133ed0cae09ce1cc55e4f2b Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 14:09:52 -0600
Subject: [PATCH 102/200] Cache whether the return type is a record type

---
 core/meta/src/TClingCallFunc.cxx |  6 ++++--
 core/meta/src/TClingCallFunc.h   | 11 +++++++----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 75c365b4fd0b2..66046904048b8 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -2132,8 +2132,8 @@ T TClingCallFunc::ExecT(void *address)
       // Sometimes we are called on a function returning void!
       return 0;
    }
-   const FunctionDecl *decl = fMethod->GetMethodDecl();
-   if (decl->getReturnType().getCanonicalType()->isRecordType())
+
+   if (fReturnIsRecordType)
       ((TCling *)gCling)->RegisterTemporary(ret);
    return sv_to<T>(ret);
 }
@@ -2306,6 +2306,8 @@ TInterpreter::CallFuncIFacePtr_t TClingCallFunc::IFacePtr()
       } else {
          fWrapper = make_wrapper();
       }
+
+      fReturnIsRecordType = decl->getReturnType().getCanonicalType()->isRecordType();
    }
    return TInterpreter::CallFuncIFacePtr_t(fWrapper);
 }
diff --git a/core/meta/src/TClingCallFunc.h b/core/meta/src/TClingCallFunc.h
index 9298c7d8c5627..4a9078e6c4fb9 100644
--- a/core/meta/src/TClingCallFunc.h
+++ b/core/meta/src/TClingCallFunc.h
@@ -68,7 +68,8 @@ class TClingCallFunc {
    /// Stored function arguments, we own.
    mutable llvm::SmallVector<cling::Value, 8> fArgVals;
    /// If true, do not limit number of function arguments to declared number.
-   bool fIgnoreExtraArgs;
+   bool fIgnoreExtraArgs : 1;
+   bool fReturnIsRecordType : 1;
 
 private:
    void* compile_wrapper(const std::string& wrapper_name,
@@ -129,20 +130,22 @@ class TClingCallFunc {
    }
 
    explicit TClingCallFunc(cling::Interpreter *interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
-      : fInterp(interp), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false)
+      : fInterp(interp), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false), fReturnIsRecordType(false)
    {
       fMethod = new TClingMethodInfo(interp);
    }
 
    explicit TClingCallFunc(TClingMethodInfo &minfo, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
-   : fInterp(minfo.GetInterpreter()), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false)
+   : fInterp(minfo.GetInterpreter()), fNormCtxt(normCtxt), fWrapper(0), fIgnoreExtraArgs(false),
+     fReturnIsRecordType(false)
+
    {
       fMethod = new TClingMethodInfo(minfo);
    }
 
    TClingCallFunc(const TClingCallFunc &rhs)
       : fInterp(rhs.fInterp), fNormCtxt(rhs.fNormCtxt), fWrapper(rhs.fWrapper), fArgVals(rhs.fArgVals),
-        fIgnoreExtraArgs(rhs.fIgnoreExtraArgs)
+        fIgnoreExtraArgs(rhs.fIgnoreExtraArgs), fReturnIsRecordType(rhs.fReturnIsRecordType)
    {
       fMethod = new TClingMethodInfo(*rhs.fMethod);
    }

From 581bfd897ced5a8874831844c076463e01d80122 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 14:10:50 -0600
Subject: [PATCH 103/200] Add lock in RegisterTemporary

---
 core/meta/src/TCling.cxx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index ed41ed317f518..f235e690f3edd 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -5987,6 +5987,7 @@ void TCling::RegisterTemporary(const cling::Value& value)
    // value; only pointers / references / objects need to be stored.
 
    if (value.isValid() && value.needsManagedAllocation()) {
+      R__LOCKGUARD(gInterpreterMutex);
       fTemporaries->push_back(value);
    }
 }

From ad6dfc3c57277bab8db0aa4903daa62cd04e0218 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 18:33:32 -0600
Subject: [PATCH 104/200] Add the ability to unlock early the guarded mutex

---
 core/base/inc/TVirtualMutex.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/core/base/inc/TVirtualMutex.h b/core/base/inc/TVirtualMutex.h
index ed3a0d8ca9b80..d8f54195702c8 100644
--- a/core/base/inc/TVirtualMutex.h
+++ b/core/base/inc/TVirtualMutex.h
@@ -77,6 +77,7 @@ class TLockGuard {
 public:
    TLockGuard(TVirtualMutex *mutex)
      : fMutex(mutex) { if (fMutex) fMutex->Lock(); }
+   void UnLock() { if (fMutex) { fMutex->UnLock(); fMutex = 0; } }
    virtual ~TLockGuard() { if (fMutex) fMutex->UnLock(); }
 
    ClassDef(TLockGuard,0)  // Exception safe locking/unlocking of mutex
@@ -84,6 +85,7 @@ class TLockGuard {
 
 // Zero overhead macros in case not compiled with thread support
 #if defined (_REENTRANT) || defined (WIN32)
+
 #define R__LOCKGUARD(mutex) TLockGuard _R__UNIQUE_(R__guard)(mutex)
 #define R__LOCKGUARD2(mutex)                             \
    if (gGlobalMutex && !mutex) {                         \
@@ -93,9 +95,13 @@ class TLockGuard {
       gGlobalMutex->UnLock();                            \
    }                                                     \
    R__LOCKGUARD(mutex)
+#define R__LOCKGUARD_NAMED(name,mutex) TLockGuard _NAME2_(R__guard,name)(mutex)
+#define R__LOCKGUARD_UNLOCK(name) _NAME2_(R__guard,name).UnLock()
 #else
 #define R__LOCKGUARD(mutex)  if (mutex) { }
 #define R__LOCKGUARD2(mutex) if (mutex) { }
+#define R__LOCKGUARD_NAMED(name,mutex) { }
+#define R__LOCKGUARD_UNLOCK(name) { }
 #endif
 
 #endif

From cbb7466df8257bd0c6fb11c0ff1c434b2ec54f20 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 18:37:51 -0600
Subject: [PATCH 105/200] Remove redundant lock (in particular in
 TMethodCall::Execute).

This allows for the global to be release during the user code execution.
Call to gCling->SetTempLevel(1); are left eventhough they are sementically change the global
state because ... it is currently a nop and needs to be replaced by a more explicit temporary
object lifetime management.
---
 core/meta/src/TMethodCall.cxx | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/core/meta/src/TMethodCall.cxx b/core/meta/src/TMethodCall.cxx
index 2215276e483b3..cebfdc01009c4 100644
--- a/core/meta/src/TMethodCall.cxx
+++ b/core/meta/src/TMethodCall.cxx
@@ -414,7 +414,6 @@ void TMethodCall::Execute(void *object)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
    void *address = 0;
    if (object) address = (void*)((Long_t)object + fOffset);
    if (!fDtorOnly && fMethod[0]=='~') {
@@ -430,7 +429,7 @@ void TMethodCall::Execute(void *object, const char *params)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
+   // SetArgs contains the necessary lock.
    gCling->CallFunc_SetArgs(fFunc, (char *)params);
 
    void *address = 0;
@@ -447,7 +446,6 @@ void TMethodCall::Execute(void *object, Long_t &retLong)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
    void *address = 0;
    if (object) address = (void*)((Long_t)object + fOffset);
    gCling->SetTempLevel(1);
@@ -462,7 +460,7 @@ void TMethodCall::Execute(void *object, const char *params, Long_t &retLong)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
+   // SetArgs contains the necessary lock.
    gCling->CallFunc_SetArgs(fFunc, (char *)params);
 
    void *address = 0;
@@ -479,7 +477,6 @@ void TMethodCall::Execute(void *object, Double_t &retDouble)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
    void *address = 0;
    if (object) address = (void*)((Long_t)object + fOffset);
    gCling->SetTempLevel(1);
@@ -494,7 +491,6 @@ void TMethodCall::Execute(void *object, const char *params, Double_t &retDouble)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
    gCling->CallFunc_SetArgs(fFunc, (char *)params);
 
    void *address = 0;
@@ -511,7 +507,6 @@ void TMethodCall::Execute(void *object, char **retText)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
    void *address = 0;
    if (object) address = (void*)((Long_t)object + fOffset);
    gCling->SetTempLevel(1);
@@ -526,7 +521,7 @@ void TMethodCall::Execute(void *object, const char *params, char **retText)
 
    if (!fFunc) return;
 
-   R__LOCKGUARD2(gInterpreterMutex);
+   // SetArgs contains the necessary lock.
    gCling->CallFunc_SetArgs(fFunc, (char *)params);
 
    void *address = 0;
@@ -567,7 +562,6 @@ void TMethodCall::SetParamPtrs(void *paramArr, Int_t nparam)
    // of default arguments.
 
    if (!fFunc) return;
-   R__LOCKGUARD2(gInterpreterMutex);
    gCling->CallFunc_SetArgArray(fFunc,(Long_t *)paramArr, nparam);
 }
 

From de4b1534dbe28deb11f460022d2790b79f9f9094 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 26 Feb 2015 18:42:02 -0600
Subject: [PATCH 106/200] Add 'proper' lock to TClingCallFunc's exec and
 exec_with_valref_return.

The lock is taken only during the part that communicate with clang and releases it before the actual call to the used code.
---
 core/meta/src/TClingCallFunc.cxx | 885 ++++++++++++++++---------------
 1 file changed, 458 insertions(+), 427 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 66046904048b8..941971b6f8b86 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -1433,441 +1433,446 @@ void TClingCallFunc::exec(void *address, void *ret) const
 {
    SmallVector<ValHolder, 8> vh_ary;
    SmallVector<void *, 8> vp_ary;
-   const FunctionDecl *FD = fMethod->GetMethodDecl();
 
-   //
-   //  Convert the arguments from cling::Value to their
-   //  actual type and store them in a holder for passing to the
-   //  wrapper function by pointer to value.
-   //
-   unsigned num_params = FD->getNumParams();
    unsigned num_args = fArgVals.size();
+   {
+      R__LOCKGUARD(gInterpreterMutex);
 
-   if (num_args < FD->getMinRequiredArguments()) {
-      Error("TClingCallFunc::exec",
-            "Not enough arguments provided for %s (%d instead of the minimum %d)",
-            fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper())),
-            num_args, FD->getMinRequiredArguments());
-      return;
-   }
-   if (address == 0 && dyn_cast<CXXMethodDecl>(FD)
-         && !(dyn_cast<CXXMethodDecl>(FD))->isStatic()
-         && !dyn_cast<CXXConstructorDecl>(FD)) {
-      Error("TClingCallFunc::exec",
-            "The method %s is called without an object.",
-            fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper())));
-      return;
-   }
-   vh_ary.reserve(num_args);
-   vp_ary.reserve(num_args);
-   for (unsigned i = 0U; i < num_args; ++i) {
-      QualType Ty;
-      if (i < num_params) {
-         const ParmVarDecl *PVD = FD->getParamDecl(i);
-         Ty = PVD->getType();
-      } else {
-         Ty = fArgVals[i].getType();
+      const FunctionDecl *FD = fMethod->GetMethodDecl();
+
+      //
+      //  Convert the arguments from cling::Value to their
+      //  actual type and store them in a holder for passing to the
+      //  wrapper function by pointer to value.
+      //
+      unsigned num_params = FD->getNumParams();
+
+      if (num_args < FD->getMinRequiredArguments()) {
+         Error("TClingCallFunc::exec",
+               "Not enough arguments provided for %s (%d instead of the minimum %d)",
+               fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper())),
+               num_args, FD->getMinRequiredArguments());
+         return;
       }
-      QualType QT = Ty.getCanonicalType();
-      if (QT->isReferenceType()) {
-         // the argument is already a pointer value (point to the same thing
-         // as the reference.
-         vp_ary.push_back((void *) sv_to_ulong_long(fArgVals[i]));
-      } else if (QT->isMemberPointerType()) {
-         ValHolder vh;
-         vh.u.vp = (void *) sv_to_ulong_long(fArgVals[i]);
-         vh_ary.push_back(vh);
-         vp_ary.push_back(&vh_ary.back());
-      } else if (QT->isPointerType() || QT->isArrayType()) {
-         ValHolder vh;
-         vh.u.vp = (void *) sv_to_ulong_long(fArgVals[i]);
-         vh_ary.push_back(vh);
-         vp_ary.push_back(&vh_ary.back());
-      } else if (QT->isRecordType()) {
-         // the argument is already a pointer value (pointing to object passed
-         // by value).
-         vp_ary.push_back((void *) sv_to_ulong_long(fArgVals[i]));
-      } else if (const EnumType *ET =
+      if (address == 0 && dyn_cast<CXXMethodDecl>(FD)
+          && !(dyn_cast<CXXMethodDecl>(FD))->isStatic()
+          && !dyn_cast<CXXConstructorDecl>(FD)) {
+         Error("TClingCallFunc::exec",
+               "The method %s is called without an object.",
+               fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper())));
+         return;
+      }
+      vh_ary.reserve(num_args);
+      vp_ary.reserve(num_args);
+      for (unsigned i = 0U; i < num_args; ++i) {
+         QualType Ty;
+         if (i < num_params) {
+            const ParmVarDecl *PVD = FD->getParamDecl(i);
+            Ty = PVD->getType();
+         } else {
+            Ty = fArgVals[i].getType();
+         }
+         QualType QT = Ty.getCanonicalType();
+         if (QT->isReferenceType()) {
+            // the argument is already a pointer value (point to the same thing
+            // as the reference.
+            vp_ary.push_back((void *) sv_to_ulong_long(fArgVals[i]));
+         } else if (QT->isMemberPointerType()) {
+            ValHolder vh;
+            vh.u.vp = (void *) sv_to_ulong_long(fArgVals[i]);
+            vh_ary.push_back(vh);
+            vp_ary.push_back(&vh_ary.back());
+         } else if (QT->isPointerType() || QT->isArrayType()) {
+            ValHolder vh;
+            vh.u.vp = (void *) sv_to_ulong_long(fArgVals[i]);
+            vh_ary.push_back(vh);
+            vp_ary.push_back(&vh_ary.back());
+         } else if (QT->isRecordType()) {
+            // the argument is already a pointer value (pointing to object passed
+            // by value).
+            vp_ary.push_back((void *) sv_to_ulong_long(fArgVals[i]));
+         } else if (const EnumType *ET =
                     dyn_cast<EnumType>(&*QT)) {
-         // Note: We may need to worry about the underlying type
-         //       of the enum here.
-         (void) ET;
-         ValHolder vh;
-         vh.u.i = (int) sv_to_long_long(fArgVals[i]);
-         vh_ary.push_back(vh);
-         vp_ary.push_back(&vh_ary.back());
-      } else if (const BuiltinType *BT =
+            // Note: We may need to worry about the underlying type
+            //       of the enum here.
+            (void) ET;
+            ValHolder vh;
+            vh.u.i = (int) sv_to_long_long(fArgVals[i]);
+            vh_ary.push_back(vh);
+            vp_ary.push_back(&vh_ary.back());
+         } else if (const BuiltinType *BT =
                     dyn_cast<BuiltinType>(&*QT)) {
-         //
-         //  WARNING!!!
-         //
-         //  This switch is organized in order-of-declaration
-         //  so that the produced assembly code is optimal.
-         //  Do not reorder!
-         //
-         switch (BT->getKind()) {
-               //
-               //  Builtin Types
-               //
-            case BuiltinType::Void: {
-                  // void
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'Void'!");
-                  return;
-               }
-               break;
-               //
-               //  Unsigned Types
-               //
-            case BuiltinType::Bool: {
-                  // bool
-                  ValHolder vh;
-                  vh.u.b = (bool) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Char_U: {
-                  // char on targets where it is unsigned
-                  ValHolder vh;
-                  vh.u.c = (char) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::UChar: {
-                  // unsigned char
-                  ValHolder vh;
-                  vh.u.uc = (unsigned char) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::WChar_U: {
-                  // wchar_t on targets where it is unsigned.
-                  // The standard doesn't allow to specify signednedd of wchar_t
-                  // thus this maps simply to wchar_t.
-                  ValHolder vh;
-                  vh.u.wc = (wchar_t) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Char16: {
-                  // char16_t
-                  //ValHolder vh;
-                  //vh.u.c16 = (char16_t) sv_to_ulong_long(fArgVals[i]);
-                  //vh_ary.push_back(vh);
-                  //vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Char32: {
-                  // char32_t
-                  //ValHolder vh;
-                  //vh.u.c32 = (char32_t) sv_to_ulong_long(fArgVals[i]);
-                  //vh_ary.push_back(vh);
-                  //vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::UShort: {
-                  // unsigned short
-                  ValHolder vh;
-                  vh.u.us = (unsigned short) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::UInt: {
-                  // unsigned int
-                  ValHolder vh;
-                  vh.u.ui = (unsigned int) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::ULong: {
-                  // unsigned long
-                  ValHolder vh;
-                  vh.u.ul = (unsigned long) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::ULongLong: {
-                  // unsigned long long
-                  ValHolder vh;
-                  vh.u.ull = (unsigned long long) sv_to_ulong_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::UInt128: {
-                  // __uint128_t
-               }
-               break;
-               //
-               //  Signed Types
-               //
-               //
-               //  Signed Types
-               //
-            case BuiltinType::Char_S: {
-                  // char on targets where it is signed
-                  ValHolder vh;
-                  vh.u.c = (char) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::SChar: {
-                  // signed char
-                  ValHolder vh;
-                  vh.u.sc = (signed char) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::WChar_S: {
-                  // wchar_t on targets where it is signed.
-                  // The standard doesn't allow to specify signednedd of wchar_t
-                  // thus this maps simply to wchar_t.
-                  ValHolder vh;
-                  vh.u.wc = (wchar_t) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Short: {
-                  // short
-                  ValHolder vh;
-                  vh.u.s = (short) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Int: {
-                  // int
-                  ValHolder vh;
-                  vh.u.i = (int) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Long: {
-                  // long
-                  ValHolder vh;
-                  vh.u.l = (long) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::LongLong: {
-                  // long long
-                  ValHolder vh;
-                  vh.u.ll = (long long) sv_to_long_long(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Int128: {
-                  // __int128_t
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'Int128'!");
-                  return;
-               }
-               break;
-            case BuiltinType::Half: {
-                  // half in OpenCL, __fp16 in ARM NEON
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'Half'!");
-                  return;
-               }
-               break;
-            case BuiltinType::Float: {
-                  // float
-                  ValHolder vh;
-                  vh.u.flt = sv_to<float>(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::Double: {
-                  // double
-                  ValHolder vh;
-                  vh.u.dbl = sv_to<double>(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::LongDouble: {
-                  // long double
-                  ValHolder vh;
-                  vh.u.ldbl = sv_to<long double>(fArgVals[i]);
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-               //
-               //  Language-Specific Types
-               //
-            case BuiltinType::NullPtr: {
-                  // C++11 nullptr
-                  ValHolder vh;
-                  vh.u.vp = fArgVals[i].getPtr();
-                  vh_ary.push_back(vh);
-                  vp_ary.push_back(&vh_ary.back());
-               }
-               break;
-            case BuiltinType::ObjCId: {
-                  // Objective C 'id' type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'ObjCId'!");
-                  return;
-               }
-               break;
-            case BuiltinType::ObjCClass: {
-                  // Objective C 'Class' type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'ObjCClass'!");
-                  return;
-               }
-               break;
-            case BuiltinType::ObjCSel: {
-                  // Objective C 'SEL' type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'ObjCSel'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage1d: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage1d'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage1dArray: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage1dArray'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage1dBuffer: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage1dBuffer'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage2d: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage2d'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage2dArray: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage2dArray'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLImage3d: {
-                  // OpenCL image type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLImage3d'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLSampler: {
-                  // OpenCL sampler_t
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLSampler'!");
-                  return;
-               }
-               break;
-            case BuiltinType::OCLEvent: {
-                  // OpenCL event_t
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'OCLEvent'!");
-                  return;
-               }
-               break;
-               //
-               //  Placeholder types.
-               //
-               //  These types are used during intermediate phases
-               //  of semantic analysis.  They are eventually resolved
-               //  to one of the preceeding types.
-               //
-            case BuiltinType::Dependent: {
-                  // dependent on a template argument
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'Dependent'!");
-                  return;
-               }
-               break;
-            case BuiltinType::Overload: {
-                  // an unresolved function overload set
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'Overload'!");
-                  return;
-               }
-               break;
-            case BuiltinType::BoundMember: {
-                  // a bound C++ non-static member function
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'BoundMember'!");
-                  return;
-               }
-               break;
-            case BuiltinType::PseudoObject: {
-                  // Object C @property or VS.NET __property
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'PseudoObject'!");
-                  return;
-               }
-               break;
-            case BuiltinType::UnknownAny: {
-                  // represents an unknown type
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'UnknownAny'!");
-                  return;
-               }
-               break;
-            case BuiltinType::BuiltinFn: {
-                  // a compiler builtin function
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'BuiltinFn'!");
-                  return;
-               }
-               break;
-            case BuiltinType::ARCUnbridgedCast: {
-                  // Objective C Automatic Reference Counting cast
-                  // which would normally require __bridge, but which
-                  // may be ok because of the context.
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid type 'ARCUnbridgedCast'!");
-                  return;
-               }
-               break;
-            default: {
-                  // There should be no others.  This is here in case
-                  // this changes in the future.
-                  Error("TClingCallFunc::exec(void*)",
-                        "Invalid builtin type (unrecognized)!");
-                  QT->dump();
-                  return;
-               }
+            //
+            //  WARNING!!!
+            //
+            //  This switch is organized in order-of-declaration
+            //  so that the produced assembly code is optimal.
+            //  Do not reorder!
+            //
+            switch (BT->getKind()) {
+                  //
+                  //  Builtin Types
+                  //
+               case BuiltinType::Void: {
+                     // void
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'Void'!");
+                     return;
+                  }
+                  break;
+                  //
+                  //  Unsigned Types
+                  //
+               case BuiltinType::Bool: {
+                     // bool
+                     ValHolder vh;
+                     vh.u.b = (bool) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Char_U: {
+                     // char on targets where it is unsigned
+                     ValHolder vh;
+                     vh.u.c = (char) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::UChar: {
+                     // unsigned char
+                     ValHolder vh;
+                     vh.u.uc = (unsigned char) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::WChar_U: {
+                     // wchar_t on targets where it is unsigned.
+                     // The standard doesn't allow to specify signednedd of wchar_t
+                     // thus this maps simply to wchar_t.
+                     ValHolder vh;
+                     vh.u.wc = (wchar_t) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Char16: {
+                     // char16_t
+                     //ValHolder vh;
+                     //vh.u.c16 = (char16_t) sv_to_ulong_long(fArgVals[i]);
+                     //vh_ary.push_back(vh);
+                     //vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Char32: {
+                     // char32_t
+                     //ValHolder vh;
+                     //vh.u.c32 = (char32_t) sv_to_ulong_long(fArgVals[i]);
+                     //vh_ary.push_back(vh);
+                     //vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::UShort: {
+                     // unsigned short
+                     ValHolder vh;
+                     vh.u.us = (unsigned short) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::UInt: {
+                     // unsigned int
+                     ValHolder vh;
+                     vh.u.ui = (unsigned int) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::ULong: {
+                     // unsigned long
+                     ValHolder vh;
+                     vh.u.ul = (unsigned long) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::ULongLong: {
+                     // unsigned long long
+                     ValHolder vh;
+                     vh.u.ull = (unsigned long long) sv_to_ulong_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::UInt128: {
+                     // __uint128_t
+                  }
+                  break;
+                  //
+                  //  Signed Types
+                  //
+                  //
+                  //  Signed Types
+                  //
+               case BuiltinType::Char_S: {
+                     // char on targets where it is signed
+                     ValHolder vh;
+                     vh.u.c = (char) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::SChar: {
+                     // signed char
+                     ValHolder vh;
+                     vh.u.sc = (signed char) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::WChar_S: {
+                     // wchar_t on targets where it is signed.
+                     // The standard doesn't allow to specify signednedd of wchar_t
+                     // thus this maps simply to wchar_t.
+                     ValHolder vh;
+                     vh.u.wc = (wchar_t) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Short: {
+                     // short
+                     ValHolder vh;
+                     vh.u.s = (short) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Int: {
+                     // int
+                     ValHolder vh;
+                     vh.u.i = (int) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Long: {
+                     // long
+                     ValHolder vh;
+                     vh.u.l = (long) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::LongLong: {
+                     // long long
+                     ValHolder vh;
+                     vh.u.ll = (long long) sv_to_long_long(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Int128: {
+                     // __int128_t
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'Int128'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::Half: {
+                     // half in OpenCL, __fp16 in ARM NEON
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'Half'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::Float: {
+                     // float
+                     ValHolder vh;
+                     vh.u.flt = sv_to<float>(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::Double: {
+                     // double
+                     ValHolder vh;
+                     vh.u.dbl = sv_to<double>(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::LongDouble: {
+                     // long double
+                     ValHolder vh;
+                     vh.u.ldbl = sv_to<long double>(fArgVals[i]);
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+                  //
+                  //  Language-Specific Types
+                  //
+               case BuiltinType::NullPtr: {
+                     // C++11 nullptr
+                     ValHolder vh;
+                     vh.u.vp = fArgVals[i].getPtr();
+                     vh_ary.push_back(vh);
+                     vp_ary.push_back(&vh_ary.back());
+                  }
+                  break;
+               case BuiltinType::ObjCId: {
+                     // Objective C 'id' type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'ObjCId'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::ObjCClass: {
+                     // Objective C 'Class' type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'ObjCClass'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::ObjCSel: {
+                     // Objective C 'SEL' type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'ObjCSel'!");
+                     return;
+                  }
                break;
+               case BuiltinType::OCLImage1d: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage1d'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLImage1dArray: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage1dArray'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLImage1dBuffer: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage1dBuffer'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLImage2d: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage2d'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLImage2dArray: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage2dArray'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLImage3d: {
+                     // OpenCL image type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLImage3d'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLSampler: {
+                     // OpenCL sampler_t
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLSampler'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::OCLEvent: {
+                     // OpenCL event_t
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'OCLEvent'!");
+                     return;
+                  }
+                  break;
+                  //
+                  //  Placeholder types.
+                  //
+                  //  These types are used during intermediate phases
+                  //  of semantic analysis.  They are eventually resolved
+                  //  to one of the preceeding types.
+                  //
+               case BuiltinType::Dependent: {
+                     // dependent on a template argument
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'Dependent'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::Overload: {
+                     // an unresolved function overload set
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'Overload'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::BoundMember: {
+                     // a bound C++ non-static member function
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'BoundMember'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::PseudoObject: {
+                     // Object C @property or VS.NET __property
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'PseudoObject'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::UnknownAny: {
+                     // represents an unknown type
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'UnknownAny'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::BuiltinFn: {
+                     // a compiler builtin function
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'BuiltinFn'!");
+                     return;
+                  }
+                  break;
+               case BuiltinType::ARCUnbridgedCast: {
+                     // Objective C Automatic Reference Counting cast
+                     // which would normally require __bridge, but which
+                     // may be ok because of the context.
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid type 'ARCUnbridgedCast'!");
+                     return;
+                  }
+                  break;
+               default: {
+                     // There should be no others.  This is here in case
+                     // this changes in the future.
+                     Error("TClingCallFunc::exec(void*)",
+                           "Invalid builtin type (unrecognized)!");
+                     QT->dump();
+                     return;
+                  }
+                  break;
+            }
+         } else {
+            Error("TClingCallFunc::exec(void*)",
+                  "Invalid type (unrecognized)!");
+            QT->dump();
+            return;
          }
-      } else {
-         Error("TClingCallFunc::exec(void*)",
-               "Invalid type (unrecognized)!");
-         QT->dump();
-         return;
       }
    }
    (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
@@ -1897,6 +1902,9 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       exec(address, 0);
       return;
    }
+
+   R__LOCKGUARD_NAMED(global,gInterpreterMutex);
+
    const FunctionDecl *FD = fMethod->GetMethodDecl();
    ASTContext &Context = FD->getASTContext();
 
@@ -1906,12 +1914,14 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       QualType QT = Context.getLValueReferenceType(ClassTy);
       *ret = cling::Value(QT, *fInterp);
       // Store the new()'ed address in getPtr()
+      R__LOCKGUARD_UNLOCK(global);
       exec(address, &ret->getPtr());
       return;
    }
    QualType QT = FD->getReturnType().getCanonicalType();
    if (QT->isReferenceType()) {
       *ret = cling::Value(QT, *fInterp);
+      R__LOCKGUARD_UNLOCK(global);
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isMemberPointerType()) {
@@ -1928,15 +1938,18 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       }
       // We are a function member pointer.
       *ret = cling::Value(QT, *fInterp);
+      R__LOCKGUARD_UNLOCK(global);
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isPointerType() || QT->isArrayType()) {
       // Note: ArrayType is an illegal function return value type.
       *ret = cling::Value(QT, *fInterp);
+      R__LOCKGUARD_UNLOCK(global);
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isRecordType()) {
       *ret = cling::Value(QT, *fInterp);
+      R__LOCKGUARD_UNLOCK(global);
       exec(address, ret->getPtr());
       return;
    } else if (const EnumType *ET = dyn_cast<EnumType>(&*QT)) {
@@ -1944,12 +1957,14 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       //       of the enum here.
       (void) ET;
       *ret = cling::Value(QT, *fInterp);
+      R__LOCKGUARD_UNLOCK(global);
       execWithLL<int>(address, QT, ret);
       return;
    } else if (const BuiltinType *BT = dyn_cast<BuiltinType>(&*QT)) {
       *ret = cling::Value(QT, *fInterp);
       switch (BT->getKind()) {
          case BuiltinType::Void:
+            R__LOCKGUARD_UNLOCK(global);
             exec(address, 0);
             return;
             break;
@@ -1958,11 +1973,13 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             //  Unsigned Types
             //
          case BuiltinType::Bool:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<bool>(address, QT, ret);
             return;
             break;
          case BuiltinType::Char_U: // char on targets where it is unsigned
          case BuiltinType::UChar:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<char>(address, QT, ret);
             return;
             break;
@@ -1970,6 +1987,7 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             // wchar_t on targets where it is unsigned.
             // The standard doesn't allow to specify signednedd of wchar_t
             // thus this maps simply to wchar_t.
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<wchar_t>(address, QT, ret);
             return;
             break;
@@ -1984,18 +2002,22 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             return;
             break;
          case BuiltinType::UShort:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<unsigned short>(address, QT, ret);
             return;
             break;
          case BuiltinType::UInt:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<unsigned int>(address, QT, ret);
             return;
             break;
          case BuiltinType::ULong:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<unsigned long>(address, QT, ret);
             return;
             break;
          case BuiltinType::ULongLong:
+            R__LOCKGUARD_UNLOCK(global);
             execWithULL<unsigned long long>(address, QT, ret);
             return;
             break;
@@ -2011,6 +2033,7 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             //
          case BuiltinType::Char_S: // char on targets where it is signed
          case BuiltinType::SChar:
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<signed char>(address, QT, ret);
             return;
             break;
@@ -2018,22 +2041,27 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             // wchar_t on targets where it is signed.
             // The standard doesn't allow to specify signednedd of wchar_t
             // thus this maps simply to wchar_t.
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<wchar_t>(address, QT, ret);
             return;
             break;
          case BuiltinType::Short:
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<short>(address, QT, ret);
             return;
             break;
          case BuiltinType::Int:
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<int>(address, QT, ret);
             return;
             break;
          case BuiltinType::Long:
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<long>(address, QT, ret);
             return;
             break;
          case BuiltinType::LongLong:
+            R__LOCKGUARD_UNLOCK(global);
             execWithLL<long long>(address, QT, ret);
             return;
             break;
@@ -2049,14 +2077,17 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             return;
             break;
          case BuiltinType::Float:
+            R__LOCKGUARD_UNLOCK(global);
             exec(address, &ret->getFloat());
             return;
             break;
          case BuiltinType::Double:
+            R__LOCKGUARD_UNLOCK(global);
             exec(address, &ret->getDouble());
             return;
             break;
          case BuiltinType::LongDouble:
+            R__LOCKGUARD_UNLOCK(global);
             exec(address, &ret->getLongDouble());
             return;
             break;

From b14a1d05c779a700359a67ce1fe2e21bcf217b74 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Fri, 6 Feb 2015 08:59:09 -0600
Subject: [PATCH 107/200] Add explicit unlock capability to LockGuard

---
 core/base/inc/TVirtualMutex.h | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/core/base/inc/TVirtualMutex.h b/core/base/inc/TVirtualMutex.h
index d8f54195702c8..3dede343de39b 100644
--- a/core/base/inc/TVirtualMutex.h
+++ b/core/base/inc/TVirtualMutex.h
@@ -77,10 +77,15 @@ class TLockGuard {
 public:
    TLockGuard(TVirtualMutex *mutex)
      : fMutex(mutex) { if (fMutex) fMutex->Lock(); }
-   void UnLock() { if (fMutex) { fMutex->UnLock(); fMutex = 0; } }
-   virtual ~TLockGuard() { if (fMutex) fMutex->UnLock(); }
-
-   ClassDef(TLockGuard,0)  // Exception safe locking/unlocking of mutex
+   Int_t UnLock() {
+      if (!fMutex) return 0;
+      auto tmp = fMutex;
+      fMutex = 0;
+      return tmp->UnLock();
+   }
+   ~TLockGuard() { if (fMutex) fMutex->UnLock(); }
+
+   ClassDefNV(TLockGuard,0)  // Exception safe locking/unlocking of mutex
 };
 
 // Zero overhead macros in case not compiled with thread support
@@ -99,8 +104,8 @@ class TLockGuard {
 #define R__LOCKGUARD_UNLOCK(name) _NAME2_(R__guard,name).UnLock()
 #else
 #define R__LOCKGUARD(mutex)  if (mutex) { }
+#define R__LOCKGUARD_NAMED(name,mutex) if (mutex) { }
 #define R__LOCKGUARD2(mutex) if (mutex) { }
-#define R__LOCKGUARD_NAMED(name,mutex) { }
 #define R__LOCKGUARD_UNLOCK(name) { }
 #endif
 

From 3ac475c85ca1e221210b65ef3832877a3659a241 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Fri, 6 Feb 2015 08:59:13 -0600
Subject: [PATCH 108/200] Add missing locks in interface between TCling and
 cling.

The moral equivalent of those locks where embeded in CINT's code.
---
 core/meta/src/TClingCallFunc.cxx  | 73 +++++++++++++++++--------------
 core/meta/src/TClingClassInfo.cxx | 54 +++++++++++++++++++----
 2 files changed, 85 insertions(+), 42 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 941971b6f8b86..33d74d7bbe54e 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -101,6 +101,8 @@ static
 void
 EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
 {
+   R__LOCKGUARD(gInterpreterMutex);
+
    // Evaluate an Expr* and return its cling::Value
    ASTContext &C = interp.getCI()->getASTContext();
    APSInt res;
@@ -636,6 +638,8 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
 
 tcling_callfunc_Wrapper_t TClingCallFunc::make_wrapper()
 {
+   R__LOCKGUARD(gInterpreterMutex);
+
    const FunctionDecl *FD = fMethod->GetMethodDecl();
    ASTContext &Context = FD->getASTContext();
    PrintingPolicy Policy(Context.getPrintingPolicy());
@@ -1742,7 +1746,7 @@ void TClingCallFunc::exec(void *address, void *ret) const
                            "Invalid type 'ObjCSel'!");
                      return;
                   }
-               break;
+                  break;
                case BuiltinType::OCLImage1d: {
                      // OpenCL image type
                      Error("TClingCallFunc::exec(void*)",
@@ -1874,7 +1878,7 @@ void TClingCallFunc::exec(void *address, void *ret) const
             return;
          }
       }
-   }
+   } // End of scope holding the lock
    (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
 }
 
@@ -1914,14 +1918,14 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       QualType QT = Context.getLValueReferenceType(ClassTy);
       *ret = cling::Value(QT, *fInterp);
       // Store the new()'ed address in getPtr()
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       exec(address, &ret->getPtr());
       return;
    }
    QualType QT = FD->getReturnType().getCanonicalType();
    if (QT->isReferenceType()) {
       *ret = cling::Value(QT, *fInterp);
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isMemberPointerType()) {
@@ -1933,23 +1937,24 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
          // But that's not relevant: we use it as a non-builtin, allocated
          // type.
          *ret = cling::Value(QT, *fInterp);
+         R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
          exec(address, ret->getPtr());
          return;
       }
       // We are a function member pointer.
       *ret = cling::Value(QT, *fInterp);
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isPointerType() || QT->isArrayType()) {
       // Note: ArrayType is an illegal function return value type.
       *ret = cling::Value(QT, *fInterp);
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       exec(address, &ret->getPtr());
       return;
    } else if (QT->isRecordType()) {
       *ret = cling::Value(QT, *fInterp);
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       exec(address, ret->getPtr());
       return;
    } else if (const EnumType *ET = dyn_cast<EnumType>(&*QT)) {
@@ -1957,14 +1962,14 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
       //       of the enum here.
       (void) ET;
       *ret = cling::Value(QT, *fInterp);
-      R__LOCKGUARD_UNLOCK(global);
+      R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
       execWithLL<int>(address, QT, ret);
       return;
    } else if (const BuiltinType *BT = dyn_cast<BuiltinType>(&*QT)) {
       *ret = cling::Value(QT, *fInterp);
       switch (BT->getKind()) {
          case BuiltinType::Void:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             exec(address, 0);
             return;
             break;
@@ -1973,13 +1978,13 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             //  Unsigned Types
             //
          case BuiltinType::Bool:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<bool>(address, QT, ret);
             return;
             break;
          case BuiltinType::Char_U: // char on targets where it is unsigned
          case BuiltinType::UChar:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<char>(address, QT, ret);
             return;
             break;
@@ -1987,7 +1992,7 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             // wchar_t on targets where it is unsigned.
             // The standard doesn't allow to specify signednedd of wchar_t
             // thus this maps simply to wchar_t.
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<wchar_t>(address, QT, ret);
             return;
             break;
@@ -2002,22 +2007,22 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             return;
             break;
          case BuiltinType::UShort:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<unsigned short>(address, QT, ret);
             return;
             break;
          case BuiltinType::UInt:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<unsigned int>(address, QT, ret);
             return;
             break;
          case BuiltinType::ULong:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<unsigned long>(address, QT, ret);
             return;
             break;
          case BuiltinType::ULongLong:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithULL<unsigned long long>(address, QT, ret);
             return;
             break;
@@ -2033,7 +2038,7 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             //
          case BuiltinType::Char_S: // char on targets where it is signed
          case BuiltinType::SChar:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<signed char>(address, QT, ret);
             return;
             break;
@@ -2041,27 +2046,27 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             // wchar_t on targets where it is signed.
             // The standard doesn't allow to specify signednedd of wchar_t
             // thus this maps simply to wchar_t.
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<wchar_t>(address, QT, ret);
             return;
             break;
          case BuiltinType::Short:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<short>(address, QT, ret);
             return;
             break;
          case BuiltinType::Int:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<int>(address, QT, ret);
             return;
             break;
          case BuiltinType::Long:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<long>(address, QT, ret);
             return;
             break;
          case BuiltinType::LongLong:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             execWithLL<long long>(address, QT, ret);
             return;
             break;
@@ -2077,17 +2082,17 @@ void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret) c
             return;
             break;
          case BuiltinType::Float:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             exec(address, &ret->getFloat());
             return;
             break;
          case BuiltinType::Double:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             exec(address, &ret->getDouble());
             return;
             break;
          case BuiltinType::LongDouble:
-            R__LOCKGUARD_UNLOCK(global);
+            R__LOCKGUARD_UNLOCK(global); // Release lock during user function execution
             exec(address, &ret->getLongDouble());
             return;
             break;
@@ -2214,18 +2219,18 @@ void *TClingCallFunc::ExecDefaultConstructor(const TClingClassInfo *info, void *
       Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
       return 0;
    }
-   const Decl *D = info->GetDecl();
-   //if (!info->HasDefaultConstructor()) {
-   //   // FIXME: We might have a ROOT ioctor, we might
-   //   //        have to check for that here.
-   //   Error("TClingCallFunc::ExecDefaultConstructor",
-   //         "Class has no default constructor: %s",
-   //         info->Name());
-   //   return 0;
-   //}
    tcling_callfunc_ctor_Wrapper_t wrapper = 0;
    {
       R__LOCKGUARD(gInterpreterMutex);
+      const Decl *D = info->GetDecl();
+      //if (!info->HasDefaultConstructor()) {
+      //   // FIXME: We might have a ROOT ioctor, we might
+      //   //        have to check for that here.
+      //   Error("TClingCallFunc::ExecDefaultConstructor",
+      //         "Class has no default constructor: %s",
+      //         info->Name());
+      //   return 0;
+      //}
       map<const Decl *, void *>::iterator I = gCtorWrapperStore.find(D);
       if (I != gCtorWrapperStore.end()) {
          wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
diff --git a/core/meta/src/TClingClassInfo.cxx b/core/meta/src/TClingClassInfo.cxx
index dc77faf4b01f4..dbb50894f6bfa 100644
--- a/core/meta/src/TClingClassInfo.cxx
+++ b/core/meta/src/TClingClassInfo.cxx
@@ -302,6 +302,7 @@ TClingMethodInfo TClingClassInfo::GetMethod(const char *fname) const
    }
 
    R__LOCKGUARD(gInterpreterMutex);
+
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -352,6 +353,7 @@ TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
    }
 
    R__LOCKGUARD(gInterpreterMutex);
+
    if (fType) {
       const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
       if (TT) {
@@ -571,6 +573,9 @@ int TClingClassInfo::GetMethodNArg(const char *method, const char *proto,
    if (!IsLoaded()) {
       return -1;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    TClingMethodInfo mi = GetMethod(method, proto, objectIsConst, 0, mode);
    int clang_val = -1;
    if (mi.IsValid()) {
@@ -582,6 +587,9 @@ int TClingClassInfo::GetMethodNArg(const char *method, const char *proto,
 
 long TClingClassInfo::GetOffset(const CXXMethodDecl* md) const
 {
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    long offset = 0L;
    const CXXRecordDecl* definer = md->getParent();
    const CXXRecordDecl* accessor =
@@ -606,6 +614,9 @@ long TClingClassInfo::GetOffset(const CXXMethodDecl* md) const
 
 ptrdiff_t TClingClassInfo::GetBaseOffset(TClingClassInfo* base, void* address, bool isDerivedObject)
 {
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    // Check for the offset in the cache.
    llvm::DenseMapIterator<const clang::Decl *, std::pair<ptrdiff_t, ptrdiff_t (*)(void*, bool)>, llvm::DenseMapInfo<const clang::Decl *>, true> iter
       = fOffsetCache.find(base->GetDecl());
@@ -752,6 +763,9 @@ void TClingClassInfo::Init(int tagnum)
 void TClingClassInfo::Init(const Type &tag)
 {
    fType = &tag;
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    const TagType *tagtype = fType->getAs<TagType>();
    if (tagtype) {
       fDecl = tagtype->getDecl();
@@ -778,6 +792,9 @@ bool TClingClassInfo::IsBase(const char *name) const
    if (!base.IsValid()) {
       return false;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    const CXXRecordDecl *CRD =
       llvm::dyn_cast<CXXRecordDecl>(fDecl);
    if (!CRD) {
@@ -812,6 +829,9 @@ bool TClingClassInfo::IsLoaded() const
    if (fDecl == 0) {
       return false;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    const CXXRecordDecl *CRD = llvm::dyn_cast<CXXRecordDecl>(fDecl);
    if ( CRD ) {
       if (!CRD->hasDefinition()) {
@@ -850,6 +870,9 @@ bool TClingClassInfo::IsValidMethod(const char *method, const char *proto,
 
 int TClingClassInfo::InternalNext()
 {
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (!*fIter) {
       // Iterator is already invalid.
       if (fFirstTime && fDecl) {
@@ -985,7 +1008,7 @@ void *TClingClassInfo::New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) co
          //      FullyQualifiedName(fDecl).c_str());
          return 0;
       }
-   }
+   } // End of Lock section.
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
    obj = cf.ExecDefaultConstructor(this, /*address=*/0, /*nary=*/0);
@@ -1012,8 +1035,10 @@ void *TClingClassInfo::New(int n, const ROOT::TMetaUtils::TNormalizedCtxt &normC
             FullyQualifiedName(fDecl).c_str());
       return 0;
    }
+
    {
       R__LOCKGUARD(gInterpreterMutex);
+
       const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
       if (!RD) {
          Error("TClingClassInfo::New(n)", "This is a namespace!: %s",
@@ -1027,7 +1052,7 @@ void *TClingClassInfo::New(int n, const ROOT::TMetaUtils::TNormalizedCtxt &normC
          //      FullyQualifiedName(fDecl).c_str());
          return 0;
       }
-   }
+   } // End of Lock section.
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
    obj = cf.ExecDefaultConstructor(this, /*address=*/0,
@@ -1072,7 +1097,7 @@ void *TClingClassInfo::New(int n, void *arena, const ROOT::TMetaUtils::TNormaliz
          //      FullyQualifiedName(fDecl).c_str());
          return 0;
       }
-   }
+   } // End of Lock section
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
    // Note: This will always return arena.
@@ -1097,6 +1122,7 @@ void *TClingClassInfo::New(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt
    }
    {
       R__LOCKGUARD(gInterpreterMutex);
+
       const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(fDecl);
       if (!RD) {
          Error("TClingClassInfo::New(arena)", "This is a namespace!: %s",
@@ -1110,7 +1136,7 @@ void *TClingClassInfo::New(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt
          //      FullyQualifiedName(fDecl).c_str());
          return 0;
       }
-   }
+   } // End of Locked section.
    void* obj = 0;
    TClingCallFunc cf(fInterp,normCtxt);
    // Note: This will always return arena.
@@ -1123,6 +1149,9 @@ long TClingClassInfo::Property() const
    if (!IsValid()) {
       return 0L;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    long property = 0L;
    property |= kIsCPPCompiled;
    const clang::DeclContext *ctxt = fDecl->getDeclContext();
@@ -1184,6 +1213,9 @@ int TClingClassInfo::Size() const
       // A forward declared class.
       return 0;
    }
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    Decl::Kind DK = fDecl->getKind();
    if (DK == Decl::Namespace) {
       // Namespaces are special for cint.
@@ -1255,8 +1287,8 @@ const char *TClingClassInfo::Name() const
    if (!IsValid()) {
       return 0;
    }
-   // Note: This *must* be static because we are returning a pointer inside it!
-   static std::string buf;
+   // Note: This *must* be static/thread_local because we are returning a pointer inside it!
+   thread_local std::string buf;
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {
       PrintingPolicy Policy(fDecl->getASTContext().getPrintingPolicy());
@@ -1276,6 +1308,9 @@ const char *TClingClassInfo::Title()
    // file, if present.
    // Iterate over the redeclarations, we can have muliple definitions in the
    // redecl chain (came from merging of pcms).
+
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (const TagDecl *TD = llvm::dyn_cast<TagDecl>(GetDecl())) {
       if ( (TD = ROOT::TMetaUtils::GetAnnotatedRedeclarable(TD)) ) {
          if (AnnotateAttr *A = TD->getAttr<AnnotateAttr>()) {
@@ -1308,8 +1343,11 @@ const char *TClingClassInfo::TmpltName() const
    if (!IsValid()) {
       return 0;
    }
-   // Note: This *must* be static because we are returning a pointer inside it!
-   static std::string buf;
+
+   R__LOCKGUARD(gInterpreterMutex);
+
+   // Note: This *must* be static/thread_local because we are returning a pointer inside it!
+   thread_local std::string buf;
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {
       // Note: This does *not* include the template arguments!

From 67b26b9f4b0d837ee495ebb3dcba6ca42197d627 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Fri, 6 Feb 2015 09:01:47 -0600
Subject: [PATCH 109/200] coding conventions

---
 core/meta/src/TClingCallFunc.cxx | 68 ++++++++++++++++----------------
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/core/meta/src/TClingCallFunc.cxx b/core/meta/src/TClingCallFunc.cxx
index 33d74d7bbe54e..42ac3addbb7f2 100644
--- a/core/meta/src/TClingCallFunc.cxx
+++ b/core/meta/src/TClingCallFunc.cxx
@@ -80,8 +80,8 @@ using namespace llvm;
 using namespace clang;
 using namespace std;
 
-static unsigned long long wrapper_serial = 0LL;
-static const string indent_string("   ");
+static unsigned long long gWrapperSerial = 0LL;
+static const string kIndentString("   ");
 
 static map<const FunctionDecl *, void *> gWrapperStore;
 static map<const Decl *, void *> gCtorWrapperStore;
@@ -93,7 +93,7 @@ void
 indent(ostringstream &buf, int indent_level)
 {
    for (int i = 0; i < indent_level; ++i) {
-      buf << indent_string;
+      buf << kIndentString;
    }
 }
 
@@ -285,14 +285,14 @@ void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf,
       string fp_typedef_name;
       {
          ostringstream nm;
-         nm << "FP" << wrapper_serial++;
+         nm << "FP" << gWrapperSerial++;
          type_name = nm.str();
          raw_string_ostream OS(fp_typedef_name);
          QT.print(OS, Policy, type_name);
          OS.flush();
       }
       for (int i = 0; i < indent_level; ++i) {
-         typedefbuf << indent_string;
+         typedefbuf << kIndentString;
       }
       typedefbuf << "typedef " << fp_typedef_name << ";\n";
       return;
@@ -300,14 +300,14 @@ void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf,
       string mp_typedef_name;
       {
          ostringstream nm;
-         nm << "MP" << wrapper_serial++;
+         nm << "MP" << gWrapperSerial++;
          type_name = nm.str();
          raw_string_ostream OS(mp_typedef_name);
          QT.print(OS, Policy, type_name);
          OS.flush();
       }
       for (int i = 0; i < indent_level; ++i) {
-         typedefbuf << indent_string;
+         typedefbuf << kIndentString;
       }
       typedefbuf << "typedef " << mp_typedef_name << ";\n";
       return;
@@ -323,14 +323,14 @@ void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf,
       string ar_typedef_name;
       {
          ostringstream ar;
-         ar << "AR" << wrapper_serial++;
+         ar << "AR" << gWrapperSerial++;
          type_name = ar.str();
          raw_string_ostream OS(ar_typedef_name);
          QT.print(OS, Policy, type_name);
          OS.flush();
       }
       for (int i = 0; i < indent_level; ++i) {
-         typedefbuf << indent_string;
+         typedefbuf << kIndentString;
       }
       typedefbuf << "typedef " << ar_typedef_name << ";\n";
       return;
@@ -365,7 +365,7 @@ void TClingCallFunc::make_narg_ctor(const unsigned N, ostringstream &typedefbuf,
          } else {
             callbuf << "\n";
             for (int j = 0; j <= indent_level; ++j) {
-               callbuf << indent_string;
+               callbuf << kIndentString;
             }
          }
       }
@@ -429,7 +429,7 @@ void TClingCallFunc::make_narg_call(const unsigned N, ostringstream &typedefbuf,
          } else {
             callbuf << "\n";
             for (int j = 0; j <= indent_level; ++j) {
-               callbuf << indent_string;
+               callbuf << kIndentString;
             }
          }
       }
@@ -461,7 +461,7 @@ void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &
    // }
    //
    for (int i = 0; i < indent_level; ++i) {
-      buf << indent_string;
+      buf << kIndentString;
    }
    buf << "if (ret) {\n";
    ++indent_level;
@@ -472,7 +472,7 @@ void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &
       //  Write the return value assignment part.
       //
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       callbuf << "(*(" << class_name << "**)ret) = ";
       //
@@ -484,7 +484,7 @@ void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &
       //
       callbuf << ";\n";
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       callbuf << "return;\n";
       //
@@ -494,11 +494,11 @@ void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &
    }
    --indent_level;
    for (int i = 0; i < indent_level; ++i) {
-      buf << indent_string;
+      buf << kIndentString;
    }
    buf << "}\n";
    for (int i = 0; i < indent_level; ++i) {
-      buf << indent_string;
+      buf << kIndentString;
    }
    buf << "else {\n";
    ++indent_level;
@@ -506,19 +506,19 @@ void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &
       ostringstream typedefbuf;
       ostringstream callbuf;
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       make_narg_ctor(N, typedefbuf, callbuf, class_name, indent_level);
       callbuf << ";\n";
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       callbuf << "return;\n";
       buf << typedefbuf.str() << callbuf.str();
    }
    --indent_level;
    for (int i = 0; i < indent_level; ++i) {
-      buf << indent_string;
+      buf << kIndentString;
    }
    buf << "}\n";
 }
@@ -546,18 +546,18 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
       ostringstream typedefbuf;
       ostringstream callbuf;
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       make_narg_call(N, typedefbuf, callbuf, class_name, indent_level);
       callbuf << ";\n";
       for (int i = 0; i < indent_level; ++i) {
-         callbuf << indent_string;
+         callbuf << kIndentString;
       }
       callbuf << "return;\n";
       buf << typedefbuf.str() << callbuf.str();
    } else {
       for (int i = 0; i < indent_level; ++i) {
-         buf << indent_string;
+         buf << kIndentString;
       }
       buf << "if (ret) {\n";
       ++indent_level;
@@ -568,7 +568,7 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
          //  Write the placement part of the placement new.
          //
          for (int i = 0; i < indent_level; ++i) {
-            callbuf << indent_string;
+            callbuf << kIndentString;
          }
          callbuf << "new (ret) ";
          string type_name;
@@ -596,7 +596,7 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
          //
          callbuf << ");\n";
          for (int i = 0; i < indent_level; ++i) {
-            callbuf << indent_string;
+            callbuf << kIndentString;
          }
          callbuf << "return;\n";
          //
@@ -606,11 +606,11 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
       }
       --indent_level;
       for (int i = 0; i < indent_level; ++i) {
-         buf << indent_string;
+         buf << kIndentString;
       }
       buf << "}\n";
       for (int i = 0; i < indent_level; ++i) {
-         buf << indent_string;
+         buf << kIndentString;
       }
       buf << "else {\n";
       ++indent_level;
@@ -618,19 +618,19 @@ void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &
          ostringstream typedefbuf;
          ostringstream callbuf;
          for (int i = 0; i < indent_level; ++i) {
-            callbuf << indent_string;
+            callbuf << kIndentString;
          }
          make_narg_call(N, typedefbuf, callbuf, class_name, indent_level);
          callbuf << ";\n";
          for (int i = 0; i < indent_level; ++i) {
-            callbuf << indent_string;
+            callbuf << kIndentString;
          }
          callbuf << "return;\n";
          buf << typedefbuf.str() << callbuf.str();
       }
       --indent_level;
       for (int i = 0; i < indent_level; ++i) {
-         buf << indent_string;
+         buf << kIndentString;
       }
       buf << "}\n";
    }
@@ -1022,7 +1022,7 @@ tcling_callfunc_Wrapper_t TClingCallFunc::make_wrapper()
       //string mn;
       //fInterp->maybeMangleDeclName(ND, mn);
       //buf << '_' << mn;
-      buf << '_' << wrapper_serial++;
+      buf << '_' << gWrapperSerial++;
       wrapper_name = buf.str();
    }
    //
@@ -1045,14 +1045,14 @@ tcling_callfunc_Wrapper_t TClingCallFunc::make_wrapper()
       // possible number of arguments per call.
       for (unsigned N = min_args; N <= num_params; ++N) {
          for (int i = 0; i < indent_level; ++i) {
-            buf << indent_string;
+            buf << kIndentString;
          }
          buf << "if (nargs == " << N << ") {\n";
          ++indent_level;
          make_narg_call_with_return(N, class_name, buf, indent_level);
          --indent_level;
          for (int i = 0; i < indent_level; ++i) {
-            buf << indent_string;
+            buf << kIndentString;
          }
          buf << "}\n";
       }
@@ -1145,7 +1145,7 @@ tcling_callfunc_ctor_Wrapper_t TClingCallFunc::make_ctor_wrapper(const TClingCla
       //string mn;
       //fInterp->maybeMangleDeclName(ND, mn);
       //buf << '_dtor_' << mn;
-      buf << '_' << wrapper_serial++;
+      buf << '_' << gWrapperSerial++;
       wrapper_name = buf.str();
    }
    //
@@ -1299,7 +1299,7 @@ TClingCallFunc::make_dtor_wrapper(const TClingClassInfo *info)
       //string mn;
       //fInterp->maybeMangleDeclName(ND, mn);
       //buf << '_dtor_' << mn;
-      buf << '_' << wrapper_serial++;
+      buf << '_' << gWrapperSerial++;
       wrapper_name = buf.str();
    }
    //

From 4f0696bdd0d1e0fe96540baf668ef196260094ae Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 27 Feb 2015 15:38:10 +0100
Subject: [PATCH 110/200] Implement proper solutions for the thread_local issue
 on Windows (thanks Philippe!)

---
 core/base/src/TSystem.cxx         |  7 ++++---
 core/meta/src/TClingClassInfo.cxx | 12 ++++++++----
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/core/base/src/TSystem.cxx b/core/base/src/TSystem.cxx
index 58e1b82f06c92..054db5b8a5164 100644
--- a/core/base/src/TSystem.cxx
+++ b/core/base/src/TSystem.cxx
@@ -1992,12 +1992,13 @@ TString &TSystem::GetLastErrorString()
    // Return the thread local storage for the custom last error message
 
 #ifdef R__WIN32
-   static TString gLastErrorString;
+   thread_local TString *gLastErrorStringPtr = 0;
+   if (!gLastErrorStringPtr) gLastErrorStringPtr = new TString();
+   return *gLastErrorStringPtr;
 #else
    thread_local TString gLastErrorString;
-#endif
-
    return gLastErrorString;
+#endif
 }
 
 //______________________________________________________________________________
diff --git a/core/meta/src/TClingClassInfo.cxx b/core/meta/src/TClingClassInfo.cxx
index 68e40fd2e7774..25908f1588445 100644
--- a/core/meta/src/TClingClassInfo.cxx
+++ b/core/meta/src/TClingClassInfo.cxx
@@ -1288,9 +1288,11 @@ const char *TClingClassInfo::Name() const
    }
    // Note: This *must* be static/thread_local because we are returning a pointer inside it!
 #ifdef R__WIN32
-   static std::string buf;
+   thread_local std::string *pbuf = 0;
+   if (!pbuf) pbuf = new std::string();
+   std::string &buf = *pbuf;
 #else
-    thread_local std::string buf;
+   thread_local std::string buf;
 #endif
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {
@@ -1351,9 +1353,11 @@ const char *TClingClassInfo::TmpltName() const
 
    // Note: This *must* be static/thread_local because we are returning a pointer inside it!
 #ifdef R__WIN32
-   static std::string buf;
+   thread_local std::string *pbuf = 0;
+   if (!pbuf) pbuf = new std::string();
+   std::string &buf = *pbuf;
 #else
-    thread_local std::string buf;
+   thread_local std::string buf;
 #endif
    buf.clear();
    if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(fDecl)) {

From 62585572276c3933d15fa5176d130a835dd6145e Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Sat, 28 Feb 2015 17:12:32 +0100
Subject: [PATCH 111/200] stressProof: adapt to new default packetizer

---
 test/stressProof.cxx | 255 ++++++++++++++++++++++---------------------
 1 file changed, 130 insertions(+), 125 deletions(-)

diff --git a/test/stressProof.cxx b/test/stressProof.cxx
index 081a4813e25ad..7fb567a18024e 100644
--- a/test/stressProof.cxx
+++ b/test/stressProof.cxx
@@ -14,7 +14,7 @@
 // *                                                                       * //
 // * To run interactively:                                                 * //
 // * $ root                                                                * //
-// * root[] .I $ROOTSYS/tutorials                                          * //
+// * root[] .include $ROOTSYS/tutorials                                    * //
 // * root[] .L stressProof.cxx+                                            * //
 // * root[] stressProof(master, tests, wrks, verbose, logfile, dyn, \      * //
 // *                    dyn, skipds, h1src, eventsrc, dryrun)              * //
@@ -34,9 +34,7 @@
 // *  ******************************************************************   * //
 // *  *  Starting  P R O O F - S T R E S S suite                       *   * //
 // *  ******************************************************************   * //
-// *  * Temp dir for this run: /tmp/ganis/stressProof-31556                * //
-// *  ******************************************************************   * //
-// *  * Main log file: /tmp/ganis/stressProof-31556/main.log               * //
+// *  *  Log file: /tmp/ProofStress_XrcwBe                                 * //
 // *  ******************************************************************   * //
 // *   Test  1 : Open a session ................................... OK *   * //
 // *   Test  2 : Get session logs ................................. OK *   * //
@@ -44,7 +42,7 @@
 // *   Test  4 : Dataset handling with H1 files ................... OK *   * //
 // *   Test  5 : H1: chain processing ............................. OK *   * //
 // *   Test  6 : H1: file collection processing ................... OK *   * //
-// *   Test  7 : H1: file collection, TPacketizer ................. OK *   * //
+// *   Test  7 : H1: file collection, TPacketizerAdaptive ......... OK *   * //
 // *   Test  8 : H1: by-name processing ........................... OK *   * //
 // *   Test  9 : H1: multi dataset processing ..................... OK *   * //
 // *   Test 10 : H1: multi dataset and entry list ................. OK *   * //
@@ -56,7 +54,7 @@
 // *   Test 16 : Admin functionality .............................. OK *   * //
 // *   Test 17 : Dynamic sub-mergers functionality ................ OK *   * //
 // *   Test 18 : Event range processing ........................... OK *   * //
-// *   Test 19 : Event range, TPacketizer ......................... OK *   * //
+// *   Test 19 : Event range, TPacketizerAdaptive ................. OK *   * //
 // *   Test 20 : File-resident output: merge ...................... OK *   * //
 // *   Test 21 : File-resident output: merge w/ submergers ........ OK *   * //
 // *   Test 22 : File-resident output: create dataset ............. OK *   * //
@@ -72,8 +70,8 @@
 // *                                                                       * //
 // * The application redirects the processing logs to a log file which is  * //
 // * normally deleted at the end of a successful run; if the test fails    * //
-// * the caller is asked if they want to keep the log file; if they        * //
-// * specify a log file path of their choice, the log file is never        * //
+// * the caller is asked if she/he wants to keep the log file; if the      * //
+// * specifies a log file path of her/his choice, the log file is never    * //
 // * deleted.                                                              * //
 // *                                                                       * //
 // * SKIPPED means that the test cannot be run.                            * //
@@ -203,7 +201,7 @@ static TString gPack2("/proof/packtest2.par");
 int stressProof(const char *url = 0,
                 const char *tests = 0, Int_t nwrks = -1,
                 const char *verbose = "1", const char *logfile = 0,
-                Bool_t dyn = kFALSE, Bool_t skipds = kTRUE,
+                Bool_t dyn = kFALSE, Bool_t skipds = kTRUE, 
                 const char *h1src = 0, const char *eventsrc = 0,
                 Bool_t dryrun = kFALSE, Bool_t showcpu = kFALSE,
                 Bool_t clearcache = kFALSE, Bool_t useprogress = kTRUE,
@@ -328,7 +326,7 @@ int main(int argc,const char *argv[])
          if (i+1 == argc || argv[i+1][0] == '-') {
             printf(" -l should be followed by a path: ignoring \n");
             i++;
-         } else {
+         } else { 
             logfile = argv[i+1];
             i += 2;
          }
@@ -359,7 +357,7 @@ int main(int argc,const char *argv[])
          if (i+1 == argc || argv[i+1][0] == '-') {
             printf(" -t should be followed by a string or a number: ignoring \n");
             i++;
-         } else {
+         } else { 
             tests = argv[i+1];
             i += 2;
          }
@@ -367,7 +365,7 @@ int main(int argc,const char *argv[])
          if (i+1 == argc || argv[i+1][0] == '-') {
             printf(" -h1 should be followed by a path: ignoring \n");
             i++;
-         } else {
+         } else { 
             h1src = argv[i+1];
             i += 2;
          }
@@ -375,7 +373,7 @@ int main(int argc,const char *argv[])
          if (i+1 == argc || argv[i+1][0] == '-') {
             printf(" -event should be followed by a path: ignoring \n");
             i++;
-         } else {
+         } else { 
             eventsrc = argv[i+1];
             i += 2;
          }
@@ -398,7 +396,7 @@ int main(int argc,const char *argv[])
          if (i+1 == argc || argv[i+1][0] == '-') {
             printf(" -tut should be followed by a path: ignoring \n");
             i++;
-         } else {
+         } else { 
             tutdir = argv[i+1];
             i += 2;
          }
@@ -457,7 +455,7 @@ void PrintEmptyProgress(Long64_t, Long64_t, Float_t, Long64_t)
    // Dummy PrintProgress
    return;
 }
-
+   
 // Guard class
 class SwitchProgressGuard {
 public:
@@ -539,10 +537,10 @@ class RunTimes {
    Double_t fCpu;
    Double_t fReal;
    RunTimes(Double_t c = -1., Double_t r = -1.) : fCpu(c), fReal(r) { }
-
+   
    RunTimes &operator=(const RunTimes &rt) { fCpu = rt.fCpu; fReal = rt.fReal; return *this; }
    void Set(Double_t c = -1., Double_t r = -1.) { if (c > -1.) fCpu = c; if (r > -1.) fReal = r; }
-   void Print(const char *tag = "") { printf("%s real: %f s, cpu: %f s\n", tag, fReal, fCpu); }
+   void Print(const char *tag = "") { printf("%s real: %f s, cpu: %f s\n", tag, fReal, fCpu); }  
 };
 RunTimes operator-(const RunTimes &rt1, const RunTimes &rt2) {
    RunTimes rt(rt1.fCpu - rt2.fCpu, rt1.fReal - rt2.fReal);
@@ -566,7 +564,7 @@ class ProofTest : public TNamed {
    Double_t        fRefReal; // Ref Real time used for PROOF marks
    Double_t        fProofMarks; // PROOF marks
    Bool_t          fUseForMarks; // Use in the calculation of the average PROOF marks
-
+   
    static Double_t gRefReal[PT_NUMTEST]; // Reference Cpu times
 
 public:
@@ -587,7 +585,7 @@ class ProofTest : public TNamed {
    Int_t  Num() const { return fSeq; }
 
    Int_t  Run(Bool_t dryrun = kFALSE, Bool_t showcpu = kFALSE);
-
+   
    Double_t ProofMarks() const { return fProofMarks; }
    Bool_t UseForMarks() const { return fUseForMarks; }
 };
@@ -601,8 +599,8 @@ Double_t ProofTest::gRefReal[PT_NUMTEST] = {
    0.276155,   // #4:  Dataset handling with H1 files
    5.355514,   // #5:  H1: chain processing
    2.414207,   // #6:  H1: file collection processing
-   3.381990,   // #7:  H1: file collection, TPacketizer
-   3.227942,   // #8:  H1: by-name processing
+   3.381990,   // #7:  H1: file collection, TPacketizerAdaptive 
+   3.227942,   // #8:  H1: by-name processing 
    3.944204,   // #9:  H1: multi dataset processing
    9.146988,   // #10: H1: multi dataset and entry list
    2.703881,   // #11: Package management with 'event'
@@ -613,7 +611,7 @@ Double_t ProofTest::gRefReal[PT_NUMTEST] = {
    0.349625,   // #16: Admin functionality
    0.989456,   // #17: Dynamic sub-mergers functionality
    11.23798,   // #18: Event range processing
-   6.087582,   // #19: Event range, TPacketizer
+   6.087582,   // #19: Event range, TPacketizerAdaptive
    2.489555,   // #20: File-resident output: merge
    0.180897,   // #21: File-resident output: merge w/ submergers
    1.417233,   // #22: File-resident output: create dataset
@@ -803,7 +801,7 @@ typedef struct ptoption {
    Int_t fTwo;
 } PT_Option_t;
 
-static PT_Packetizer_t gStd_Old = { "TPacketizer", 0 };
+static PT_Packetizer_t gStd_Old = { "TPacketizerAdaptive", 1 };
 
 //_____________________________________________________________________________
 int stressProof(const char *url, const char *tests, Int_t nwrks,
@@ -818,7 +816,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
 
    // Use defaults or environment settings where required
    if (!url) {
-      url = getenv("STRESSPROOF_URL");
+      url = getenv("STRESSPROOF_URL"); 
       if (!url) url = urldef;
    }
    // Set dynamic mode
@@ -881,14 +879,14 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
    } else {
      gSkipDataSetTest = gLocalCluster;
    }
-
+   
    // Clear cache
    gClearCache = clearcache;
 
    // Log file path
    Bool_t usedeflog = kTRUE;
    FILE *flog = 0;
-   if (!logfile) logfile = getenv("STRESSPROOF_LOGFILE");
+   if (!logfile) logfile = getenv("STRESSPROOF_LOGFILE"); 
    if (logfile && strlen(logfile) > 0 && !dryrun) {
       usedeflog = kFALSE;
       glogfile = logfile;
@@ -919,41 +917,16 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
          }
       }
    }
-
-   // Temp dir for this stress run
-#if defined(R__MACOSX)
-   // Force '/tmp' under macosx, to avoid problems with lengths and symlinks
-   TString tmpdir("/tmp"), uspid;
-#else
-   TString tmpdir(gSystem->TempDirectory()), uspid;
-#endif
-   UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid());
-   if (!ug) {
-      printf("\n >>> Test failure: could not get user info");
-      return -1;
-   }
-   if (!tmpdir.EndsWith(ug->fUser.Data())) {
-      uspid.Form("/%s/stressProof-%d", ug->fUser.Data(), gSystem->GetPid());
-      delete ug;
-   } else {
-      uspid.Form("/stressProof-%d", gSystem->GetPid());
-   }
-   gtutdir.Form("%s%s", tmpdir.Data(), uspid.Data());
-   if (gSystem->AccessPathName(gtutdir)) {
-      if (gSystem->mkdir(gtutdir, kTRUE) != 0) {
-         printf("\n >>> Failure: could not assert/create the temporary directory"
-                " for the tutorial (%s)", gtutdir.Data());
+   if (usedeflog && !dryrun) {
+      glogfile = "ProofStress_";
+      if (!(flog = gSystem->TempFileName(glogfile, gSystem->TempDirectory()))) {
+         printf(" >>> Cannot create a temporary log file on %s - exit\n", gSystem->TempDirectory());
          return 1;
       }
-   }
-   printf("*  Temp dir for this run: %s \n", gtutdir.Data());
-   printf("******************************************************************\n");
-
-   if (usedeflog && !dryrun) {
-      glogfile.Form("%s/main.log", gtutdir.Data());
+      fclose(flog);
    }
    if (gverbose > 0) {
-      printf("*  Main log file: %s\n", glogfile.Data());
+      printf("*  Log file: %s\n", glogfile.Data());
       if (cleanlog)
          printf("*  (NB: file will be removed if test is successful)              *\n");
       printf("******************************************************************\n");
@@ -971,7 +944,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
       printf("*  PROOF-Lite session (tests #15 and #16 skipped)               **\n");
       printf("******************************************************************\n");
    }
-   if (!h1src) h1src = getenv("STRESSPROOF_H1SRC");
+   if (!h1src) h1src = getenv("STRESSPROOF_H1SRC"); 
    if (h1src && strlen(h1src)) {
       if (!strcmp(h1src, "download") && extcluster) {
          if (gverbose > 0) {
@@ -987,7 +960,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
          gh1ok = kFALSE;
       }
    }
-   if (!eventsrc) eventsrc = getenv("STRESSPROOF_EVENT");
+   if (!eventsrc) eventsrc = getenv("STRESSPROOF_EVENT"); 
    if (eventsrc && strlen(eventsrc)) {
       if (!strcmp(eventsrc, "download") && extcluster) {
          if (gverbose > 0) {
@@ -1003,7 +976,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
          geventok = kFALSE;
       }
    }
-   if (!tutdir) tutdir = getenv("STRESSPROOF_TUTORIALDIR");
+   if (!tutdir) tutdir = getenv("STRESSPROOF_TUTORIALDIR"); 
    if (tutdir && strlen(tutdir)) {
       if (!(gTutDir == tutdir)) {
          if (gverbose > 0) {
@@ -1042,8 +1015,8 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
    testList->Add(new ProofTest("H1: chain processing", 5, &PT_H1Http, 0, "1", "h1analysis", kTRUE));
    // H1 analysis over HTTP (file collection)
    testList->Add(new ProofTest("H1: file collection processing", 6, &PT_H1FileCollection, 0, "1", "h1analysis", kTRUE));
-   // H1 analysis over HTTP: classic packetizer
-   testList->Add(new ProofTest("H1: file collection, TPacketizer", 7,
+   // H1 analysis over HTTP: adaptive packetizer
+   testList->Add(new ProofTest("H1: file collection, TPacketizerAdaptive", 7,
                                &PT_H1FileCollection, (void *)&gStd_Old, "1", "h1analysis", kTRUE));
    // H1 analysis over HTTP by dataset name
    testList->Add(new ProofTest("H1: by-name processing", 8, &PT_H1DataSet, 0, "1,4", "h1analysis", kTRUE));
@@ -1070,8 +1043,8 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
    // Test range chain and dataset processing EventProc
    testList->Add(new ProofTest("Event range processing", 18,
                                &PT_EventRange, 0, "1,11", "ProofEventProc,ProcFileElements", kTRUE));
-   // Test range chain and dataset processing EventProc with TPacketizer
-   testList->Add(new ProofTest("Event range, TPacketizer", 19,
+   // Test range chain and dataset processing EventProc with TPacketizerAdaptive
+   testList->Add(new ProofTest("Event range, TPacketizerAdaptive", 19,
                                &PT_EventRange, (void *)&gStd_Old, "1,11", "ProofEventProc,ProcFileElements", kTRUE));
    // Test TProofOutputFile technology for ntuple creation
    testList->Add(new ProofTest("File-resident output: merge", 20, &PT_POFNtuple, 0, "1", "ProofNtuple", kTRUE));
@@ -1124,7 +1097,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
    ProofTest *t = 0, *treq = 0;
    TIter nxt(testList);
    Bool_t all = kTRUE;
-   if (!tests) tests = getenv("STRESSPROOF_TESTS");
+   if (!tests) tests = getenv("STRESSPROOF_TESTS"); 
    if (tests && strlen(tests)) {
       TString tts(tests), tsg, ts, ten;
       Ssiz_t from = 0;
@@ -1222,7 +1195,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
          printf("*                                                               **\r");
          printf("*  Running only test(s) %s (and related)\n", ten.Data());
          printf("******************************************************************\n");
-      }
+      }      
    }
    if (all) {
       // Clean all the selectors
@@ -1247,7 +1220,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
       printf("******************************************************************\n");
       return 0;
    }
-
+   
    // Add the ACLiC option to the selector strings
    gH1Sel += "+";
    gEventSel += "+";
@@ -1306,10 +1279,9 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
          }
       } else {
          printf("+++ Warning: could not attach to manager to get the session logs\n");
-      }
+      }         
       printf("******************************************************************\n");
-      printf(" Main log file kept at %s\n", glogfile.Data());
-      printf(" (Proof logs in %s)\n", logfiles.Data());
+      printf(" Main log file kept at %s (Proof logs in %s)\n", glogfile.Data(), logfiles.Data());
       if (catlog) {
 
          // Display all logfiles directly on this terminal. Useful for getting
@@ -1368,7 +1340,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
             }
          }
       if (navg > 0) avgmarks /= navg;
-
+      
       gProof->GetStatistics((gverbose > 0));
       // Reference time measured on a HP DL580 24 core (4 x Intel(R) Xeon(R) CPU X7460
       // @ 2.132 GHz, 48GB RAM, 1 Gb/s NIC) with 4 workers.
@@ -1403,7 +1375,7 @@ int stressProof(const char *url, const char *tests, Int_t nwrks,
 //_____________________________________________________________________________
 Int_t PT_H1ReleaseCache(const char *h1src)
 {
-   // Release memory cache associated with the H1 files at 'h1src', if it
+   // Release memory cache associated with the H1 files at 'h1src', if it 
    // makes any sense, i.e. are local ...
 
    if (!h1src || strlen(h1src) <= 0) {
@@ -1444,7 +1416,7 @@ Int_t PT_H1AssertFiles(const char *h1src)
    // Locality
    TUrl u(h1src, kTRUE);
    gh1local = (!strcmp(u.GetProtocol(), "file")) ? kTRUE : kFALSE;
-
+   
    gh1sep = '/';
    // Special cases
    if (!strncmp(h1src,"download",8)) {
@@ -1525,14 +1497,14 @@ Int_t PT_H1AssertFiles(const char *h1src)
 //_____________________________________________________________________________
 Int_t PT_EventReleaseCache(const char *eventsrc, Int_t nf = 10)
 {
-   // Release memory cache associated with the event files at 'eventsrc', if it
+   // Release memory cache associated with the event files at 'eventsrc', if it 
    // makes any sense, i.e. are local ...
 
    if (!eventsrc || strlen(eventsrc) <= 0) {
       printf("\n >>> Test failure: src dir undefined\n");
       return -1;
    }
-
+   
    if (nf > 50) {
       printf("\n >>> Test failure: max 50 event files can be checked\n");
       return -1;
@@ -1563,7 +1535,7 @@ Int_t PT_EventAssertFiles(const char *eventsrc, Int_t nf = 10)
       printf("\n >>> Test failure: src dir undefined\n");
       return -1;
    }
-
+   
    if (nf > 50) {
       printf("\n >>> Test failure: max 50 event files can be checked\n");
       return -1;
@@ -1628,7 +1600,7 @@ Int_t PT_EventAssertFiles(const char *eventsrc, Int_t nf = 10)
    geventok = kTRUE;
    return 0;
 }
-
+      
 //_____________________________________________________________________________
 Int_t PT_AssertTutorialDir(const char *tutdir)
 {
@@ -1673,7 +1645,7 @@ Int_t PT_AssertTutorialDir(const char *tutdir)
    gAuxSel.Insert(0, tutdir);
    gSystem->ExpandPathName(gAuxSel);
    if (gSystem->AccessPathName(gAuxSel)) return -1;
-
+   
    // Special class
    gProcFileElem.Insert(0, tutdir);
    gSystem->ExpandPathName(gProcFileElem);
@@ -1775,7 +1747,7 @@ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname)
       printf("\n >>> Test failure: output list not found\n");
       return -1;
    }
-
+   
    // Get the file collection
    PutPoint();
    TFileCollection *fc = dynamic_cast<TFileCollection *>(out->FindObject(dsname));
@@ -1784,7 +1756,7 @@ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname)
              " found in the output list\n", dsname);
       return -1;
    }
-
+   
    // Check the default tree name
    const char *tname = "/ntuple";
    PutPoint();
@@ -1801,7 +1773,7 @@ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname)
              fc->GetTotalEntries(tname), nevt);
       return -1;
    }
-
+   
    // Check 'pz' histo
    TH1F *hpx = new TH1F("PT_px", "PT_px", 20, -5., 5.);
    PutPoint();
@@ -1811,7 +1783,7 @@ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname)
              hpx->GetMean(), hpx->GetRMS());
       return -1;
    }
-
+      
    // Check 'pz' histo
    TH1F *hpz = new TH1F("PT_pz", "PT_pz", 20, 0., 20.);
    PutPoint();
@@ -1835,10 +1807,10 @@ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname)
    SafeDelete(hpx);
    SafeDelete(hpz);
    SafeDelete(hpr);
-
+     
    // Clear dsname
    gProof->ClearData(TProof::kDataset |TProof::kForceClear, dsname);
-
+   
    // Done
    PutPoint();
    return 0;
@@ -1911,7 +1883,7 @@ Int_t PT_CheckH1(TQueryResult *qr, Int_t irun = 0)
 }
 
 //_____________________________________________________________________________
-Int_t PT_CheckEvent(TQueryResult *qr, const char *pack = "TPacketizerAdaptive")
+Int_t PT_CheckEvent(TQueryResult *qr, const char *pack = "TPacketizer")
 {
    // Check the result of the EventProc analysis
 
@@ -1977,7 +1949,7 @@ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt)
       printf("\n >>> Test failure: TProofOutputFile not found in the output list\n");
       return -1;
    }
-
+   
    // Get the file full path
    TString outputFile(pof->GetOutputFileName());
    TString outputName(pof->GetName());
@@ -1997,7 +1969,7 @@ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt)
       printf("\n >>> Test failure: 'ntuple' not found\n");
       return -1;
    }
-
+   
    // Check the ntuple content by filling some histos
    TH1F *h1s[3] = {0};
    h1s[0] = new TH1F("h1_1", "3*px+2 with px**2+py**2>1", 50, -15., 15.);
@@ -2017,7 +1989,7 @@ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt)
       if (px*px+py*py > 4. && py > 0.) h1s[2]->Fill(1.3*px + 2.);
       // Go next
       ent++;
-   }
+   } 
 
    Int_t rch1s = 0;
    TString emsg;
@@ -2037,10 +2009,10 @@ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt)
          rch1s = -1;
          break;
       }
-   }
+   }   
 
    // Cleanup
-   for (Int_t i = 0; i < 3; i++) delete h1s[i];
+   for (Int_t i = 0; i < 3; i++) delete h1s[i];   
    f->Close();
    delete f;
 
@@ -2049,7 +2021,7 @@ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt)
       printf("\n >>> Test failure: %s\n", emsg.Data());
       return -1;
    }
-
+   
    // Done
    PutPoint();
    return 0;
@@ -2082,7 +2054,7 @@ Int_t PT_CheckDataset(TQueryResult *qr, Long64_t nevt)
       printf("\n >>> Test failure: dataset '%s' not found in the repository\n", dsname);
       return -1;
    }
-   // ... and that the default tree is 'ntuple'
+   // ... and that the default tree is 'ntuple' 
    gProof->SetDataSetTreeName(dsname, "ntuple");
 
    // Create the histos
@@ -2100,7 +2072,7 @@ Int_t PT_CheckDataset(TQueryResult *qr, Long64_t nevt)
       PutPoint();
       gProof->DrawSelect(dsname, "1.3*px+2 >> h1s2","(px^2+py^2>4) && py>0");
    }
-
+    
    Int_t rch1s = 0;
    TString emsg;
    // Check the histogram entries and mean values
@@ -2109,7 +2081,7 @@ Int_t PT_CheckDataset(TQueryResult *qr, Long64_t nevt)
    Double_t prec = 10. / TMath::Sqrt(nevt);  // ~10 sigma ... conservative
    for (Int_t i = 0; i < 3; i++) {
       Double_t ent = h1s[i]->GetEntries();
-      if (TMath::Abs(ent - hent[i] * nevt) / ent > prec) {
+      if (TMath::Abs(ent - hent[i] * nevt) / ent > prec) { 
          emsg.Form("'%s' histo: wrong number"
                " of entries (%lld: expected %lld)",
                 h1s[i]->GetName(), (Long64_t) ent, (Long64_t)(hent[i] *nevt));
@@ -2123,17 +2095,17 @@ Int_t PT_CheckDataset(TQueryResult *qr, Long64_t nevt)
          rch1s = -1;
          break;
       }
-   }
+   }   
 
    // Cleanup
-   for (Int_t i = 0; i < 3; i++) delete h1s[i];
+   for (Int_t i = 0; i < 3; i++) delete h1s[i];   
 
    // Check the result
    if (rch1s != 0) {
       printf("\n >>> Test failure: %s\n", emsg.Data());
       return -1;
    }
-
+   
    // Done
    PutPoint();
    return 0;
@@ -2197,7 +2169,7 @@ Int_t PT_CheckFriends(TQueryResult *qr, Long64_t nevt, bool withfriends)
          rchs = -1;
          break;
       }
-   }
+   }   
 
    if (rchs != 0) {
       printf("\n >>> Test failure: %s\n", emsg.Data());
@@ -2222,6 +2194,39 @@ Int_t PT_Open(void *args, RunTimes &tt)
       return -1;
    }
 
+   // Temp dir for PROOF tutorials
+   PutPoint();
+#if defined(R__MACOSX) 
+   // Force '/tmp' under macosx, to avoid problems with lengths and symlinks
+   TString tmpdir("/tmp"), uspid;
+#else
+   TString tmpdir(gSystem->TempDirectory()), uspid;
+#endif
+   UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid());
+   if (!ug) {
+      printf("\n >>> Test failure: could not get user info");
+      return -1;      
+   }
+   if (!tmpdir.EndsWith(ug->fUser.Data())) {
+      uspid.Form("/%s/%d", ug->fUser.Data(), gSystem->GetPid());
+      delete ug;
+   } else {
+      uspid.Form("/%d", gSystem->GetPid());
+   }
+   tmpdir += uspid;
+#if !defined(R__MACOSX) 
+   gtutdir.Form("%s/.proof-tutorial", tmpdir.Data());
+#else
+   gtutdir.Form("%s/.proof", tmpdir.Data());
+#endif
+   if (gSystem->AccessPathName(gtutdir)) {
+      if (gSystem->mkdir(gtutdir, kTRUE) != 0) {
+         printf("\n >>> Test failure: could not assert/create the temporary directory"
+                " for the tutorial (%s)", gtutdir.Data());
+         return -1;
+      }
+   }
+
    // String to initialize the dataset manager
    TString dsetmgrstr;
    dsetmgrstr.Form("file dir:%s/datasets opt:-Cq:As:Sb:", gtutdir.Data());
@@ -2239,7 +2244,7 @@ Int_t PT_Open(void *args, RunTimes &tt)
       printf("\n >>> Test failure: could not start the session\n");
       return -1;
    }
-
+   
    // Re-check locality: if the logged user name is different from the local one, we may
    // not have all the rights we need, so we go no-local
    if (gLocalCluster) {
@@ -2249,7 +2254,7 @@ Int_t PT_Open(void *args, RunTimes &tt)
          delete pw;
       }
    }
-
+   
    // Check if it is in dynamic startup mode
    Int_t dyn = 0;
    p->GetRC("Proof.DynamicStartup", dyn);
@@ -2297,7 +2302,7 @@ Int_t PT_Open(void *args, RunTimes &tt)
 
    // Fill times
    PT_GetLastTimes(tt);
-
+   
    // Done
    PutPoint();
    return 0;
@@ -2350,7 +2355,7 @@ Int_t PT_Simple(void *opts, RunTimes &tt)
    }
 
    PT_Option_t *ptopt = (PT_Option_t *) opts;
-
+   
    // Setup submergers if required
    if (ptopt && ptopt->fOne > 0) {
       gProof->SetParameter("PROOF_UseMergers", 0);
@@ -2408,7 +2413,7 @@ Int_t PT_OutputHandlingViaFile(void *opts, RunTimes &tt)
    PutPoint();
 
    PT_Option_t *ptopt = (PT_Option_t *) opts;
-
+   
    // Setup submergers if required
    if (ptopt && ptopt->fOne > 0) {
       gProof->SetParameter("PROOF_UseMergers", 0);
@@ -2447,7 +2452,7 @@ Int_t PT_OutputHandlingViaFile(void *opts, RunTimes &tt)
       // Remove file
       gSystem->Unlink("proofsimple.root");
    }
-
+      
    // Test dataset creationg with a ntuple
    const char *dsname = "PT_ds_proofsimple";
    if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear();
@@ -2562,7 +2567,7 @@ Int_t PT_H1FileCollection(void *arg, RunTimes &tt)
    // Are we asked to change the packetizer strategy?
    if (arg) {
       PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg;
-      if (strcmp(strategy->fName, "TPacketizerAdaptive")) {
+      if (strcmp(strategy->fName, "TPacketizer")) {
          gProof->SetParameter("PROOF_Packetizer", strategy->fName);
       } else {
          if (strategy->fType != 1)
@@ -2603,7 +2608,7 @@ Int_t PT_H1FileCollection(void *arg, RunTimes &tt)
       gProof->Process(fc, gH1Sel.Data());
       gTimer.Stop();
    }
-
+   
    // Restore settings
    gProof->DeleteParameters("PROOF_Packetizer");
    gProof->DeleteParameters("PROOF_PacketizerStrategy");
@@ -2743,7 +2748,7 @@ Int_t PT_H1MultiDSetEntryList(void *, RunTimes &tt)
 
    // Set/unset the parallel unzip flag
    AssertParallelUnzip();
-
+   
    // Multiple dataset used to create the entry list
    TString dsname("h1dseta|h1dsetb");
 
@@ -2764,7 +2769,7 @@ Int_t PT_H1MultiDSetEntryList(void *, RunTimes &tt)
       gProof->Process(dsname, gH1Sel.Data(), "fillList=elist.root");
       gTimer.Stop();
    }
-
+   
    // Cleanup entry-list from the input list
    TIter nxi(gProof->GetInputList());
    TObject *o = 0;
@@ -3417,7 +3422,7 @@ Int_t PT_PackageArguments(void *, RunTimes &tt)
 //_____________________________________________________________________________
 Int_t PT_H1SimpleAsync(void *arg, RunTimes &tt)
 {
-   // Test run for the H1 and Simple analysis in asynchronous mode
+   // Test run for the H1 and Simple analysis in asynchronous mode 
 
    // Checking arguments
    if (!gProof) {
@@ -3440,7 +3445,7 @@ Int_t PT_H1SimpleAsync(void *arg, RunTimes &tt)
    // Are we asked to change the packetizer strategy?
    if (arg) {
       PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg;
-      if (strcmp(strategy->fName, "TPacketizerAdaptive")) {
+      if (strcmp(strategy->fName, "TPacketizer")) {
          gProof->SetParameter("PROOF_Packetizer", strategy->fName);
       } else {
          if (strategy->fType != 1)
@@ -3743,7 +3748,7 @@ Int_t PT_AdminFunc(void *, RunTimes &tt)
 Int_t PT_EventRange(void *arg, RunTimes &tt)
 {
    // Test processing of sub-samples (entries-from-first) from files with the
-   // 'event' structures
+   // 'event' structures 
 
    // Checking arguments
    PutPoint();
@@ -3756,10 +3761,10 @@ Int_t PT_EventRange(void *arg, RunTimes &tt)
    AssertParallelUnzip();
 
    // Are we asked to change the packetizer strategy?
-   const char *pack = "TPacketizerAdaptive";
+   const char *pack = "TPacketizer";
    if (arg) {
       PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg;
-      if (strcmp(strategy->fName, "TPacketizerAdaptive")) {
+      if (strcmp(strategy->fName, "TPacketizer")) {
          gProof->SetParameter("PROOF_Packetizer", strategy->fName);
          pack = strategy->fName;
       } else {
@@ -3814,7 +3819,7 @@ Int_t PT_EventRange(void *arg, RunTimes &tt)
    TString flst = TString::Format("%s/event_%d.root?lst=%lld", geventsrc.Data(), ilst, elst);
    gProof->SetParameter("Range_Last_File", flst.Data());
    gProof->SetParameter("Range_Num_Files", (Int_t) (ilst - ifst + 1));
-
+   
    // Process
    PutPoint();
    chain->SetProof();
@@ -3850,7 +3855,7 @@ Int_t PT_EventRange(void *arg, RunTimes &tt)
    // Register the dataset
    PutPoint();
    gProof->RegisterDataSet("dsevent", fc);
-
+   
    // Check the result
    if (!gProof->ExistsDataSet("dsevent")) {
       printf("\n >>> Test failure: could not register 'dsevent'\n");
@@ -3870,7 +3875,7 @@ Int_t PT_EventRange(void *arg, RunTimes &tt)
       printf("\n >>> Test failure: could not clear memory cache for the event files\n");
       return -1;
    }
-
+   
    // Process
    PutPoint();
    {  SwitchProgressGuard spg;
@@ -3890,7 +3895,7 @@ Int_t PT_EventRange(void *arg, RunTimes &tt)
 
    // The runtimes
    PT_GetLastProofTimes(tt);
-
+  
    // Check the results
    PutPoint();
    return PT_CheckEvent(gProof->GetQueryResult(), pack);
@@ -3910,7 +3915,7 @@ Int_t PT_POFNtuple(void *opts, RunTimes &tt)
    }
 
    PT_Option_t *ptopt = (PT_Option_t *) opts;
-
+   
    // Setup submergers if required
    if (ptopt && ptopt->fTwo > 0) {
       gProof->SetParameter("PROOF_UseMergers", 0);
@@ -3924,7 +3929,7 @@ Int_t PT_POFNtuple(void *opts, RunTimes &tt)
    gProof->SetInputDataFile(gNtpRndm);
    // Set the related parameter
    gProof->SetParameter("PROOF_USE_NTP_RNDM","yes");
-
+   
    // Define the number of events and histos
    Long64_t nevt = 1000;
 
@@ -3967,7 +3972,7 @@ Int_t PT_POFDataset(void *, RunTimes &tt)
       printf("\n >>> Test failure: no PROOF session found\n");
       return -1;
    }
-
+   
    const char *dsname = "testNtuple";
    // Clean-up any existing dataset with that name
    if (gProof->ExistsDataSet(dsname)) gProof->RemoveDataSet(dsname);
@@ -4161,7 +4166,7 @@ Int_t PT_Friends(void *sf, RunTimes &tt)
       printf("\n >>> Test failure: could not get the list of information about the workers\n");
       return -1;
    }
-
+   
    // Create the map
    TString fntree;
    TMap *files = new TMap;
@@ -4232,13 +4237,13 @@ Int_t PT_Friends(void *sf, RunTimes &tt)
             dsetf->Add(os->GetName());
       }
    }
-
+   
    // If we did not found the main or the friend meta info we fail
    if (!foundMain || !foundFriend) {
       printf("\n >>> Test failure: 'main' or 'friend' meta info missing!\n");
       return -1;
    }
-
+   
    // Connect the two datasets for processing
    dset->AddFriend(dsetf, "friend");
 
@@ -4296,7 +4301,7 @@ Int_t PT_TreeSubDirs(void*, RunTimes &tt)
       printf("\n >>> Test failure: could not get the list of information about the workers\n");
       return -1;
    }
-
+   
    // Create the map
    TString fntree;
    TMap *files = new TMap;
@@ -4352,7 +4357,7 @@ Int_t PT_TreeSubDirs(void*, RunTimes &tt)
       }
    }
    dset->SetProof();
-
+   
    // If we did not found the main or the friend meta info we fail
    if (!foundMain) {
       printf("\n >>> Test failure: 'main' meta info missing!\n");

From b9728a1b31786cb9e9c8ba60e99ddc0c9c447303 Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Sat, 28 Feb 2015 23:00:53 +0100
Subject: [PATCH 112/200] ProofX: change default for socket reconnection to OFF

---
 proof/proofx/src/TXSocket.cxx     | 2 +-
 proof/proofx/src/TXUnixSocket.cxx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/proof/proofx/src/TXSocket.cxx b/proof/proofx/src/TXSocket.cxx
index 90dd66a8b3fc7..7180786354b1e 100644
--- a/proof/proofx/src/TXSocket.cxx
+++ b/proof/proofx/src/TXSocket.cxx
@@ -2093,7 +2093,7 @@ Int_t TXSocket::Reconnect()
                         fUrl.Data(), fConn->GetLogConnID());
    }
 
-   Int_t tryreconnect = gEnv->GetValue("TXSocket.Reconnect", 1);
+   Int_t tryreconnect = gEnv->GetValue("TXSocket.Reconnect", 0);
    if (tryreconnect == 0 || fXrdProofdVersion < 1005) {
       if (tryreconnect == 0)
          Info("Reconnect","%p: reconnection attempts explicitly disabled!", this);
diff --git a/proof/proofx/src/TXUnixSocket.cxx b/proof/proofx/src/TXUnixSocket.cxx
index 7d30f4366af19..6937399099e34 100644
--- a/proof/proofx/src/TXUnixSocket.cxx
+++ b/proof/proofx/src/TXUnixSocket.cxx
@@ -69,7 +69,7 @@ Int_t TXUnixSocket::Reconnect()
                         fConn, (fConn ? fConn->IsValid() : 0), fUrl.Data());
    }
 
-   Int_t tryreconnect = gEnv->GetValue("TXSocket.Reconnect", 1);
+   Int_t tryreconnect = gEnv->GetValue("TXSocket.Reconnect", 0);
    if (tryreconnect == 0 || fXrdProofdVersion < 1005) {
       if (tryreconnect == 0)
          Info("Reconnect","%p: reconnection attempts explicitly disabled!", this);

From af663410a87de81f8af5eeff79e1358314c07d5b Mon Sep 17 00:00:00 2001
From: Gerardo Ganis <Gerardo.Ganis@cern.ch>
Date: Sat, 28 Feb 2015 23:02:01 +0100
Subject: [PATCH 113/200] ProofPlayer: remove remnant from debug session

---
 proof/proofplayer/src/TPerfStats.cxx | 2 --
 1 file changed, 2 deletions(-)

diff --git a/proof/proofplayer/src/TPerfStats.cxx b/proof/proofplayer/src/TPerfStats.cxx
index 94895ae979e96..33c75dae84a2d 100644
--- a/proof/proofplayer/src/TPerfStats.cxx
+++ b/proof/proofplayer/src/TPerfStats.cxx
@@ -159,8 +159,6 @@ TPerfStats::TPerfStats(TList *input, TList *output)
    while (TSlaveInfo *si = dynamic_cast<TSlaveInfo*>(nextslaveinfo()))
       if (si->fStatus == TSlaveInfo::kActive) fSlaves++;
 
-   fSlaves = 8;
-
    PDB(kMonitoring,1) Info("TPerfStats", "Statistics for %d slave(s)", fSlaves);
 
    fDoHist = (input->FindObject("PROOF_StatsHist") != 0);

From e9f56ac531bfddf1c733a8c427641ec80bc8dd40 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Mon, 2 Mar 2015 11:17:41 +0100
Subject: [PATCH 114/200] Fix the STL type enumerator adding fwd list at the
 end

therewith re-gaining backward compatibility with TStreamerElements
written in the past.
---
 core/metautils/inc/ESTLType.h     | 17 ++++++++++-------
 core/metautils/src/TClassEdit.cxx | 16 +++++++++-------
 core/metautils/src/TMetaUtils.cxx | 12 +++++++-----
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/core/metautils/inc/ESTLType.h b/core/metautils/inc/ESTLType.h
index a9c491ca77f48..f4ff19e11bfd1 100644
--- a/core/metautils/inc/ESTLType.h
+++ b/core/metautils/inc/ESTLType.h
@@ -29,13 +29,16 @@ namespace ROOT {
       kNotSTL         = 0,
       kSTLvector      = 1,
       kSTLlist        = 2,
-      kSTLforwardlist = 3,
-      kSTLdeque       = 4,
-      kSTLmap         = 5,
-      kSTLmultimap    = 6,
-      kSTLset         = 7,
-      kSTLmultiset    = 8,
-      kSTLbitset      = 9,
+      kSTLdeque       = 3,
+      kSTLmap         = 4,
+      kSTLmultimap    = 5,
+      kSTLset         = 6,
+      kSTLmultiset    = 7,
+      kSTLbitset      = 8,
+      // Here the c++11 containers start. Order counts. For example,
+      // tstreamerelements in written rootfiles carry a value and we cannot
+      // introduce shifts.
+      kSTLforwardlist = 9,
       kSTLend         = 10,
       kSTLany         = 300 /* TVirtualStreamerInfo::kSTL */,
       kSTLstring      = 365 /* TVirtualStreamerInfo::kSTLstring */
diff --git a/core/metautils/src/TClassEdit.cxx b/core/metautils/src/TClassEdit.cxx
index e2a70fb9e6305..925a96950f066 100644
--- a/core/metautils/src/TClassEdit.cxx
+++ b/core/metautils/src/TClassEdit.cxx
@@ -412,16 +412,16 @@ ROOT::ESTLType TClassEdit::STLKind(const char *type, size_t len)
 
    //container names
    static const char *stls[] =
-      { "any", "vector", "list", "forward_list", "deque", "map", "multimap", "set", "multiset", "bitset", 0};
+      { "any", "vector", "list", "deque", "map", "multimap", "set", "multiset", "bitset", "forward_list", 0};
    static const size_t stllen[] =
-      { 3, 6, 4, 12, 5, 3, 8, 3, 8, 6, 0};
+      { 3, 6, 4, 5, 3, 8, 3, 8, 6, 12, 0};
    static const ROOT::ESTLType values[] =
       {  ROOT::kNotSTL, ROOT::kSTLvector,
-         ROOT::kSTLlist, ROOT::kSTLforwardlist,
-         ROOT::kSTLdeque,
+         ROOT::kSTLlist, ROOT::kSTLdeque,
          ROOT::kSTLmap, ROOT::kSTLmultimap,
          ROOT::kSTLset, ROOT::kSTLmultiset,
-         ROOT::kSTLbitset, ROOT::kNotSTL
+         ROOT::kSTLbitset, ROOT::kSTLforwardlist,
+         ROOT::kNotSTL
       };
 
    // kind of stl container
@@ -444,8 +444,8 @@ int   TClassEdit::STLArgs(int kind)
 //      Return number of arguments for STL container before allocator
 
    static const char  stln[] =// min number of container arguments
-      //     vector, list, deque, map, multimap, set, multiset, bitset
-      {    1,     1,    1,     1,   3,        3,   2,        2,      1 };
+      //     vector, list, deque, map, multimap, set, multiset, bitset, forward_list
+      {    1,     1,    1,     1,   3,        3,   2,        2,      1,            1};
 
    return stln[kind];
 }
@@ -1135,6 +1135,7 @@ bool TClassEdit::IsStdClass(const char *classname)
 
    if ( strncmp(classname,"vector<",strlen("vector<"))==0) return true;
    if ( strncmp(classname,"list<",strlen("list<"))==0) return true;
+   if ( strncmp(classname,"forward_list<",strlen("forward_list<"))==0) return true;
    if ( strncmp(classname,"deque<",strlen("deque<"))==0) return true;
    if ( strncmp(classname,"map<",strlen("map<"))==0) return true;
    if ( strncmp(classname,"multimap<",strlen("multimap<"))==0) return true;
@@ -1493,6 +1494,7 @@ string TClassEdit::InsertStd(const char *tname)
       "domain_error",
       "equal_to",
       "exception",
+      "forward_list",
       "fpos",
       "greater_equal",
       "greater",
diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx
index 928ebee10a291..5b7cef848b581 100644
--- a/core/metautils/src/TMetaUtils.cxx
+++ b/core/metautils/src/TMetaUtils.cxx
@@ -1835,7 +1835,9 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
       finalString << "      instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << "Pushback" << "<TStdBitsetHelper< " << classname.c_str() << " > >()));" << "\n";
 
       needCollectionProxy = true;
-   } else if (stl != 0 && ((stl>0 && stl<9) || (stl<0 && stl>-9)) )  {
+   } else if (stl != 0 &&
+              ((stl>0 && stl<10) || (stl<0 && stl>-10)) && // is an stl container
+              (stl != 8 && stl !=-8) ){     // is no bitset
       int idx = classname.find("<");
       int stlType = (idx!=(int)std::string::npos) ? TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
       const char* methodTCP=0;
@@ -4581,14 +4583,14 @@ ROOT::ESTLType ROOT::TMetaUtils::STLKind(const llvm::StringRef type)
    // Converts STL container name to number. vector -> 1, etc..
 
    static const char *stls[] =                  //container names
-      {"any","vector","list", "forward_list", "deque","map","multimap","set","multiset","bitset",0};
+      {"any","vector","list", "deque","map","multimap","set","multiset","bitset","forward_list",0};
    static const ROOT::ESTLType values[] =
       {ROOT::kNotSTL, ROOT::kSTLvector,
-       ROOT::kSTLlist, ROOT::kSTLforwardlist,
-       ROOT::kSTLdeque,
+       ROOT::kSTLlist, ROOT::kSTLdeque,
        ROOT::kSTLmap, ROOT::kSTLmultimap,
        ROOT::kSTLset, ROOT::kSTLmultiset,
-       ROOT::kSTLbitset, ROOT::kNotSTL
+       ROOT::kSTLbitset, ROOT::kSTLforwardlist,
+       ROOT::kNotSTL
       };
    //              kind of stl container
    for(int k=1;stls[k];k++) {if (type.equals(stls[k])) return values[k];}

From ae97a1737eeae4f23d2cfab31984ce66b3859d3a Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Mon, 2 Mar 2015 11:54:33 -0600
Subject: [PATCH 115/200] Avoid double counting size of 'in-memory' basket.

Even when the TTree was not connected to a file TBranch::WriteBasket would record the size of the basket in fTotBytes,
when/if the TTree was later written to a file, the size of the basket would be added _again_ to fTotBytes by WriteBasket
---
 tree/tree/src/TBranch.cxx | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tree/tree/src/TBranch.cxx b/tree/tree/src/TBranch.cxx
index 1417b5d78822f..35302ca97173b 100644
--- a/tree/tree/src/TBranch.cxx
+++ b/tree/tree/src/TBranch.cxx
@@ -2567,11 +2567,12 @@ Int_t TBranch::WriteBasket(TBasket* basket, Int_t where)
 
       reusebasket = basket;
       reusebasket->Reset();
+
+      fZipBytes += nout;
+      fTotBytes += addbytes;
+      fTree->AddTotBytes(addbytes);
+      fTree->AddZipBytes(nout);
    }
-   fZipBytes += nout;
-   fTotBytes += addbytes;
-   fTree->AddTotBytes(addbytes);
-   fTree->AddZipBytes(nout);
 
    if (where==fWriteBasket) {
       ++fWriteBasket;

From a506b2e42593b0a79cf88ffdfe12342b70c09574 Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Tue, 3 Mar 2015 10:09:09 +0100
Subject: [PATCH 116/200] Fix default constructor initialisation of RooTFn*
 classes. This fixes he problem reported at
 https://root.cern.ch/phpBB3/viewtopic.php?f=15&t=19314

---
 roofit/roofit/inc/RooTFnBinding.h      | 12 ++++----
 roofit/roofit/inc/RooTFnPdfBinding.h   |  8 +++---
 roofit/roofit/src/RooTFnBinding.cxx    | 40 +++++++++++++-------------
 roofit/roofit/src/RooTFnPdfBinding.cxx | 22 +++++++-------
 4 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/roofit/roofit/inc/RooTFnBinding.h b/roofit/roofit/inc/RooTFnBinding.h
index 6017abd2f5200..219fad152dd20 100644
--- a/roofit/roofit/inc/RooTFnBinding.h
+++ b/roofit/roofit/inc/RooTFnBinding.h
@@ -16,9 +16,9 @@ class TF3 ;
 
 class RooTFnBinding : public RooAbsReal {
 public:
-  RooTFnBinding() {} ; 
-  RooTFnBinding(const char *name, const char *title, TF1* _func, const RooArgList& _list);
-  RooTFnBinding(const char *name, const char *title, TF1* _func, const RooArgList& _list, const RooArgList& _plist);
+   RooTFnBinding() : _func(0) {} ; 
+  RooTFnBinding(const char *name, const char *title, TF1* func, const RooArgList& list);
+  RooTFnBinding(const char *name, const char *title, TF1* func, const RooArgList& list, const RooArgList& plist);
   RooTFnBinding(const RooTFnBinding& other, const char* name=0) ;
   virtual TObject* clone(const char* newname) const { return new RooTFnBinding(*this,newname); }
   inline virtual ~RooTFnBinding() { }
@@ -27,9 +27,9 @@ class RooTFnBinding : public RooAbsReal {
 
 protected:
 
-  RooListProxy olist ;
-  RooListProxy plist ;
-  TF1* func ;
+  RooListProxy _olist ;
+  RooListProxy _plist ;
+  TF1* _func ;
   
   Double_t evaluate() const ;
 
diff --git a/roofit/roofit/inc/RooTFnPdfBinding.h b/roofit/roofit/inc/RooTFnPdfBinding.h
index 23c84172a753f..17549170983f4 100644
--- a/roofit/roofit/inc/RooTFnPdfBinding.h
+++ b/roofit/roofit/inc/RooTFnPdfBinding.h
@@ -15,8 +15,8 @@ class TF3 ;
 
 class RooTFnPdfBinding : public RooAbsPdf {
 public:
-  RooTFnPdfBinding() {} ; 
-  RooTFnPdfBinding(const char *name, const char *title, TF1* _func, const RooArgList& _list);
+  RooTFnPdfBinding() : _func(0) {} ; 
+  RooTFnPdfBinding(const char *name, const char *title, TF1* func, const RooArgList& list);
   RooTFnPdfBinding(const RooTFnPdfBinding& other, const char* name=0) ;
   virtual TObject* clone(const char* newname) const { return new RooTFnPdfBinding(*this,newname); }
   inline virtual ~RooTFnPdfBinding() { }
@@ -25,8 +25,8 @@ class RooTFnPdfBinding : public RooAbsPdf {
 
 protected:
 
-  RooListProxy list ;
-  TF1* func ;
+  RooListProxy _list ;
+  TF1* _func ;
   
   Double_t evaluate() const ;
 
diff --git a/roofit/roofit/src/RooTFnBinding.cxx b/roofit/roofit/src/RooTFnBinding.cxx
index 792ff9f140a11..3c55069eb1d54 100644
--- a/roofit/roofit/src/RooTFnBinding.cxx
+++ b/roofit/roofit/src/RooTFnBinding.cxx
@@ -17,31 +17,31 @@ using namespace std;
 
 ClassImp(RooTFnBinding) 
 
-RooTFnBinding::RooTFnBinding(const char *name, const char *title, TF1* _func, const RooArgList& _list) :
+RooTFnBinding::RooTFnBinding(const char *name, const char *title, TF1* func, const RooArgList& list) :
   RooAbsReal(name,title), 
-  olist("obs","obs",this),
-  func(_func)
+  _olist("obs","obs",this),
+  _func(func)
 { 
-  olist.add(_list) ;
+  _olist.add(list) ;
 } 
 
 
-RooTFnBinding::RooTFnBinding(const char *name, const char *title, TF1* _func, const RooArgList& _obsList, const RooArgList& paramList) :
+RooTFnBinding::RooTFnBinding(const char *name, const char *title, TF1* func, const RooArgList& obsList, const RooArgList& paramList) :
   RooAbsReal(name,title), 
-  olist("obs","obs",this),
-  plist("params","params",this),
-  func(_func)
+  _olist("obs","obs",this),
+  _plist("params","params",this),
+  _func(func)
 { 
-  olist.add(_obsList) ;
-  plist.add(paramList) ;
+  _olist.add(obsList) ;
+  _plist.add(paramList) ;
 } 
 
 
 RooTFnBinding::RooTFnBinding(const RooTFnBinding& other, const char* name) :  
   RooAbsReal(other,name), 
-  olist("obs",this,other.olist),
-  plist("params",this,other.plist),
-  func(other.func)
+  _olist("obs",this,other._olist),
+  _plist("params",this,other._plist),
+  _func(other._func)
 { 
 } 
 
@@ -49,13 +49,13 @@ RooTFnBinding::RooTFnBinding(const RooTFnBinding& other, const char* name) :
 
 Double_t RooTFnBinding::evaluate() const 
 { 
-  Double_t x = olist.at(0) ? ((RooAbsReal*)olist.at(0))->getVal() : 0 ;
-  Double_t y = olist.at(1) ? ((RooAbsReal*)olist.at(1))->getVal() : 0 ;
-  Double_t z = olist.at(2) ? ((RooAbsReal*)olist.at(2))->getVal() : 0 ;
-  for (Int_t i=0 ; i<func->GetNpar() ; i++) {
-    func->SetParameter(i,plist.at(i)?((RooAbsReal*)plist.at(i))->getVal() : 0) ;
+  Double_t x = _olist.at(0) ? ((RooAbsReal*)_olist.at(0))->getVal() : 0 ;
+  Double_t y = _olist.at(1) ? ((RooAbsReal*)_olist.at(1))->getVal() : 0 ;
+  Double_t z = _olist.at(2) ? ((RooAbsReal*)_olist.at(2))->getVal() : 0 ;
+  for (Int_t i=0 ; i<_func->GetNpar() ; i++) {
+    _func->SetParameter(i,_plist.at(i)?((RooAbsReal*)_plist.at(i))->getVal() : 0) ;
   }
-  return func->Eval(x,y,z) ;
+  return _func->Eval(x,y,z) ;
 } 
 
 
@@ -63,7 +63,7 @@ Double_t RooTFnBinding::evaluate() const
 void RooTFnBinding::printArgs(ostream& os) const 
 {
   // Print object arguments and name/address of function pointer
-  os << "[ TFn={" << func->GetName() << "=" << func->GetTitle() << "} " ;    
+  os << "[ TFn={" << _func->GetName() << "=" << _func->GetTitle() << "} " ;    
   for (Int_t i=0 ; i<numProxies() ; i++) {
     RooAbsProxy* p = getProxy(i) ;
     if (!TString(p->name()).BeginsWith("!")) {
diff --git a/roofit/roofit/src/RooTFnPdfBinding.cxx b/roofit/roofit/src/RooTFnPdfBinding.cxx
index 7316db5b8f314..29501c827711b 100644
--- a/roofit/roofit/src/RooTFnPdfBinding.cxx
+++ b/roofit/roofit/src/RooTFnPdfBinding.cxx
@@ -17,19 +17,19 @@ using namespace std;
 
 ClassImp(RooTFnPdfBinding) 
 
-RooTFnPdfBinding::RooTFnPdfBinding(const char *name, const char *title, TF1* _func, const RooArgList& _list) :
+RooTFnPdfBinding::RooTFnPdfBinding(const char *name, const char *title, TF1* func, const RooArgList& list) :
   RooAbsPdf(name,title), 
-  list("params","params",this),
-  func(_func)
+  _list("params","params",this),
+  _func(func)
 { 
-  list.add(_list) ;
+  _list.add(list) ;
 } 
 
 
 RooTFnPdfBinding::RooTFnPdfBinding(const RooTFnPdfBinding& other, const char* name) :  
   RooAbsPdf(other,name), 
-  list("params",this,other.list),
-  func(other.func)
+  _list("params",this,other._list),
+  _func(other._func)
 { 
 } 
 
@@ -37,10 +37,10 @@ RooTFnPdfBinding::RooTFnPdfBinding(const RooTFnPdfBinding& other, const char* na
 
 Double_t RooTFnPdfBinding::evaluate() const 
 { 
-  Double_t x = list.at(0) ? ((RooAbsReal*)list.at(0))->getVal() : 0 ;
-  Double_t y = list.at(1) ? ((RooAbsReal*)list.at(1))->getVal() : 0 ;
-  Double_t z = list.at(2) ? ((RooAbsReal*)list.at(2))->getVal() : 0 ;
-  return func->Eval(x,y,z) ;
+  Double_t x = _list.at(0) ? ((RooAbsReal*)_list.at(0))->getVal() : 0 ;
+  Double_t y = _list.at(1) ? ((RooAbsReal*)_list.at(1))->getVal() : 0 ;
+  Double_t z = _list.at(2) ? ((RooAbsReal*)_list.at(2))->getVal() : 0 ;
+  return _func->Eval(x,y,z) ;
 } 
 
 
@@ -48,7 +48,7 @@ Double_t RooTFnPdfBinding::evaluate() const
 void RooTFnPdfBinding::printArgs(ostream& os) const 
 {
   // Print object arguments and name/address of function pointer
-  os << "[ TFn={" << func->GetName() << "=" << func->GetTitle() << "} " ;    
+  os << "[ TFn={" << _func->GetName() << "=" << _func->GetTitle() << "} " ;    
   for (Int_t i=0 ; i<numProxies() ; i++) {
     RooAbsProxy* p = getProxy(i) ;
     if (!TString(p->name()).BeginsWith("!")) {

From 74f3cb27557b45dae3ee7289402c66decc309a9e Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Tue, 3 Mar 2015 11:53:16 +0100
Subject: [PATCH 117/200] Implemented configuration option cxx14 to enable
 compiling with this c++14 version of the standard.

---
 cmake/modules/CheckCompiler.cmake     | 18 ++++++++++++++++++
 cmake/modules/RootBuildOptions.cmake  |  1 +
 cmake/modules/RootConfiguration.cmake |  5 +++++
 config/RConfigure.in                  |  1 +
 4 files changed, 25 insertions(+)

diff --git a/cmake/modules/CheckCompiler.cmake b/cmake/modules/CheckCompiler.cmake
index 170f0421313fb..6947ddf2abc48 100644
--- a/cmake/modules/CheckCompiler.cmake
+++ b/cmake/modules/CheckCompiler.cmake
@@ -69,6 +69,10 @@ include(CheckCXXCompilerFlag)
 include(CheckCCompilerFlag)
 
 #---Check for cxx11 option------------------------------------------------------------
+if(cxx11 AND cxx14)
+  message(STATUS "c++11 mode requested but superseded by request for c++14 mode")
+  set(cxx11 OFF CACHE BOOL "" FORCE)
+endif()
 if(cxx11)
   CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_CXX11)
   if(NOT HAS_CXX11)
@@ -76,6 +80,13 @@ if(cxx11)
     set(cxx11 OFF CACHE BOOL "" FORCE)
   endif()
 endif()
+if(cxx14)
+  CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CXX14)
+  if(NOT HAS_CXX14)
+    message(STATUS "Current compiler does not suppport -std=c++14 option. Switching OFF cxx14 option")
+    set(cxx14 OFF CACHE BOOL "" FORCE)
+  endif()
+endif()
 
 #---Check for libcxx option------------------------------------------------------------
 if(libcxx)
@@ -117,6 +128,13 @@ if(cxx11)
   endif()
 endif()
 
+if(cxx14)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+  if(CMAKE_COMPILER_IS_GNUCXX)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
+  endif()
+endif()
+
 if(libcxx)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
 endif()
diff --git a/cmake/modules/RootBuildOptions.cmake b/cmake/modules/RootBuildOptions.cmake
index b8f5f8f42e2b9..6545f36a88054 100644
--- a/cmake/modules/RootBuildOptions.cmake
+++ b/cmake/modules/RootBuildOptions.cmake
@@ -107,6 +107,7 @@ ROOT_BUILD_OPTION(builtin_cfitsio OFF "Built the FITSIO library internally (down
 ROOT_BUILD_OPTION(builtin_xrootd OFF "Built the XROOTD internally (downloading tarfile from the Web)")
 ROOT_BUILD_OPTION(builtin_llvm ON "Built the LLVM internally")
 ROOT_BUILD_OPTION(cxx11 ON "Build using C++11 compatible mode, requires gcc > 4.7.x or clang")
+ROOT_BUILD_OPTION(cxx14 OFF "Build using C++14 compatible mode, requires gcc > 4.9.x or clang")
 ROOT_BUILD_OPTION(libcxx OFF "Build using libc++, requires cxx11 option (MacOS X only, for the time being)")
 ROOT_BUILD_OPTION(castor ON "CASTOR support, requires libshift from CASTOR >= 1.5.2")
 ROOT_BUILD_OPTION(chirp ON "Chirp support (Condor remote I/O), requires libchirp_client")
diff --git a/cmake/modules/RootConfiguration.cmake b/cmake/modules/RootConfiguration.cmake
index 6198e9bd4eb6b..3ef6e104af6f1 100644
--- a/cmake/modules/RootConfiguration.cmake
+++ b/cmake/modules/RootConfiguration.cmake
@@ -450,6 +450,11 @@ if(cxx11)
 else()
   set(usec++11 undef)
 endif()
+if(cxx14)
+  set(usec++14 define)
+else()
+  set(usec++14 undef)
+endif()
 if(libcxx)
   set(uselibc++ define)
 else()
diff --git a/config/RConfigure.in b/config/RConfigure.in
index e4fbfbf284058..de85c3dc67e54 100644
--- a/config/RConfigure.in
+++ b/config/RConfigure.in
@@ -25,6 +25,7 @@
 #@hascocoa@ R__HAS_COCOA    /**/
 #@hasvc@ R__HAS_VC    /**/
 #@usec++11@ R__USE_CXX11    /**/
+#@usec++14@ R__USE_CXX14    /**/
 #@uselibc++@ R__USE_LIBCXX    /**/
 #@hasllvm@ R__EXTERN_LLVMDIR @llvmdir@
 

From e0e7ff66e2234d87300bd91111a9c21b0aa2be5c Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Tue, 3 Mar 2015 13:47:23 +0100
Subject: [PATCH 118/200] Start to do some filtering.

---
 documentation/doxygen/Doxyfile   | 124 +++++++++++++++---------------
 documentation/doxygen/Makefile   |   7 +-
 documentation/doxygen/filter.cxx | 128 +++++++++++++++++++++++++------
 3 files changed, 169 insertions(+), 90 deletions(-)

diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile
index 405202bd1864b..6ebc66d539de2 100644
--- a/documentation/doxygen/Doxyfile
+++ b/documentation/doxygen/Doxyfile
@@ -1,11 +1,5 @@
 # Doxyfile 1.8.6
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = 6.03/03
-
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project.
 #
@@ -40,6 +34,12 @@ DOXYFILE_ENCODING      = UTF-8
 
 PROJECT_NAME           = ROOT
 
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 6.03/03
+
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
@@ -154,7 +154,7 @@ FULL_PATH_NAMES        = YES
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH        =
+STRIP_FROM_PATH        = 
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
@@ -163,7 +163,7 @@ STRIP_FROM_PATH        =
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH    =
+STRIP_FROM_INC_PATH    = 
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -230,13 +230,13 @@ TAB_SIZE               = 4
 # "Side Effects:". You can put \n's in the value part of an alias to insert
 # newlines.
 
-ALIASES                =
+ALIASES                = 
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
 # will allow you to use the command class in the itcl::class meaning.
 
-TCL_SUBST              =
+TCL_SUBST              = 
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
 # only. Doxygen will then generate output that is more tailored for C. For
@@ -280,7 +280,7 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 # Note that for custom extensions you also need to set FILE_PATTERNS otherwise
 # the files are not read by doxygen.
 
-EXTENSION_MAPPING      =
+EXTENSION_MAPPING      = 
 
 # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
 # according to the Markdown format, which allows for more readable
@@ -616,7 +616,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       =
+ENABLED_SECTIONS       = 
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
@@ -658,7 +658,7 @@ SHOW_NAMESPACES        = NO
 # by doxygen. Whatever the program writes to standard output is used as the file
 # version. For an example see the documentation.
 
-FILE_VERSION_FILTER    =
+FILE_VERSION_FILTER    = 
 
 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
 # by doxygen. The layout file controls the global structure of the generated
@@ -682,7 +682,7 @@ LAYOUT_FILE            = DoxygenLayout.xml
 # search path. Do not use file names with spaces, bibtex cannot handle them. See
 # also \cite for info how to create references.
 
-CITE_BIB_FILES         =
+CITE_BIB_FILES         = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to warning and progress messages
@@ -741,7 +741,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           =
+WARN_LOGFILE           = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -753,8 +753,8 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = ../../hist/histpainter \
-                         ../../graf2d/graf
+INPUT                  = ../../graf2d/graf \
+                         ../../hist/hitspainter
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -830,7 +830,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                =
+EXCLUDE                = 
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -846,7 +846,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       =
+EXCLUDE_PATTERNS       = 
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -857,7 +857,7 @@ EXCLUDE_PATTERNS       =
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories use the pattern */test/*
 
-EXCLUDE_SYMBOLS        =
+EXCLUDE_SYMBOLS        = 
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or directories
 # that contain example code fragments that are included (see the \include
@@ -909,7 +909,7 @@ INPUT_FILTER           = ./filter
 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
 # patterns match the file name, INPUT_FILTER is applied.
 
-FILTER_PATTERNS        =
+FILTER_PATTERNS        = 
 
 # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
 # INPUT_FILTER ) will also be used to filter the input files that are used for
@@ -924,14 +924,14 @@ FILTER_SOURCE_FILES    = YES
 # *.ext= (so without naming a filter).
 # This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
 
-FILTER_SOURCE_PATTERNS =
+FILTER_SOURCE_PATTERNS = 
 
 # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
 # is part of the input, its contents will be placed on the main page
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE =
+USE_MDFILE_AS_MAINPAGE = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
@@ -1036,7 +1036,7 @@ CLANG_ASSISTED_PARSING = NO
 # specified with INPUT and INCLUDE_PATH.
 # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
 
-CLANG_OPTIONS          =
+CLANG_OPTIONS          = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the alphabetical class index
@@ -1062,7 +1062,7 @@ COLS_IN_ALPHA_INDEX    = 5
 # while generating the index headers.
 # This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
-IGNORE_PREFIX          =
+IGNORE_PREFIX          = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the HTML output
@@ -1106,7 +1106,7 @@ HTML_FILE_EXTENSION    = .html
 # of the possible markers and block names see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_HEADER            =
+HTML_HEADER            = 
 
 # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
 # generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1128,7 +1128,7 @@ HTML_FOOTER            = htmlfooter.html
 # obsolete.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_STYLESHEET        =
+HTML_STYLESHEET        = 
 
 # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
 # defined cascading style sheet that is included after the standard style sheets
@@ -1139,7 +1139,7 @@ HTML_STYLESHEET        =
 # see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_STYLESHEET  =
+HTML_EXTRA_STYLESHEET  = 
 
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
@@ -1277,7 +1277,7 @@ GENERATE_HTMLHELP      = NO
 # written to the html output directory.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_FILE               =
+CHM_FILE               = 
 
 # The HHC_LOCATION tag can be used to specify the location (absolute path
 # including file name) of the HTML help compiler ( hhc.exe). If non-empty
@@ -1285,7 +1285,7 @@ CHM_FILE               =
 # The file has to be specified with full path.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-HHC_LOCATION           =
+HHC_LOCATION           = 
 
 # The GENERATE_CHI flag controls if a separate .chi index file is generated (
 # YES) or that it should be included in the master .chm file ( NO).
@@ -1298,7 +1298,7 @@ GENERATE_CHI           = NO
 # and project file content.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_INDEX_ENCODING     =
+CHM_INDEX_ENCODING     = 
 
 # The BINARY_TOC flag controls whether a binary table of contents is generated (
 # YES) or a normal table of contents ( NO) in the .chm file.
@@ -1328,7 +1328,7 @@ GENERATE_QHP           = NO
 # the HTML output folder.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QCH_FILE               =
+QCH_FILE               = 
 
 # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
 # Project output. For more information please see Qt Help Project / Namespace
@@ -1353,7 +1353,7 @@ QHP_VIRTUAL_FOLDER     = doc
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_NAME   =
+QHP_CUST_FILTER_NAME   = 
 
 # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
 # custom filter to add. For more information please see Qt Help Project / Custom
@@ -1361,21 +1361,21 @@ QHP_CUST_FILTER_NAME   =
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_ATTRS  =
+QHP_CUST_FILTER_ATTRS  = 
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
 # project's filter section matches. Qt Help Project / Filter Attributes (see:
 # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_SECT_FILTER_ATTRS  =
+QHP_SECT_FILTER_ATTRS  = 
 
 # The QHG_LOCATION tag can be used to specify the location of Qt's
 # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
 # generated .qhp file.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHG_LOCATION           =
+QHG_LOCATION           = 
 
 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
 # generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1508,7 +1508,7 @@ MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_EXTENSIONS     =
+MATHJAX_EXTENSIONS     = 
 
 # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
 # of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1516,7 +1516,7 @@ MATHJAX_EXTENSIONS     =
 # example see the documentation.
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_CODEFILE       =
+MATHJAX_CODEFILE       = 
 
 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for
 # the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1576,7 +1576,7 @@ EXTERNAL_SEARCH        = NO
 # Searching" for details.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-SEARCHENGINE_URL       =
+SEARCHENGINE_URL       = 
 
 # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
 # search data is written to a file for indexing by an external tool. With the
@@ -1592,7 +1592,7 @@ SEARCHDATA_FILE        = searchdata.xml
 # projects and redirect the results back to the right project.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTERNAL_SEARCH_ID     =
+EXTERNAL_SEARCH_ID     = 
 
 # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
 # projects other than the one defined by this configuration file, but that are
@@ -1602,7 +1602,7 @@ EXTERNAL_SEARCH_ID     =
 # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTRA_SEARCH_MAPPINGS  =
+EXTRA_SEARCH_MAPPINGS  = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the LaTeX output
@@ -1663,7 +1663,7 @@ PAPER_TYPE             = a4
 # If left blank no extra packages will be included.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-EXTRA_PACKAGES         =
+EXTRA_PACKAGES         = 
 
 # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
 # generated LaTeX document. The header should contain everything until the first
@@ -1679,7 +1679,7 @@ EXTRA_PACKAGES         =
 # PROJECT_NAME), or the project number (see PROJECT_NUMBER).
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_HEADER           =
+LATEX_HEADER           = 
 
 # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
 # generated LaTeX document. The footer should contain everything after the last
@@ -1688,7 +1688,7 @@ LATEX_HEADER           =
 # Note: Only use a user-defined footer if you know what you are doing!
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_FOOTER           =
+LATEX_FOOTER           = 
 
 # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the LATEX_OUTPUT output
@@ -1696,7 +1696,7 @@ LATEX_FOOTER           =
 # markers available.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_EXTRA_FILES      =
+LATEX_EXTRA_FILES      = 
 
 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
 # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1796,14 +1796,14 @@ RTF_HYPERLINKS         = NO
 # default style sheet that doxygen normally uses.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_STYLESHEET_FILE    =
+RTF_STYLESHEET_FILE    = 
 
 # Set optional variables used in the generation of an RTF document. Syntax is
 # similar to doxygen's config file. A template extensions file can be generated
 # using doxygen -e rtf extensionFile.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_EXTENSIONS_FILE    =
+RTF_EXTENSIONS_FILE    = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the man page output
@@ -1864,13 +1864,13 @@ XML_OUTPUT             = xml
 # validating XML parser to check the syntax of the XML files.
 # This tag requires that the tag GENERATE_XML is set to YES.
 
-XML_SCHEMA             =
+XML_SCHEMA             = 
 
 # The XML_DTD tag can be used to specify a XML DTD, which can be used by a
 # validating XML parser to check the syntax of the XML files.
 # This tag requires that the tag GENERATE_XML is set to YES.
 
-XML_DTD                =
+XML_DTD                = 
 
 # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
 # listings (including syntax highlighting and cross-referencing information) to
@@ -1947,7 +1947,7 @@ PERLMOD_PRETTY         = YES
 # overwrite each other's variables.
 # This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
-PERLMOD_MAKEVAR_PREFIX =
+PERLMOD_MAKEVAR_PREFIX = 
 
 #---------------------------------------------------------------------------
 # Configuration options related to the preprocessor
@@ -1988,7 +1988,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           =
+INCLUDE_PATH           = 
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1996,7 +1996,7 @@ INCLUDE_PATH           =
 # used.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-INCLUDE_FILE_PATTERNS  =
+INCLUDE_FILE_PATTERNS  = 
 
 # The PREDEFINED tag can be used to specify one or more macro names that are
 # defined before the preprocessor is started (similar to the -D option of e.g.
@@ -2006,7 +2006,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             =
+PREDEFINED             = 
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -2015,7 +2015,7 @@ PREDEFINED             =
 # definition found in the source code.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_AS_DEFINED      =
+EXPAND_AS_DEFINED      = 
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
 # remove all refrences to function-like macros that are alone on a line, have an
@@ -2044,13 +2044,13 @@ SKIP_FUNCTION_MACROS   = YES
 # the path). If a tag file is not located in the directory in which doxygen is
 # run, you must also specify the path to the tagfile here.
 
-TAGFILES               =
+TAGFILES               = 
 
 # When a file name is specified after GENERATE_TAGFILE, doxygen will create a
 # tag file that is based on the input files it reads. See section "Linking to
 # external documentation" for more information about the usage of tag files.
 
-GENERATE_TAGFILE       =
+GENERATE_TAGFILE       = 
 
 # If the ALLEXTERNALS tag is set to YES all external class will be listed in the
 # class index. If set to NO only the inherited external classes will be listed.
@@ -2098,14 +2098,14 @@ CLASS_DIAGRAMS         = NO
 # the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
-MSCGEN_PATH            =
+MSCGEN_PATH            = 
 
 # You can include diagrams made with dia in doxygen documentation. Doxygen will
 # then run dia to produce the diagram and insert it in the documentation. The
 # DIA_PATH tag allows you to specify the directory where the dia binary resides.
 # If left empty dia is assumed to be found in the default search path.
 
-DIA_PATH               =
+DIA_PATH               = 
 
 # If set to YES, the inheritance and collaboration graphs will hide inheritance
 # and usage relations if the target is undocumented or is not a class.
@@ -2154,7 +2154,7 @@ DOT_FONTSIZE           = 10
 # the path where dot can find it using this tag.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_FONTPATH           =
+DOT_FONTPATH           = 
 
 # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
 # each documented class showing the direct and indirect inheritance relations.
@@ -2299,19 +2299,19 @@ DOT_PATH               = /usr/local/bin/dot
 # command).
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOTFILE_DIRS           =
+DOTFILE_DIRS           = 
 
 # The MSCFILE_DIRS tag can be used to specify one or more directories that
 # contain msc files that are included in the documentation (see the \mscfile
 # command).
 
-MSCFILE_DIRS           =
+MSCFILE_DIRS           = 
 
 # The DIAFILE_DIRS tag can be used to specify one or more directories that
 # contain dia files that are included in the documentation (see the \diafile
 # command).
 
-DIAFILE_DIRS           =
+DIAFILE_DIRS           = 
 
 # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
 # that will be shown in the graph. If the number of nodes in a graph becomes
diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index ace0f9b7d92bc..f9a6172766ed5 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -1,18 +1,15 @@
 
-.PHONY: filter doxygen images clean
+.PHONY: filter doxygen clean
 
 docdir="$(shell ./makedocdir.sh)"
 imgdir="$(shell ./makeimgdir.sh)"
 macdir="$(shell ./makemacrodir.sh)"
 
-all: filter images doxygen
+all: filter doxygen
 
 filter:
 	`root-config --cxx` -o filter filter.cxx `root-config --libs --glibs --cflags`
 
-images:
-	./makeallimages.sh $(imgdir) $(macdir)
-
 doxygen:
 	doxygen
 
diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index fc7f5ea16a8d1..7192f551d0780 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -56,37 +56,119 @@
 #include <TMath.h>
 #include <TSystem.h>
 
+// Auxiliary functions
+void GetClassName();
+
+// Global variables.
+char    gLine[255];
+TString gFileName;
+TString gLineString;
+TString gClassName;
+Bool_t  gHeader;
+Bool_t  gSource;
+Bool_t  gInClassDef;
+
 
 //______________________________________________________________________________
 int main(int argc, char *argv[])
 {
-   // prototype of filter... does nothing right now.
-
-   FILE *fin;
-   int ch;
-
-   switch (argc) {
-      case 2:
-         if ((fin = fopen(argv[1], "r")) == NULL) {
-            // First string (%s) is program name (argv[0]).
-            // Second string (%s) is name of file that could
-            // not be opened (argv[1]).
-            (void)fprintf(stderr, "%s: Cannot open input file %s\n", argv[0], argv[1]);
-            return(2);
+   // Filter ROOT files for Doxygen.
+
+   // Initialisation
+   gFileName   = argv[1];
+   gHeader     = kFALSE;
+   gSource     = kFALSE;
+   gInClassDef = kFALSE;
+   if (gFileName.EndsWith(".cxx")) gSource = kTRUE;
+   if (gFileName.EndsWith(".h"))   gHeader = kTRUE;
+   GetClassName();
+
+   // Loop on file.
+   FILE *f = fopen(gFileName.Data(),"r");
+
+   // File header.
+   if (gHeader) {
+      while (fgets(gLine,255,f)) {
+         gLineString = gLine;
+
+         if (gLineString.BeginsWith("class"))    gInClassDef = kTRUE;
+         if (gLineString.Index("ClassDef") >= 0) gInClassDef = kFALSE;
+
+         if (gInClassDef && gLineString.Index("//") >= 0) {
+            gLineString.ReplaceAll("//","///<");
          }
-         break;
 
-      case 1:
-         fin = stdin;
-         break;
+         printf("%s",gLineString.Data());
+      }
+   }
+
+   // Source file.
+   if (gSource) {
+      while (fgets(gLine,255,f)) {
+         gLineString = gLine;
+
+         if (gLineString.Index("Begin_Html") >= 0) {
+            gLineString = TString::Format("/*! \\class %s\n",gClassName.Data());
+         }
+
+         if (gLineString.Index("Begin_Macro") >= 0) {
+         }
+
+         if (gLineString.Index("End_Macro") >= 0) {
+         }
 
-      default:
-         (void)fprintf(stderr, "Usage: %s [file]\n", argv[0]);
-         return(2);
+         printf("%s",gLineString.Data());
+      }
    }
 
-   while ((ch = getc(fin)) != EOF) (void)putchar(ch);
+   TString opt1,opt0;
+   opt0 = argv[0];
+   opt1 = argv[1];
+   printf("DEBUG %d : %s - %s %d %d - %s\n",argc,opt0.Data(),opt1.Data(),gSource,gHeader,gClassName.Data());
+   fclose(f);
+
+   return 1;
+}
+
+
+//______________________________________________________________________________
+void GetClassName()
+{
+   // Retrieve the class name.
+
+   Int_t i1 = 0;
+   Int_t i2 = 0;
+
+   FILE *f = fopen(gFileName.Data(),"r");
+
+   // File header.
+   if (gHeader) {
+      while (fgets(gLine,255,f)) {
+         gLineString = gLine;
+         if (gLineString.Index("ClassDef") >= 0) {
+            i1 = gLineString.Index("(")+1;
+            i2 = gLineString.Index(",")-1;
+            gClassName = gLineString(i1,i2-i1+1);
+            fclose(f);
+            return;
+         }
+      }
+   }
+
+   // Source file.
+   if (gSource) {
+      while (fgets(gLine,255,f)) {
+         gLineString = gLine;
+         if (gLineString.Index("ClassImp") >= 0) {
+            i1 = gLineString.Index("(")+1;
+            i2 = gLineString.Index(")")-1;
+            gClassName = gLineString(i1,i2-i1+1);
+            fclose(f);
+            return;
+         }
+      }
+   }
 
-   fclose(fin);
-   return (0);
+   fclose(f);
+   return;
 }

From 57a05b3633392246dfcd60b5b9d3dab951c3093a Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Tue, 3 Mar 2015 13:59:17 +0100
Subject: [PATCH 119/200] Do not use -Werror for compilation units within the
 interpreter folder

---
 interpreter/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt
index 1ee55eefbb8d0..d11a14c767884 100644
--- a/interpreter/CMakeLists.txt
+++ b/interpreter/CMakeLists.txt
@@ -22,6 +22,9 @@ if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-conditional-uninitialized")
 endif()
 
+#---Do not transform warnings in errors-------------------------------------------------------------
+string(REPLACE "-Werror" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+
 #---Build type--------------------------------------------------------------------------------------
 if(NOT DEFINED LLVM_BUILD_TYPE)
   set(LLVM_BUILD_TYPE Release CACHE STRING "Build type for LLVM (used to set CMAKE_BUILD_TYPE)")
@@ -47,7 +50,7 @@ foreach(var ${variables})
     mark_as_advanced(FORCE ${var})
   endif()
 endforeach()
-mark_as_advanced(FORCE BUG_REPORT_URL BUILD_CLANG_FORMAT_VS_PLUGIN BUILD_SHARED_LIBS BUILD_TESTING 
+mark_as_advanced(FORCE BUG_REPORT_URL BUILD_CLANG_FORMAT_VS_PLUGIN BUILD_SHARED_LIBS BUILD_TESTING
                        C_INCLUDE_DIRS DEFAULT_SYSROOT FFI_INCLUDE_DIR FFI_LIBRARY_DIR
                        GCC_INSTALL_PREFIX LIBCLANG_BUILD_STATIC TOOL_INFO_PLIST)
 mark_as_advanced(CLEAR LLVM_ENABLE_ASSERTIONS LLVM_BUILD_TYPE)

From ab4a5ab8dbffd9ddee2360526755001b9da2b48d Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Tue, 3 Mar 2015 18:28:40 +0100
Subject: [PATCH 120/200] Add support for weighted data

---
 hist/hist/inc/TKDE.h   |  32 ++++--
 hist/hist/src/TKDE.cxx | 226 +++++++++++++++++++++++++++++------------
 2 files changed, 184 insertions(+), 74 deletions(-)

diff --git a/hist/hist/inc/TKDE.h b/hist/hist/inc/TKDE.h
index e0a018a7bf767..20ab8e296ff5c 100644
--- a/hist/hist/inc/TKDE.h
+++ b/hist/hist/inc/TKDE.h
@@ -69,16 +69,29 @@ class TKDE : public TNamed  {
       kForcedBinning
    };
 
-   explicit TKDE(UInt_t events = 0, const Double_t* data = 0, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option = "KernelType:Gaussian;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0);
+   explicit TKDE(UInt_t events = 0, const Double_t* data = 0, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option =
+                 "KernelType:Gaussian;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
+      Instantiate( nullptr,  events, data, nullptr, xMin, xMax, option, rho);
+   }
+
+   TKDE(UInt_t events, const Double_t* data, const Double_t* dataWeight, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option =
+        "KernelType:Gaussian;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0) {
+      Instantiate( nullptr,  events, data, dataWeight, xMin, xMax, option, rho);
+   }
 
    template<class KernelFunction>
    TKDE(const Char_t* /*name*/, const KernelFunction& kernfunc, UInt_t events, const Double_t* data, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option = "KernelType:UserDefined;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0)  {
-      Instantiate(new ROOT::Math::WrappedFunction<const KernelFunction&>(kernfunc), events, data, xMin, xMax, option, rho);
+      Instantiate(new ROOT::Math::WrappedFunction<const KernelFunction&>(kernfunc), events, data, nullptr, xMin, xMax, option, rho);
+   }
+   template<class KernelFunction>
+   TKDE(const Char_t* /*name*/, const KernelFunction& kernfunc, UInt_t events, const Double_t* data, const Double_t * dataWeight, Double_t xMin = 0.0, Double_t xMax = 0.0, const Option_t* option = "KernelType:UserDefined;Iteration:Adaptive;Mirror:noMirror;Binning:RelaxedBinning", Double_t rho = 1.0)  {
+      Instantiate(new ROOT::Math::WrappedFunction<const KernelFunction&>(kernfunc), events, data, dataWeight, xMin, xMax, option, rho);
    }
 
    virtual ~TKDE();
 
    void Fill(Double_t data);
+   void Fill(Double_t data, Double_t weight);
    void SetKernelType(EKernelType kern);
    void SetIteration(EIteration iter);
    void SetMirror(EMirror mir);
@@ -134,6 +147,7 @@ class TKDE : public TNamed  {
 
    std::vector<Double_t> fData;   // Data events
    std::vector<Double_t> fEvents; // Original data storage
+   std::vector<Double_t> fEventWeights; // Original data weights
 
    TF1* fPDF;             // Output Kernel Density Estimation PDF function
    TF1* fUpperPDF;        // Output Kernel Density Estimation upper confidence interval PDF function
@@ -153,6 +167,7 @@ class TKDE : public TNamed  {
 
    UInt_t fNBins;          // Number of bins for binned data option
    UInt_t fNEvents;        // Data's number of events
+   Double_t fSumOfCounts; // Data sum of weights
    UInt_t fUseBinsNEvents; // If the algorithm is allowed to use binning this is the minimum number of events to do so
 
    Double_t fMean;  // Data mean
@@ -168,14 +183,14 @@ class TKDE : public TNamed  {
    std::vector<Double_t> fCanonicalBandwidths;
    std::vector<Double_t> fKernelSigmas2;
 
-   std::vector<UInt_t> fBinCount; // Number of events per bin for binned data option
+   std::vector<Double_t> fBinCount; // Number of events per bin for binned data option
 
    std::vector<Bool_t> fSettedOptions; // User input options flag
 
    struct KernelIntegrand;
    friend struct KernelIntegrand;
 
-   void Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_t* data,
+   void Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_t* data, const Double_t* weight, 
                     Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho);
 
    inline Double_t GaussianKernel(Double_t x) const {
@@ -202,14 +217,15 @@ class TKDE : public TNamed  {
    Double_t ComputeKernelMu() const;
    Double_t ComputeKernelIntegral() const;
    Double_t ComputeMidspread() ;
+   void ComputeDataStats() ;
 
    UInt_t Index(Double_t x) const;
 
    void SetBinCentreData(Double_t xmin, Double_t xmax);
    void SetBinCountData();
    void CheckKernelValidity();
-   void SetCanonicalBandwidth();
-   void SetKernelSigma2();
+   void SetUserCanonicalBandwidth();
+   void SetUserKernelSigma2();
    void SetCanonicalBandwidths();
    void SetKernelSigmas2();
    void SetHistogram();
@@ -223,7 +239,7 @@ class TKDE : public TNamed  {
    void CheckOptions(Bool_t isUserDefinedKernel = kFALSE);
    void GetOptions(std::string optionType, std::string option);
    void AssureOptions();
-   void SetData(const Double_t* data);
+   void SetData(const Double_t* data, const Double_t * weights);
    void InitFromNewData();
    void SetMirroredEvents();
    void SetDrawOptions(const Option_t* option, TString& plotOpt, TString& drawOpt);
@@ -236,7 +252,7 @@ class TKDE : public TNamed  {
    TF1* GetPDFUpperConfidenceInterval(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
    TF1* GetPDFLowerConfidenceInterval(Double_t confidenceLevel = 0.95, UInt_t npx = 100, Double_t xMin = 1.0, Double_t xMax = 0.0);
 
-   ClassDef(TKDE, 1) // One dimensional semi-parametric Kernel Density Estimation
+   ClassDef(TKDE, 2) // One dimensional semi-parametric Kernel Density Estimation
 
 };
 
diff --git a/hist/hist/src/TKDE.cxx b/hist/hist/src/TKDE.cxx
index 4983a5c735d3c..60d84e39428c0 100644
--- a/hist/hist/src/TKDE.cxx
+++ b/hist/hist/src/TKDE.cxx
@@ -25,6 +25,7 @@
 #include <algorithm>
 #include <numeric>
 #include <limits>
+#include <cassert>
 
 #include "Math/Error.h"
 #include "TMath.h"
@@ -34,6 +35,7 @@
 #include "Math/RichardsonDerivator.h"
 #include "TGraphErrors.h"
 #include "TF1.h"
+#include "TH1.h"
 #include "TCanvas.h"
 #include "TKDE.h"
 
@@ -62,39 +64,39 @@ struct TKDE::KernelIntegrand {
    EIntegralResult fIntegralResult;
 };
 
-TKDE::TKDE(UInt_t events, const Double_t* data, Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho) :
-fData(events, 0.0),
-fEvents(events, 0.0),
-fPDF(0),
-fUpperPDF(0),
-fLowerPDF(0),
-fApproximateBias(0),
-fGraph(0),
-fNewData(false),
-fUseMinMaxFromData((xMin >= xMax)),
-fNBins(events < 10000 ? 100: events / 10),
-fNEvents(events),
-fUseBinsNEvents(10000),
-fMean(0.0),
-fSigma(0.0),
-fXMin(xMin),
-fXMax(xMax),
-fAdaptiveBandwidthFactor(1.0),
-fCanonicalBandwidths(std::vector<Double_t>(kTotalKernels, 0.0)),
-fKernelSigmas2(std::vector<Double_t>(kTotalKernels, -1.0)),
-fSettedOptions(std::vector<Bool_t>(4, kFALSE))
-{
-   //Class constructor
-   SetOptions(option, rho);
-   CheckOptions();
-   SetMirror();
-   SetUseBins();
-   SetKernelFunction();
-   SetData(data);
-   SetCanonicalBandwidths();
-   SetKernelSigmas2();
-   SetKernel();
-}
+// TKDE::TKDE(UInt_t events, const Double_t* data, Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho) :
+//    fData(events, 0.0),
+//    fEvents(events, 0.0),
+//    fPDF(0),
+//    fUpperPDF(0),
+//    fLowerPDF(0),
+//    fApproximateBias(0),
+//    fGraph(0),
+//    fNewData(false),
+//    fUseMinMaxFromData((xMin >= xMax)),
+//    fNBins(events < 10000 ? 100: events / 10),
+//    fNEvents(events),
+//    fUseBinsNEvents(10000),
+//    fMean(0.0),
+//    fSigma(0.0),
+//    fXMin(xMin),
+//    fXMax(xMax),
+//    fAdaptiveBandwidthFactor(1.0),
+//    fCanonicalBandwidths(std::vector<Double_t>(kTotalKernels, 0.0)),
+//    fKernelSigmas2(std::vector<Double_t>(kTotalKernels, -1.0)),
+//    fSettedOptions(std::vector<Bool_t>(4, kFALSE))
+// {
+//    //Class constructor
+//    SetOptions(option, rho);
+//    CheckOptions();
+//    SetMirror();
+//    SetUseBins();
+//    SetKernelFunction();
+//    SetData(data);
+//    SetCanonicalBandwidths();
+//    SetKernelSigmas2();
+//    SetKernel();
+// }
 
 TKDE::~TKDE() {
    //Class destructor
@@ -107,7 +109,7 @@ TKDE::~TKDE() {
    delete fKernel;
 }
 
-void TKDE::Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_t* data, Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho) {
+void TKDE::Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_t* data, const Double_t* dataWeights, Double_t xMin, Double_t xMax, const Option_t* option, Double_t rho) {
    // Template's constructor surrogate
    fData = std::vector<Double_t>(events, 0.0);
    fEvents = std::vector<Double_t>(events, 0.0);
@@ -131,11 +133,8 @@ void TKDE::Instantiate(KernelFunction_Ptr kernfunc, UInt_t events, const Double_
    CheckOptions(kTRUE);
    SetMirror();
    SetUseBins();
+   SetData(data, dataWeights);
    SetKernelFunction(kernfunc);
-   SetData(data);
-   SetCanonicalBandwidths();
-   SetKernelSigmas2();
-   SetKernel();
 }
 
 void TKDE::SetOptions(const Option_t* option, Double_t rho) {
@@ -427,31 +426,35 @@ void TKDE::SetMirror() {
    fUseMirroring = fMirrorLeft                 || fMirrorRight ;
 }
 
-void TKDE::SetData(const Double_t* data) {
+void TKDE::SetData(const Double_t* data, const Double_t* wgts) {
    // Sets the data events input sample or bin centres for binned option and computes basic estimators
    if (!data) {
       if (fNEvents) fData.reserve(fNEvents);
       return;
    }
    fEvents.assign(data, data + fNEvents);
+   if (wgts) fEventWeights.assign(wgts, wgts + fNEvents);
+   
    if (fUseMinMaxFromData) {
       fXMin = *std::min_element(fEvents.begin(), fEvents.end());
       fXMax = *std::max_element(fEvents.begin(), fEvents.end());
    }
-   Double_t midspread = ComputeMidspread();
-   SetMean();
-   SetSigma(midspread);
+
    if (fUseBins) {
       if (fNBins >= fNEvents) {
          this->Warning("SetData", "Default number of bins is greater or equal to number of events. Use SetNBins(UInt_t) to set the appropriate number of bins");
       }
       fWeightSize = fNBins / (fXMax - fXMin);
       SetBinCentreData(fXMin, fXMax);
-      SetBinCountData();
    } else {
       fWeightSize = fNEvents / (fXMax - fXMin);
       fData = fEvents;
    }
+   // to set fBinCOunt and fSumOfCounts
+   SetBinCountData();
+
+
+   ComputeDataStats(); 
    if (fUseMirroring) {
       SetMirroredEvents();
    }
@@ -466,9 +469,7 @@ void TKDE::InitFromNewData() {
       fXMin = *std::min_element(fEvents.begin(), fEvents.end());
       fXMax = *std::max_element(fEvents.begin(), fEvents.end());
    }
-   Double_t midspread = ComputeMidspread();
-   SetMean();
-   SetSigma(midspread);
+   ComputeDataStats(); 
    //    if (fUseBins) {
    // } // bin usage is not supported in this case
    //
@@ -480,9 +481,10 @@ void TKDE::InitFromNewData() {
 }
 
 void TKDE::SetMirroredEvents() {
-   // Mirrors the data
+   // Mirrors the data 
    std::vector<Double_t> originalEvents = fEvents;
-   if (fMirrorLeft) {
+   std::vector<Double_t> originalWeights = fEventWeights;
+  if (fMirrorLeft) {
       fEvents.resize(2 * fNEvents, 0.0);
       transform(fEvents.begin(), fEvents.begin() + fNEvents, fEvents.begin() + fNEvents, std::bind1st(std::minus<Double_t>(), 2 * fXMin));
    }
@@ -490,16 +492,23 @@ void TKDE::SetMirroredEvents() {
       fEvents.resize((fMirrorLeft + 2) * fNEvents, 0.0);
       transform(fEvents.begin(), fEvents.begin() + fNEvents, fEvents.begin() + (fMirrorLeft + 1) * fNEvents, std::bind1st(std::minus<Double_t>(), 2 * fXMax));
    }
+   if (!fEventWeights.empty() && (fMirrorLeft || fMirrorRight)) {
+      // copy weights too
+      fEventWeights.insert(fEventWeights.end(), fEventWeights.begin(), fEventWeights.end() ); 
+   }
+
    if(fUseBins) {
       fNBins *= (fMirrorLeft + fMirrorRight + 1);
       Double_t xmin = fMirrorLeft  ? 2 * fXMin - fXMax : fXMin;
       Double_t xmax = fMirrorRight ? 2 * fXMax - fXMin : fXMax;
       SetBinCentreData(xmin, xmax);
-      SetBinCountData();
    } else {
       fData = fEvents;
    }
+   SetBinCountData();
+   
    fEvents = originalEvents;
+   fEventWeights = originalWeights; 
 }
 
 void TKDE::SetMean() {
@@ -518,7 +527,7 @@ void TKDE::SetKernel() {
    UInt_t n = fData.size();
    if (n == 0) return;
    // Optimal bandwidth (Silverman's rule of thumb with assumed Gaussian density)
-   Double_t weight(fCanonicalBandwidths[kGaussian] * fSigmaRob * std::pow(3. / (8. * std::sqrt(M_PI)) * n, -0.2));
+   Double_t weight = fCanonicalBandwidths[kGaussian] * fSigmaRob * std::pow(3. / (8. * std::sqrt(M_PI)) * n, -0.2);
    weight *= fRho * fCanonicalBandwidths[fKernelType] / fCanonicalBandwidths[kGaussian];
    fKernel = new TKernel(weight, this);
    if (fIteration == kAdaptive) {
@@ -542,19 +551,31 @@ void TKDE::SetKernelFunction(KernelFunction_Ptr kernfunc) {
          fKernelFunction = new ROOT::Math::WrappedMemFunction<TKDE, Double_t (TKDE::*)(Double_t) const>(*this, &TKDE::CosineArchKernel);
          break;
       case kUserDefined :
+         fKernelFunction = kernfunc;
+         if (fKernelFunction)  CheckKernelValidity();
+         break;
       case kTotalKernels :
       default:
+         /// for user defined kernels
          fKernelFunction = kernfunc;
-         if (fKernelFunction) {
-            CheckKernelValidity();
-            SetCanonicalBandwidth();
-            SetKernelSigma2();
-            SetKernel();
-         } else {
-            Error("SetKernelFunction", "Undefined user kernel function input!");
-            //exit(EXIT_FAILURE);
-         }
+         fKernelType = kUserDefined; 
+   }
+
+   if (fKernelType == kUserDefined) { 
+      if (fKernelFunction) {
+         CheckKernelValidity();
+         SetUserCanonicalBandwidth();
+         SetUserKernelSigma2();
+      }
+      else {
+         Error("SetKernelFunction", "User kernel function is not defined !");
+         return;
+      }
    }
+   assert(fKernelFunction); 
+   SetKernelSigmas2();
+   SetCanonicalBandwidths();
+   SetKernel();
 }
 
 void TKDE::SetCanonicalBandwidths() {
@@ -563,6 +584,7 @@ void TKDE::SetCanonicalBandwidths() {
    fCanonicalBandwidths[kEpanechnikov] = 1.7188; // Checked in Mathematica
    fCanonicalBandwidths[kBiweight] = 2.03617;    // Checked in Mathematica
    fCanonicalBandwidths[kCosineArch] = 1.7663;   // Checked in Mathematica
+   fCanonicalBandwidths[kUserDefined] = 1.0;     // To be Checked 
 }
 
 void TKDE::SetKernelSigmas2() {
@@ -608,6 +630,18 @@ void TKDE::Fill(Double_t data) {
    fNewData = kTRUE;
 }
 
+void TKDE::Fill(Double_t data, Double_t weight) {
+   // Fills data member with User input data event for the unbinned option
+   if (fUseBins) {
+      this->Warning("Fill", "Cannot fill data with data binned option. Data input ignored.");
+      return;
+   }
+   fData.push_back(data);  // should not be here fEvent ??
+   fEventWeights.push_back(weight);
+   fNEvents++;
+   fNewData = kTRUE;
+}
+
 Double_t TKDE::operator()(const Double_t* x, const Double_t*) const {
    // The class's unary function: returns the kernel density estimate
    return (*this)(*x);
@@ -677,10 +711,38 @@ void TKDE::SetBinCentreData(Double_t xmin, Double_t xmax) {
 
 void TKDE::SetBinCountData() {
    // Returns the bins' count from the data for using with the binned option
-   fBinCount.resize(fNBins);
-   for (UInt_t i = 0; i < fNEvents; ++i) {
-      if (fEvents[i] >= fXMin && fEvents[i] < fXMax)
-         fBinCount[Index(fEvents[i])]++;
+   // or set the bin count to the weights in case of weighted data
+   if (fUseBins) { 
+      fBinCount.resize(fNBins);
+      fSumOfCounts = 0;
+      // case of weighted events 
+      if (!fEventWeights.empty() ) { 
+         for (UInt_t i = 0; i < fNEvents; ++i) {
+            if (fEvents[i] >= fXMin && fEvents[i] < fXMax) {
+               fBinCount[Index(fEvents[i])] += fEventWeights[i];
+               fSumOfCounts += fEventWeights[i];
+            }
+         }
+      }
+      // case of unweighted data 
+      else {
+         for (UInt_t i = 0; i < fNEvents; ++i) {
+            if (fEvents[i] >= fXMin && fEvents[i] < fXMax) {
+               fBinCount[Index(fEvents[i])] += 1;
+               fSumOfCounts += 1;
+            }
+         }
+      }
+   }
+   else if (!fEventWeights.empty() ) {
+      fBinCount = fEventWeights;
+      fSumOfCounts = 0;
+      for (UInt_t i = 0; i < fNEvents; ++i) 
+         fSumOfCounts += fEventWeights[i];
+   }
+   else {
+      fSumOfCounts = fNEvents;
+      fBinCount.clear(); 
    }
 }
 
@@ -816,9 +878,12 @@ Double_t TKDE::TKernel::operator()(Double_t x) const {
    // The internal class's unary function: returns the kernel density estimate
    Double_t result(0.0);
    UInt_t n = fKDE->fData.size();
+   // case of bins or weighted data 
    Bool_t useBins = (fKDE->fBinCount.size() == n);
+   Double_t nSum = (useBins) ? fKDE->fSumOfCounts : fKDE->fNEvents; 
    for (UInt_t i = 0; i < n; ++i) {
       Double_t binCount = (useBins) ? fKDE->fBinCount[i] : 1.0;
+      //printf("data point %i  %f  count %f weight % f result % f\n",i,fKDE->fData[i],binCount,fWeights[i], result);
       result += binCount / fWeights[i] * (*fKDE->fKernelFunction)((x - fKDE->fData[i]) / fWeights[i]);
       if (fKDE->fAsymLeft) {
          result -= binCount / fWeights[i] * (*fKDE->fKernelFunction)((x - (2. * fKDE->fXMin - fKDE->fData[i])) / fWeights[i]);
@@ -827,7 +892,7 @@ Double_t TKDE::TKernel::operator()(Double_t x) const {
          result -= binCount / fWeights[i] * (*fKDE->fKernelFunction)((x - (2. * fKDE->fXMax - fKDE->fData[i])) / fWeights[i]);
       }
    }
-   return result / fKDE->fNEvents;
+   return result / nSum;
 }
 
 UInt_t TKDE::Index(Double_t x) const {
@@ -942,6 +1007,35 @@ Double_t TKDE::ComputeKernelIntegral() const {
    return result;
 }
 
+void TKDE::ComputeDataStats() {
+   /// in case of weights use
+   if (!fEventWeights.empty() ) {
+      // weighted data
+      double x1 = fXMin - 0.001*(fXMax-fXMin);
+      double x2 = fXMax + 0.001*(fXMax-fXMin);
+      TH1D h1("temphist","", 500, x1, x2);
+      h1.FillN(fEvents.size(), fEvents.data(), fEventWeights.data() );
+      assert (h1.GetSumOfWeights() > 0) ;
+      fMean = h1.GetMean();
+      fSigma = h1.GetRMS();
+      // compute robust sigma using midspread
+      Double_t quantiles[2] = {0.0, 0.0};
+      Double_t prob[2] = {0.25, 0.75};
+      h1.GetQuantiles(2, quantiles, prob);
+      Double_t midspread = quantiles[1] - quantiles[0];
+      fSigmaRob = std::min(fSigma, midspread / 1.349); // Sigma's robust estimator
+      //printf("weight case - stat: m = %f, s= %f, sr = %f \n",fMean, fSigma, midspread);
+      return;
+   }
+   else {
+      // compute statistics using the data
+      SetMean();
+      Double_t midspread = ComputeMidspread();
+      SetSigma(midspread);
+      //printf("un-weight case - stat: m = %f, s= %f, sr = %f \n",fMean, fSigma, fSigmaRob);
+   }
+}
+
 Double_t TKDE::ComputeMidspread () {
    // Computes the inter-quartile range from the data
    std::sort(fEvents.begin(), fEvents.end());
@@ -953,12 +1047,12 @@ Double_t TKDE::ComputeMidspread () {
    return upperquartile - lowerquartile;
 }
 
-void TKDE::SetCanonicalBandwidth() {
+void TKDE::SetUserCanonicalBandwidth() {
    // Computes the user's input kernel function canonical bandwidth
    fCanonicalBandwidths[kUserDefined] = std::pow(ComputeKernelL2Norm() / std::pow(ComputeKernelSigma2(), 2), 1. / 5.);
 }
 
-void TKDE::SetKernelSigma2() {
+void TKDE::SetUserKernelSigma2() {
    // Computes the user's input kernel function sigma2
    fKernelSigmas2[kUserDefined] = ComputeKernelSigma2();
 }

From e067938a142b1257747be74c96ae1f63c1f84408 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Tue, 3 Mar 2015 22:50:13 +0100
Subject: [PATCH 121/200] Fix for ROOT-7120 - cmake warnings 3.1

---
 CMakeLists.txt                      | 5 +++--
 interpreter/llvm/src/CMakeLists.txt | 4 +++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcf991990738d..940977049f4bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,8 +61,9 @@ endif()
 #---Populate the configure arguments returned by 'root-config --config'-------------------------
 get_cmake_property(variables CACHE_VARIABLES)
 foreach(var ${variables})
-  if((var MATCHES "_(LIBRARIES|LIBRARY|INCLUDE)") AND (NOT "${${var}}" STREQUAL "") AND
-     (NOT "${var}" MATCHES "NOTFOUND"))
+  if((var MATCHES "_(LIBRARIES|LIBRARY|INCLUDE)") AND
+     (NOT ${${var}} STREQUAL "") AND
+     (NOT ${var} MATCHES "NOTFOUND"))
     if (var MATCHES "^QT_")
       # filter out the very long list of Qt libraries and include dirs
       if (var MATCHES "(QT_LIBRARY_DIR|QT_QTCORE_INCLUDE_DIR)")
diff --git a/interpreter/llvm/src/CMakeLists.txt b/interpreter/llvm/src/CMakeLists.txt
index 7444665c1c901..09e2cec8f0014 100644
--- a/interpreter/llvm/src/CMakeLists.txt
+++ b/interpreter/llvm/src/CMakeLists.txt
@@ -210,7 +210,9 @@ option(LLVM_ENABLE_THREADS "Use threads if available." ON)
 
 option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)
 
-if(${LLVM_TARGETS_TO_BUILD} STREQUAL "all")
+cmake_policy(SET CMP0054 NEW)
+
+if(LLVM_TARGETS_TO_BUILD STREQUAL "all")
   set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )
 endif()
 

From 4c712968283ca1551805cce8521534568f88040c Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Tue, 3 Mar 2015 23:25:00 +0100
Subject: [PATCH 122/200] Fix for ROOT-7120 - added protection for old versions
 of CMake

---
 interpreter/llvm/src/CMakeLists.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/interpreter/llvm/src/CMakeLists.txt b/interpreter/llvm/src/CMakeLists.txt
index 09e2cec8f0014..a93f117f6c459 100644
--- a/interpreter/llvm/src/CMakeLists.txt
+++ b/interpreter/llvm/src/CMakeLists.txt
@@ -210,7 +210,9 @@ option(LLVM_ENABLE_THREADS "Use threads if available." ON)
 
 option(LLVM_ENABLE_ZLIB "Use zlib for compression/decompression if available." ON)
 
-cmake_policy(SET CMP0054 NEW)
+if(POLICY CMP0054)
+  cmake_policy(SET CMP0054 NEW)
+endif()
 
 if(LLVM_TARGETS_TO_BUILD STREQUAL "all")
   set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )

From d9c541390f8bc289e88219cf6714cd21c0edaf8e Mon Sep 17 00:00:00 2001
From: Wim Lavrijsen <WLavrijsen@lbl.gov>
Date: Tue, 3 Mar 2015 22:13:01 -0800
Subject: [PATCH 123/200] from Toby: fixes for python3

---
 bindings/pyroot/cppyy.py           | 6 +++---
 bindings/pyroot/src/RootModule.cxx | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/bindings/pyroot/cppyy.py b/bindings/pyroot/cppyy.py
index 41e05569f7429..70d7745dd6cef 100644
--- a/bindings/pyroot/cppyy.py
+++ b/bindings/pyroot/cppyy.py
@@ -50,8 +50,8 @@ def _AddressOf( self, obj ):
    _builtin_cppyy = False
 
    # load PyROOT C++ extension module, special case for linux and Sun
-   needsGlobal =  ( 0 <= string.find( sys.platform, 'linux' ) ) or\
-                  ( 0 <= string.find( sys.platform, 'sunos' ) )
+   needsGlobal =  ( 0 <= sys.platform.find( 'linux' ) ) or\
+                  ( 0 <= sys.platform.find( 'sunos' ) )
    if needsGlobal:
       # change dl flags to load dictionaries from pre-linked .so's
       dlflags = sys.getdlopenflags()
@@ -180,7 +180,7 @@ class short(int): pass
 class long_int(int): pass
 class unsigned_short(int): pass
 class unsigned_int(int): pass
-class unsigned_long(long): pass
+class unsigned_long(int): pass
 
 #--- Copy over locally defined names ------------------------------------
 if _builtin_cppyy:
diff --git a/bindings/pyroot/src/RootModule.cxx b/bindings/pyroot/src/RootModule.cxx
index eba08f384a2b8..0eb545088b50e 100644
--- a/bindings/pyroot/src/RootModule.cxx
+++ b/bindings/pyroot/src/RootModule.cxx
@@ -396,7 +396,7 @@ namespace {
       }
       if ( !PyErr_Occurred() ) {
          PyObject* str = PyObject_Str( dummy );
-         if ( str && PyString_Check( str ) )
+         if ( str && PyROOT_PyUnicode_Check( str ) )
             PyErr_Format( PyExc_ValueError, "unknown object %s", PyBytes_AS_STRING( str ) );
          else
             PyErr_Format( PyExc_ValueError, "unknown object at %p", (void*)dummy );

From 7548d861f9b61cb45bcb73c5858d644af52f343a Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Wed, 4 Mar 2015 09:12:04 +0100
Subject: [PATCH 124/200] Deal with the "all" as value and variable

---
 interpreter/llvm/src/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/interpreter/llvm/src/CMakeLists.txt b/interpreter/llvm/src/CMakeLists.txt
index a93f117f6c459..1073aee479dca 100644
--- a/interpreter/llvm/src/CMakeLists.txt
+++ b/interpreter/llvm/src/CMakeLists.txt
@@ -214,7 +214,7 @@ if(POLICY CMP0054)
   cmake_policy(SET CMP0054 NEW)
 endif()
 
-if(LLVM_TARGETS_TO_BUILD STREQUAL "all")
+if("${LLVM_TARGETS_TO_BUILD}" STREQUAL "all")
   set( LLVM_TARGETS_TO_BUILD ${LLVM_ALL_TARGETS} )
 endif()
 

From c8c6faf1837aac4d093e4d755b821591c7674c81 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Tue, 3 Mar 2015 17:23:43 +0100
Subject: [PATCH 125/200] jsroot: use MathJax for latex output

1. Introduce central method where all kind of text drawings
   are handled. At this place decide which kind of rendering -
   plain text, simplify latex or normal MathJax is used
2. Implement correct size adjustment and alignment for
   all kinds of text output (with and without MathJax)
3. Support TMathText class - always MathJax will be used
4. Draw label in TPabeText
5. Avoid concurent calls of JSROOT.AssertPrerequisities

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 documentation/JSROOT/JSROOT.md      |    8 +-
 etc/http/changes.md                 |    4 +
 etc/http/index.htm                  |    1 +
 etc/http/scripts/JSRoot3DPainter.js |    3 +-
 etc/http/scripts/JSRootCore.js      |   69 +-
 etc/http/scripts/JSRootPainter.js   | 1004 +++++++++++++++------------
 6 files changed, 610 insertions(+), 479 deletions(-)

diff --git a/documentation/JSROOT/JSROOT.md b/documentation/JSROOT/JSROOT.md
index fbee3cbd7fd13..1a034b3394fa3 100644
--- a/documentation/JSROOT/JSROOT.md
+++ b/documentation/JSROOT/JSROOT.md
@@ -27,6 +27,7 @@ The following parameters can be specified in the URL string:
 - optimize - drawing optimization 0:off, 1:only large histograms (default), 2:always
 - interactive - enable/disable interactive functions 0-disable all, 1-enable all
 - noselect - hide file-selection part in the browser (only when file name is specified)
+- mathjax - use MathJax for latex output
 
 When specifying `file`, `item` or `opt` parameters, one could provide array like `file=['file1.root','file2.root']`.
 One could skip quotes when specifying elements names `item=[file1.root/hpx,file2.root/hpy]` or `opt=['',colz]`.
@@ -44,7 +45,7 @@ One can very easy integrate JSROOT graphic into other HTML pages using a __ifram
 
 In principle, one could open any ROOT file placed in the web, providing the full URL to it like:
 
-<https://web-docs.gsi.de/~linev/js/3.3/?file=http://root.cern.ch/js/files/hsimple.root&item=hpx>
+<https://web-docs.gsi.de/~linev/js/3.3/?file=https://root.cern.ch/js/files/hsimple.root&item=hpx>
 
 But one should be aware of [Cross-Origin Request blocking](https://developer.mozilla.org/en/http_access_control),
 when the browser blocks requests to files from domains other than current web page.
@@ -91,7 +92,7 @@ One could also specify similar URL parameters to configure the displayed items a
 
 It is also possible to display one single item from the THttpServer server like:
 
-<https://root.cern.ch/js/3.3/demo/Files/job1.root/hpxpy/draw.htm?opt=colz>
+<https://root.cern.ch/js/3.3/httpserver.C/Files/job1.root/hpxpy/draw.htm?opt=colz>
 
 
 ##  Data monitoring with JSROOT
@@ -104,7 +105,7 @@ changes and request only the items currently displayed in the browser.
 To enable monitoring, one should activate the appropriate checkbox or
 provide __monitoring__ parameter in the URL string like:
 
-<https://root.cern.ch/js/3.3/demo/Files/job1.root/hprof/draw.htm?monitoring=1000>
+<https://root.cern.ch/js/3.3/httpserver.C/Files/job1.root/hprof/draw.htm?monitoring=1000>
 
 The parameter value is the update interval in milliseconds.
 
@@ -186,6 +187,7 @@ In URL string with JSRootCore.js script one should specify which JSROOT function
     + '2d' normal drawing for 1D/2D objects
     + '3d' 3D drawing for 2D/3D histograms
     + 'io' binary file I/O
+    + 'mathjax' loads MathJax and uses for latex output
     + 'gui' default gui for offline/online applications
     + 'load' name of user script(s) to load
     + 'onload' name of function to call when scripts loading completed
diff --git a/etc/http/changes.md b/etc/http/changes.md
index 740a7bcc43ff8..915c69737ec78 100644
--- a/etc/http/changes.md
+++ b/etc/http/changes.md
@@ -10,6 +10,10 @@ Many old problems and errors are fixed, new functions are provided.
    usage of jquery.js in core JSROOT classes
 3. Implement main graphics without jquery at all,
    such mode used in `nobrowser` mode.
+4. Implement MathJax support in JSROOT, TMathText always drawn with MathJax
+   other classes require `mathjax` option in URL
+5. Improve drawing of different text classes, correctly handle
+   their alignment and scaling
 
 
 ## Changes in v 3.3
diff --git a/etc/http/index.htm b/etc/http/index.htm
index 4b32be9c89c09..ca4dc1f412f33 100644
--- a/etc/http/index.htm
+++ b/etc/http/index.htm
@@ -25,6 +25,7 @@
    layout    - can be 'collapsible', 'tabs' or gridNxM where N and M are integer values
    nobrowser - only file item(s) will be displayed, browser will be disabled
    load      - name of JavaScript(s), automatically loaded at the beginning
+   mathjax   - use MathJax for Latex output (automatically loaded for TMathText objects)
 
 Example:
    https://root.cern.ch/js/3.4/?file=../files/hsimple.root&layout=grid2x2&item=[hpx;1,hpxpy;1]&opts=[,colz]
diff --git a/etc/http/scripts/JSRoot3DPainter.js b/etc/http/scripts/JSRoot3DPainter.js
index c4330058c087c..058dfb095dc04 100644
--- a/etc/http/scripts/JSRoot3DPainter.js
+++ b/etc/http/scripts/JSRoot3DPainter.js
@@ -253,8 +253,7 @@
 
    JSROOT.Painter.real_drawHistogram2D = function(painter) {
 
-      var w = Number(painter.svg_pad().attr("width")),
-          h = Number(painter.svg_pad().attr("height")), size = 100;
+      var w = painter.pad_width(), h = painter.pad_height(), size = 100;
 
       var xmin = painter.xmin, xmax = painter.xmax;
       if (painter.zoom_xmin != painter.zoom_xmax) {
diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index f3cef7197daf5..dc691863607a7 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,7 +14,7 @@
 
    JSROOT = {};
 
-   JSROOT.version = "3.4 dev 26/02/2015";
+   JSROOT.version = "3.4 dev 3/03/2015";
 
    JSROOT.source_dir = "";
    JSROOT.source_min = false;
@@ -34,6 +34,8 @@
 
    JSROOT.function_list = []; // do we really need it here?
 
+   JSROOT.MathJax = 0; // indicate usage of mathjax 0 - off, 1 - on
+
    JSROOT.BIT = function(n) { return 1 << (n); }
 
    // TH1 status bits
@@ -181,7 +183,7 @@
       if (!url) url = document.URL;
 
       var pos = url.indexOf("?");
-      if (pos<0) return null;
+      if (pos<0) return dflt;
       url = url.slice(pos+1);
 
       while (url.length>0) {
@@ -266,17 +268,24 @@
    JSROOT.CallBack = function(func, arg1, arg2) {
       // generic method to invoke callback function
       // func either normal function or container like
-      // { obj: _ object_pointer_, func: name of method to call }
+      // { obj: object_pointer, func: name of method to call }
+      // { _this: object pointer, func: function to call }
       // arg1, arg2 are optional arguments of the callback
 
-      if (func==null) return;
+      if (func == null) return;
 
       if (typeof func == 'string') func = JSROOT.findFunction(func);
 
       if (typeof func == 'function') return func(arg1,arg2);
 
-      if (typeof func == 'object' && typeof func.obj == 'object' &&
-         typeof func.func == 'string' && typeof func.obj[func.func] == 'function') return func.obj[func.func](arg1, arg2);
+      if (typeof func != 'object') return;
+
+      if (('obj' in func) && ('func' in func) &&
+         (typeof func.obj == 'object') && (typeof func.func == 'string') &&
+         (typeof func.obj[func.func] == 'function')) return func.obj[func.func](arg1, arg2);
+
+      if (('_this' in func) && ('func' in func) &&
+         (typeof func.func == 'function')) return func.func.call(func._this, arg1, arg2);
    }
 
    JSROOT.NewHttpRequest = function(url, kind, user_call_back) {
@@ -289,6 +298,7 @@
       //  "xml" - returns res.responseXML
       //  "head" - returns request itself, uses "HEAD" method
       // Result will be returned to the callback functions
+      // Request will be set as this pointer in the callback
       // If failed, request returns null
 
       var xhr = new XMLHttpRequest();
@@ -298,10 +308,7 @@
          if (typeof user_call_back == 'function') user_call_back.call(xhr, res);
       }
 
-
-//      if (typeof ActiveXObject == "function") {
       if (window.ActiveXObject) {
-         // console.log(" Create IE request");
 
          xhr.onreadystatechange = function() {
             // console.log(" Ready IE request");
@@ -446,10 +453,7 @@
             var href = styles[n]['href'];
             if ((href == null) || (href.length == 0)) continue;
 
-            if (href.indexOf(filename)>=0) {
-               console.log("style "+  filename + " already loaded");
-               return completeLoad();
-            }
+            if (href.indexOf(filename)>=0) return completeLoad();
          }
 
       } else {
@@ -463,7 +467,6 @@
 
             if ((src.indexOf(filename)>=0) && (src.indexOf("load=")<0)) {
                // avoid wrong decision when script name is specified as more argument
-               // debug("script "+  filename + " already loaded src = " + src);
                return completeLoad();
             }
          }
@@ -503,7 +506,9 @@
       document.getElementsByTagName("head")[0].appendChild(element);
    }
 
-   JSROOT.AssertPrerequisites = function(kind, andThan, debugout) {
+   JSROOT.doing_assert = null; // array where all requests are collected
+
+   JSROOT.AssertPrerequisites = function(kind, callback, debugout) {
       // one could specify kind of requirements
       // 'io' for I/O functionality (default)
       // '2d' for 2d graphic
@@ -511,12 +516,24 @@
       // 'simple' for basic user interface
       // 'load:' list of user-specific scripts at the end of kind string
 
-      if (typeof kind == 'function') { andThan = kind; kind = null; }
-
       if ((typeof kind != 'string') || (kind == ''))
-         return JSROOT.CallBack(andThan);
+         return JSROOT.CallBack(callback);
+
+      if (kind=='shift') {
+         var req = JSROOT.doing_assert.shift();
+         kind = req._kind;
+         callback = req._callback;
+         debugout = req._debug;
+      } else
+      if (JSROOT.doing_assert != null) {
+         // if function already called, store request
+         return JSROOT.doing_assert.push({_kind:kind, _callback:callback, _debug: debugout});
+      } else {
+         JSROOT.doing_assert = [];
+      }
 
       if (kind.charAt(kind.length-1)!=";") kind+=";";
+
       var ext = JSROOT.source_min ? ".min" : "";
 
       var need_jquery = false;
@@ -548,8 +565,10 @@
                      "$$$scripts/JSRoot3DPainter" + ext + ".js;";
       }
 
-      if (kind.indexOf("mathjax;")>=0)
-        allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML;";
+      if (kind.indexOf("mathjax;")>=0) {
+         allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML;";
+         if (JSROOT.MathJax == 0) JSROOT.MathJax = 1;
+      }
 
       if (kind.indexOf("simple;")>=0) {
          need_jquery = true;
@@ -570,7 +589,12 @@
       if (pos<0) pos = kind.indexOf("load:");
       if (pos>=0) allfiles += kind.slice(pos+5);
 
-      JSROOT.loadScript(allfiles, andThan, debugout);
+      JSROOT.loadScript(allfiles, function() {
+         if (JSROOT.doing_assert.length==0) JSROOT.doing_assert = null;
+         JSROOT.CallBack(callback);
+         if (JSROOT.doing_assert!=null)
+            JSROOT.AssertPrerequisites('shift');
+      }, debugout);
    }
 
    JSROOT.BuildSimpleGUI = function(user_scripts, andThen) {
@@ -1042,7 +1066,7 @@
             // - Loop on bins (including underflows/overflows)
             var bin, binx, biny, binz;
             var cu, factor = 1;
-            if (Math.abs(h1['fNormFactor']) > 2e-308) factor = h1['fNormFactor'] / h1.getSumOfWeights();
+            if (Math.abs(h1['fNormFactor']) > Number.MIN_VALUE) factor = h1['fNormFactor'] / h1.getSumOfWeights();
             for (binz=0;binz<=nbinsz+1;binz++) {
                for (biny=0;biny<=nbinsy+1;biny++) {
                   for (binx=0;binx<=nbinsx+1;binx++) {
@@ -2198,6 +2222,7 @@
          if (JSROOT.GetUrlOption('2d', src)!=null) prereq += "2d;";
          if (JSROOT.GetUrlOption('jq2d', src)!=null) prereq += "jq2d;";
          if (JSROOT.GetUrlOption('3d', src)!=null) prereq += "3d;";
+         if (JSROOT.GetUrlOption('mathjax', src)!=null) prereq += "mathjax;";
          var user = JSROOT.GetUrlOption('load', src);
          if ((user!=null) && (user.length>0)) prereq += "load:" + user;
          var onload = JSROOT.GetUrlOption('onload', src);
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index dc73bd0c4ff55..26d574c067e67 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -61,7 +61,9 @@
 
    JSROOT.Painter.createMenu = function(maincallback, menuname) {
       // dummy functions, forward call to the jquery function
+      document.body.style.cursor = 'wait';
       JSROOT.AssertPrerequisites('jq2d', function() {
+         document.body.style.cursor = 'auto';
          JSROOT.Painter.createMenu(maincallback, menuname);
       });
    }
@@ -97,12 +99,7 @@
          if ((col!=NaN) && (col>0) && (col<4)) JSROOT.gStyle.DefaultCol = col;
       }
 
-      var mathjax = JSROOT.GetUrlOption("mathjax", url);
-      if (mathjax == "") JSROOT.gStyle.MathJax = 1; else
-      if (mathjax != null) {
-         JSROOT.gStyle.MathJax = parseInt(mathjax);
-         if (JSROOT.gStyle.MathJax == NaN) JSROOT.gStyle.MathJax = 1;
-      }
+      if (JSROOT.GetUrlOption("mathjax", url) != null) JSROOT.MathJax = 1;
    }
 
    JSROOT.Painter.Coord = {
@@ -421,13 +418,6 @@
       return x;
    }
 
-   JSROOT.Painter.moveChildToEnd = function(child) {
-      if (!child) return;
-      var prnt = child.node().parentNode;
-      prnt.removeChild(child.node());
-      prnt.appendChild(child.node());
-   }
-
    JSROOT.Painter.ytoPad = function(y, pad) {
       if (pad['fLogy']) {
          if (y > 0)
@@ -803,6 +793,45 @@
       return str;
    }
 
+   JSROOT.Painter.isAnyLatex = function(str) {
+
+      return (str.indexOf("#")>=0) || (str.indexOf("\\")>=0) || (str.indexOf("{")>=0);
+
+      //var specials = "\\{}_()#";
+      //for (var i=0;i<str.length;i++) {
+      //   if (specials.indexOf(str[i])>=0) return true;
+      //}
+      //return false;
+
+      //for ( var x in JSROOT.Painter.symbols_map)
+      //   if (str.indexOf(x) >= 0) return true;
+   }
+
+   JSROOT.Painter.translateMath = function(str, kind) {
+      // function translate ROOT TLatex into MathJax format
+
+      if (kind!=2) {
+
+         for (var x in JSROOT.Painter.symbols_map) {
+            var y = "\\" + x.substr(1);
+            str = str.replace(new RegExp(x,'g'), y);
+         }
+
+         str = str.replace(/#frac/g, "\\frac");
+         str = str.replace(/#left{/g, "\\left\\{");
+         str = str.replace(/#right}/g, "\\right\\}");
+         str = str.replace(/#left/g, "\\left");
+         str = str.replace(/#right/g, "\\right");
+         // processing of #[] #{} should be done
+         str = str.replace(/#\[\]/g, "\\[]");
+      } else {
+         str = str.replace(/\\\^/g, "\\hat");
+      }
+
+
+      return "\\(" + str + "\\)";
+   }
+
    // ==============================================================================
 
    JSROOT.TBasePainter = function() {
@@ -943,6 +972,26 @@
       return this.svg_pad().select(".root_frame");
    }
 
+   JSROOT.TObjectPainter.prototype.pad_width = function() {
+      var res = parseInt(this.svg_pad().attr("width"));
+      return (res==NaN) ? 0 : res;
+   }
+
+   JSROOT.TObjectPainter.prototype.pad_height = function() {
+      var res = parseInt(this.svg_pad().attr("height"));
+      return (res==NaN) ? 0 : res;
+   }
+
+   JSROOT.TObjectPainter.prototype.frame_width = function() {
+      var res = parseInt(this.svg_frame().attr("width"));
+      return (res==NaN) ? 0 : res;
+   }
+
+   JSROOT.TObjectPainter.prototype.frame_height = function() {
+      var res = parseInt(this.svg_frame().attr("height"));
+      return (res==NaN) ? 0 : res;
+   }
+
    /** Returns main pad painter - normally TH1/TH2 painter, which draws all axis */
    JSROOT.TObjectPainter.prototype.main_painter = function() {
       if (!this.main) {
@@ -1177,158 +1226,166 @@
       if (pad_painter) pad_painter.Redraw();
    }
 
-   JSROOT.TObjectPainter.prototype.RemoveDrag = function(id) {
-      var drag_rect_name = id + "_drag_rect";
-      var resize_rect_name = id + "_resize_rect";
-      if (this[drag_rect_name]) {
-         this[drag_rect_name].remove();
-         this[drag_rect_name] = null;
-      }
-      if (this[resize_rect_name]) {
-         this[resize_rect_name].remove();
-         this[resize_rect_name] = null;
-      }
-   }
-
-   JSROOT.TObjectPainter.prototype.AddDrag = function(id, draw_g, callback) {
+   JSROOT.TObjectPainter.prototype.AddDrag = function(callback) {
       if (!JSROOT.gStyle.MoveResize) return;
 
       var pthis = this;
 
-      var drag_rect_name = id + "_drag_rect";
-      var resize_rect_name = id + "_resize_rect";
-
-      var rect_width = function() { return Number(draw_g.attr("width")); }
-      var rect_height = function() { return Number(draw_g.attr("height")); }
+      var rect_width = function() { return Number(pthis.draw_g.attr("width")); }
+      var rect_height = function() { return Number(pthis.draw_g.attr("height")); }
 
       var acc_x = 0, acc_y = 0, pad_w = 1, pad_h = 1;
 
+      function detectRightButton(event) {
+         if ('buttons' in event) return event.buttons === 2;
+         else if ('which' in event) return event.which === 2;
+         else if ('button' in event) return event.button === 2;
+         return false;
+      }
+
+      var resize_rect =
+         pthis.draw_g.append("rect")
+                  .style("opacity", "0")
+                  .style("cursor", "se-resize")
+                  .attr("x", rect_width() - 20)
+                  .attr("y", rect_height() - 20)
+                  .attr("width", 20)
+                  .attr("height", 20);
+
+      var drag_rect = null;
+
       var drag_move = d3.behavior.drag().origin(Object)
          .on("dragstart",  function() {
+            if (detectRightButton(d3.event.sourceEvent)) return;
+
             d3.event.sourceEvent.preventDefault();
 
             acc_x = 0; acc_y = 0;
-            pad_w = Number(pthis.svg_pad().attr("width")) - rect_width();
-            pad_h = Number(pthis.svg_pad().attr("height")) - rect_height();
+            pad_w = pthis.pad_width() - rect_width();
+            pad_h = pthis.pad_height() - rect_height();
 
-            pthis[drag_rect_name] =
-               pthis.svg_pad()
-                 .append("rect")
+            drag_rect = pthis.draw_g.append("rect")
                  .attr("class", "zoom")
-                 .attr("id", drag_rect_name)
-                 .attr("x",  draw_g.attr("x"))
-                 .attr("y", draw_g.attr("y"))
+                 .attr("x",  0)
+                 .attr("y", 0)
                  .attr("width", rect_width())
                  .attr("height", rect_height())
                  .style("cursor", "move");
           }).on("drag", function() {
+               if (drag_rect == null) return;
+
                d3.event.sourceEvent.preventDefault();
 
-               var x = Number(pthis[drag_rect_name].attr("x"));
-               var y = Number(pthis[drag_rect_name].attr("y"));
-               var dx = d3.event.dx, dy = d3.event.dy;
+               var x = Number(drag_rect.attr("x"));
+               var y = Number(drag_rect.attr("y"));
+               var real_x = Number(pthis.draw_g.attr("x")) + x;
+               var real_y = Number(pthis.draw_g.attr("y")) + y;
 
-               if (((acc_x<0) && (dx>0)) || ((acc_x>0) && (dx<0))) { acc_x += dx; dx = 0; }
-               if (((acc_y<0) && (dy>0)) || ((acc_y>0) && (dy<0))) { acc_y += dy; dy = 0; }
+               var dx = d3.event.dx, dy = d3.event.dy;
 
-               if ((x + dx < 0) || (x +dx > pad_w)) acc_x += dx; else x+=dx;
-               if ((y+dy < 0) || (y+dy > pad_h)) acc_y += dy; else y += dy;
+               if (((acc_x<0) && (dx>0)) || ((acc_x>0) && (dx<0))) { acc_x+=dx; dx=0; }
+               if (((acc_y<0) && (dy>0)) || ((acc_y>0) && (dy<0))) { acc_y+=dy; dy=0; }
 
-               pthis[drag_rect_name].attr("x", x);
-               pthis[drag_rect_name].attr("y", y);
+               if ((real_x+dx < 0) || (real_x+dx > pad_w)) acc_x+=dx; else x+=dx;
+               if ((real_y+dy < 0) || (real_y+dy > pad_h)) acc_y+=dy; else y+=dy;
 
-               JSROOT.Painter.moveChildToEnd(pthis[drag_rect_name]);
+               drag_rect.attr("x", x).attr("y", y);
 
                d3.event.sourceEvent.stopPropagation();
           }).on("dragend", function() {
+               if (drag_rect==null) return;
+
                d3.event.sourceEvent.preventDefault();
 
-               pthis[drag_rect_name].style("cursor", "auto");
+               drag_rect.style("cursor", "auto");
 
-               var x = Number(pthis[drag_rect_name].attr("x"));
-               var y = Number(pthis[drag_rect_name].attr("y"));
+               var dx = Number(drag_rect.attr("x"));
+               var dy = Number(drag_rect.attr("y"));
 
-               var dx = x - Number(draw_g.attr("x"));
-               var dy = y - Number(draw_g.attr("y"));
+               var x = Number(pthis.draw_g.attr("x")) + dx;
+               var y = Number(pthis.draw_g.attr("y")) + dy;
 
-               pthis[drag_rect_name].remove();
-               pthis[drag_rect_name] = null;
+               drag_rect.remove();
+               drag_rect = null;
 
-               draw_g.attr("x", x).attr("y", y);
+               pthis.draw_g.attr("x", x).attr("y", y);
+               pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
 
-               callback.move(x, y, dx, dy);
+               resize_rect.attr("x", rect_width() - 20)
+                          .attr("y", rect_height() - 20);
 
-               pthis[resize_rect_name]
-                    .attr("x", rect_width() - 20)
-                    .attr("y", rect_height() - 20);
+               if ('move' in callback) callback.move(x, y, dx, dy);
+               else if ('obj' in callback) {
+                  callback.obj['fX1NDC'] += dx / pthis.pad_width();
+                  callback.obj['fX2NDC'] += dx / pthis.pad_width();
+                  callback.obj['fY1NDC'] -= dy / pthis.pad_height();
+                  callback.obj['fY2NDC'] -= dy / pthis.pad_height();
+               }
             });
 
       var drag_resize = d3.behavior.drag().origin(Object)
         .on( "dragstart", function() {
+           if (detectRightButton(d3.event.sourceEvent)) return;
+
            d3.event.sourceEvent.stopPropagation();
            d3.event.sourceEvent.preventDefault();
 
            acc_x = 0; acc_y = 0;
-           pad_w = Number(pthis.svg_pad().attr("width")) - Number(draw_g.attr("x"));
-           pad_h = Number(pthis.svg_pad().attr("height")) - Number(draw_g.attr("y"));
-           pthis[drag_rect_name] =
-              pthis.svg_pad()
-                .append("rect")
+           pad_w = pthis.pad_width() - Number(pthis.draw_g.attr("x"));
+           pad_h = pthis.pad_height() - Number(pthis.draw_g.attr("y"));
+           drag_rect = pthis.draw_g.append("rect")
                 .attr("class", "zoom")
-                .attr("id", drag_rect_name)
-                .attr("x",  draw_g.attr("x"))
-                .attr("y", draw_g.attr("y"))
+                .attr("x",  0)
+                .attr("y", 0)
                 .attr("width", rect_width())
                 .attr("height", rect_height())
                 .style("cursor", "se-resize");
          }).on("drag", function() {
+            if (drag_rect == null) return;
+
             d3.event.sourceEvent.preventDefault();
 
-            var w = Number(pthis[drag_rect_name].attr("width"));
-            var h = Number(pthis[drag_rect_name].attr("height"));
+            var w = Number(drag_rect.attr("width"));
+            var h = Number(drag_rect.attr("height"));
             var dx = d3.event.dx, dy = d3.event.dy;
             if ((acc_x>0) && (dx<0)) { acc_x += dx; dx = 0; }
             if ((acc_y>0) && (dy<0)) { acc_y += dy; dy = 0; }
             if (w+dx > pad_w) acc_x += dx; else w+=dx;
             if (h+dy > pad_h) acc_y += dy; else h+=dy;
-            pthis[drag_rect_name].attr("width", w);
-            pthis[drag_rect_name].attr("height", h);
-
-            JSROOT.Painter.moveChildToEnd(pthis[drag_rect_name]);
+            drag_rect.attr("width", w).attr("height", h);
 
             d3.event.sourceEvent.stopPropagation();
          }).on( "dragend", function() {
+            if (drag_rect == null) return;
+
             d3.event.sourceEvent.preventDefault();
-            pthis[drag_rect_name].style("cursor", "auto");
 
-            var newwidth = Number(pthis[drag_rect_name].attr("width"));
-            var newheight = Number(pthis[drag_rect_name].attr("height"));
+            drag_rect.style("cursor", "auto");
+
+            var newwidth = Number(drag_rect.attr("width"));
+            var newheight = Number(drag_rect.attr("height"));
 
-            draw_g.attr('width', newwidth).attr('height', newheight);
+            pthis.draw_g.attr('width', newwidth).attr('height', newheight);
 
-            pthis[drag_rect_name].remove();
-            pthis[drag_rect_name] = null;
+            drag_rect.remove();
+            drag_rect = null;
 
-            callback.resize(newwidth, newheight);
+            resize_rect.attr("x", newwidth - 20)
+                       .attr("y", newheight - 20);
 
-            // do it after call-back - rectangle has correct coordinates
-            pthis[resize_rect_name]
-              .attr("x", newwidth - 20)
-              .attr("y", newheight - 20);
+            if ('resize' in callback) callback.resize(newwidth, newheight); else {
+                if ('obj' in callback) {
+                   callback.obj['fX2NDC'] = callback.obj['fX1NDC'] + newwidth  / pthis.pad_width();
+                   callback.obj['fY1NDC'] = callback.obj['fY2NDC'] - newheight / pthis.pad_height();
+                }
+                if (('redraw' in callback) &&
+                    (typeof pthis[callback.redraw] == 'function')) pthis[callback.redraw]();
+            }
          });
 
-      draw_g.call(drag_move);
+      pthis.draw_g.style("cursor", "move").call(drag_move);
 
-      this[resize_rect_name] =
-         draw_g.append("rect")
-                  .attr("class", resize_rect_name)
-                  .style("opacity", "0")
-                  .style("cursor", "se-resize")
-                  .attr("x", rect_width() - 20)
-                  .attr("y", rect_height() - 20)
-                  .attr("width", 20)
-                  .attr("height", 20)
-                  .call(drag_resize);
+      resize_rect.call(drag_resize);
    }
 
    JSROOT.TObjectPainter.prototype.FindPainterFor = function(selobj,selname) {
@@ -1358,6 +1415,230 @@
       // options
    }
 
+   JSROOT.TObjectPainter.prototype.StartTextDrawing = function(font_face, font_size, draw_g) {
+      // we need to preserve font to be able rescle at the end
+
+      if (!draw_g) draw_g = this.draw_g;
+
+      var font = JSROOT.Painter.getFontDetails(font_face, font_size);
+
+      draw_g.call(font.func);
+
+      draw_g.property('text_font', font);
+      draw_g.property('mathjax_cnt', 1); // one should wait until last call
+      draw_g.property('text_factor', 0.);
+      draw_g.property('max_text_width', 0); // keep maximal text width, use it later
+   }
+
+   JSROOT.TObjectPainter.prototype.TextScaleFactor = function(value, draw_g) {
+      // function used to remember maximal text scaling factor
+      if (!draw_g) draw_g = this.draw_g;
+      if (value && (value > draw_g.property('text_factor'))) draw_g.property('text_factor', value);
+   }
+
+   JSROOT.TObjectPainter.prototype.FinishTextDrawing = function(entry, draw_g) {
+      if (!draw_g) draw_g = this.draw_g;
+
+      if (entry != null) {
+
+         MathJax.Hub.Typeset(entry.node());
+
+         var scale = entry.property('_scale');
+         var fo = entry.property('_fo'); entry.property('_fo', null);
+         var align = entry.property('_align');
+
+         var prnt = entry.node();
+         if (scale) prnt = prnt.parentNode;
+         // getBoundingClientRect do not work for div with width/height attributes, check childs
+         // var rect = prnt.getBoundingClientRect();
+         var chlds = prnt.childNodes;
+         var left = 100000000, right = 0, top = 100000000, bottom = 0;
+         for (var n=0;n<chlds.length+1;n++) {
+            var rrr = null;
+            if (n<chlds.length) {
+               if (typeof chlds[n]['getBoundingClientRect'] != 'function') continue;
+               rrr = chlds[n].getBoundingClientRect();
+            } else {
+               if ((left<right) && (top<bottom)) continue;
+               rrr = prnt.getBoundingClientRect();
+            }
+
+            if ((rrr.left==rrr.right) || (rrr.top==rrr.bottom)) continue;
+
+            left = Math.min(left, parseInt(rrr.left));
+            right = Math.max(right, parseInt(rrr.right));
+            top = Math.min(top,parseInt(rrr.top));
+            bottom = Math.max(bottom, parseInt(rrr.bottom));
+            //console.log(n+ "  left = " + rrr.left + " right = " + rrr.right + " top = " + rrr.top + " bottom = " + rrr.bottom);
+         }
+         var real_w = right - left, real_h = bottom - top;
+
+         // console.log("childs width = " + real_w + "  left = " +left + " right = " + right + " rotate = " + rotate);
+         // console.log("childs height = " + real_h + " top = " + top + " bottom = " + bottom);
+
+         if (real_w > draw_g.property('max_text_width')) draw_g.property('max_text_width', real_w);
+         if (!scale) {
+            // only after drawing performed one could calculate size and adjust position
+            var dx = 0, dy = 0;
+            if (entry.property('_rotate')) {
+               if (align[1] == 'middle') dy = -real_w/2; else
+               if (align[1] == 'top') dy = -real_w;
+               if (align[0] == 'middle') dx = -real_h/2; else
+               if (align[0] == 'end') dx = -real_h;
+            } else {
+               if (align[1] == 'middle') dy = -real_h/2; else
+               if (align[1] == 'top') dy = -real_h;
+               if (align[0] == 'middle') dx = -real_w/2; else
+               if (align[0] == 'end') dx = -real_w;
+            }
+            if (dx != 0) { dx += parseInt(fo.attr('x')); fo.attr('x', dx); }
+            if (dy != 0) { dy += parseInt(fo.attr('y')); fo.attr('y', dy); }
+            return; // no need to continue when scaling not performed
+         }
+
+         this.TextScaleFactor(1.*real_w / parseInt(fo.attr('width')), draw_g);
+         this.TextScaleFactor(1.*real_h / parseInt(fo.attr('height')), draw_g);
+      }
+
+      var cnt = draw_g.property('mathjax_cnt') - 1;
+      draw_g.property('mathjax_cnt', cnt);
+      if (cnt > 0) return 0;
+
+      var f = draw_g.property('text_factor');
+      var font = draw_g.property('text_font');
+      if ((f>0) && ((f<0.9) || (f>1.))) {
+         font.size = Math.floor(font.size/f);
+         draw_g.call(font.func);
+      }
+
+      return draw_g.property('max_text_width');
+   }
+
+   JSROOT.TObjectPainter.prototype.DrawText = function(align_arg, x, y, w, h, label, tcolor, latex_kind, draw_g) {
+      if (!draw_g) draw_g = this.draw_g;
+      var align;
+
+      if (typeof align_arg == 'string') {
+         align = align_arg.split(";");
+         if (align.length==1) align.push('middle');
+      } else {
+         align = ['start', 'middle'];
+         if ((align_arg / 10) >= 3) align[0] = 'end'; else
+         if ((align_arg / 10) >= 2) align[0] = 'middle';
+         if ((align_arg % 10) == 1) align[1] = 'top'; else
+         if ((align_arg % 10) == 3) align[1] = 'bottom';
+      }
+
+      var scale = (w>0) && (h>0);
+
+      if (latex_kind==null) latex_kind = 1;
+      if (latex_kind<2)
+         if (!JSROOT.Painter.isAnyLatex(label)) latex_kind = 0;
+
+      if (((JSROOT.MathJax<1) && (latex_kind!=2)) || (latex_kind<1)) {
+         if (latex_kind>0) label = JSROOT.Painter.translateLaTeX(label);
+
+         var pos_x = x.toFixed(1);
+
+         if (scale) {
+            if (align[0]=="middle") pos_x = (x+w*0.5).toFixed(1); else
+            if (align[0]=="end") pos_x = (x+w).toFixed(1);
+         }
+
+         var txt = draw_g.append("text")
+                         .attr("text-anchor", align[0])
+                         .attr("x", pos_x)
+                         .attr("fill", tcolor ? tcolor : null)
+                         .text(label);
+
+         if (align[1]=="middle") txt.attr("dominant-baseline", "middle");
+
+         if (scale) {
+            if (align[1]=="middle") txt.attr("y", (y + h*0.5).toFixed(1));
+                               else txt.attr("y", y.toFixed(1));
+         } else {
+            txt.attr("y", y.toFixed(1));
+            if (h==-270) txt.attr("transform", "rotate(270, 0, 0)");
+         }
+
+         // console.log('text attr y = ' + txt.attr("y"));
+         var box = txt.node().getBBox();
+         var real_w = parseInt(box.width), real_h = parseInt(box.height);
+
+         if (!scale) {
+            // make adjustment after drawing
+            // if (align[0]=="middle") txt.attr("x", (x + real_w/2).toFixed(1)); else
+            // if (align[0]=="end") txt.attr("x", (x + real_w).toFixed(1));
+            // if (align[1]=="middle") txt.attr("y", (y-real_h/2).toFixed(1)); else
+
+            if ((align[1]=="bottom") && (h==0)) { txt.attr("y", (y-real_h).toFixed(1)); console.log('shift y due to vertical align'); }
+
+         }
+
+         if (real_w > draw_g.property('max_text_width')) draw_g.property('max_text_width', real_w);
+         if ((w>0) && scale) this.TextScaleFactor(real_w / w, draw_g);
+         if ((h>0) && scale) this.TextScaleFactor(real_h / h, draw_g);
+
+         return real_w;
+      }
+
+      w = Math.round(w); h = Math.round(h);
+      x = Math.round(x); y = Math.round(y);
+
+      var rotate = false;
+
+      if (!scale) {
+         if (h==-270) rotate = true;
+         w = this.pad_width(); h = this.pad_height(); // artifical values, big enough to see output
+      }
+
+      var fo = draw_g.append("foreignObject").attr("width", w).attr("height", h);
+      this.SetForeignObjectPosition(fo, x, y);
+      if (rotate) fo.attr("transform", "rotate(270, 0, 0)");
+
+      label = JSROOT.Painter.translateMath(label, latex_kind);
+
+      var entry = fo.append("xhtml:div");
+      if (scale) {
+         var tr = "";
+         entry = entry.style("width", w+"px")
+                      .style("height", h+"px")
+                      .append("xhtml:div")
+                      .style('position','absolute');
+         switch (align[0]) {
+            case 'left' : entry.style('left','0%'); break;
+            case 'middle' : entry.style('left','50%'); tr = "translateX(-50%) "; break;
+            case 'right' :  entry.style('left','100%'); tr = "translateX(-100%) "; break;
+         }
+         switch (align[1]) {
+            case 'top': entry.style('top','0%'); break;
+            case 'middle' : entry.style('top','50%'); tr+="translateY(-50%)"; break;
+            case 'bottom' :  entry.style('top','100%'); tr+="translateY(-100%)"; break;
+         }
+         if (tr.length>0) entry.style('transform', tr);
+      }
+
+
+      entry.style("color", tcolor ? tcolor : null);
+
+      entry.property("_painter", this)
+          .property("_scale", scale)
+          .property("_align", align) // keep align for the end
+          .property("_fo", fo) // keep foreign object till the end
+          .property("_rotate", rotate) // keep rotate attr the end
+          .html(label);
+
+      var cnt = draw_g.property('mathjax_cnt')+1;
+      draw_g.property('mathjax_cnt', cnt);
+
+      JSROOT.AssertPrerequisites('mathjax', { _this:entry, func: function() {
+         if (typeof MathJax != 'object') return;
+         MathJax.Hub.Queue(["FinishTextDrawing", this.property('_painter'), this]);
+      }});
+
+      return 0;
+   }
+
    // ===========================================================
 
    JSROOT.TFramePainter = function(tframe) {
@@ -1380,8 +1661,7 @@
    }
 
    JSROOT.TFramePainter.prototype.DrawFrameSvg = function() {
-      var width = Number(this.svg_pad().attr("width")),
-          height = Number(this.svg_pad().attr("height"));
+      var width = this.pad_width(), height = this.pad_height();
       var w = width, h = height;
 
       var ndc = this.svg_frame().empty() ? null : this.svg_frame().property('NDC');
@@ -1626,8 +1906,7 @@
    }
 
    JSROOT.TF1Painter.prototype.DrawBins = function() {
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       this.RecreateDrawG();
 
@@ -1875,8 +2154,7 @@
       this.lineatt.width = this.lineatt.width % 100; // line width
       if (this.lineatt.width > 0) this.optionLine = 1;
 
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       var ratio = w / h;
 
@@ -2088,9 +2366,7 @@
    }
 
    JSROOT.TGraphPainter.prototype.DrawBins = function() {
-
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       this.RecreateDrawG();
 
@@ -2344,77 +2620,61 @@
    JSROOT.TPavePainter.prototype.DrawPaveText = function() {
       var pavetext = this.pavetext;
 
-      var w = Number(this.svg_pad().attr("width")),
-          h = Number(this.svg_pad().attr("height"));
+      var w = this.pad_width(), h = this.pad_height();
 
-      var pos_x = Math.round(pavetext['fX1NDC'] * w);
+      if ((pavetext.fOption.indexOf("NDC")<0) && !pavetext.fInit) {
+         pavetext.fInit = 1;
+         var pad = this.root_pad();
+         if (pad!=null) {
+            if (pad['fLogx']) {
+               if (pavetext.fX1 > 0) pavetext.fX1 = JSROOT.Math.log10(pavetext.fX1);
+               if (pavetext.fX2 > 0) pavetext.fX2 = JSROOT.Math.log10(pavetext.fX2);
+            }
+            if (pad['fLogy']) {
+               if (pavetext.fY1 > 0) pavetext.fY1 = JSROOT.Math.log10(pavetext.fY1);
+               if (pavetext.fY2 > 0) pavetext.fY2 = JSROOT.Math.log10(pavetext.fY2);
+            }
+            pavetext['fX1NDC'] = (pavetext.fX1-pad['fX1'])/(pad['fX2'] - pad['fX1']);
+            pavetext['fY1NDC'] = (pavetext.fY1-pad['fY1'])/(pad['fY2'] - pad['fY1']);
+            pavetext['fX2NDC'] = (pavetext.fX2-pad['fX1'])/(pad['fX2'] - pad['fX1']);
+            pavetext['fY2NDC'] = (pavetext.fY2-pad['fY1'])/(pad['fY2'] - pad['fY1']);
 
+         } else {
+            pavetext['fX1NDC'] = 0.1;
+            pavetext['fX2NDC'] = 0.9;
+            pavetext['fY1NDC'] = 0.1;
+            pavetext['fY2NDC'] = 0.9;
+         }
+      }
+
+      var pos_x = Math.round(pavetext['fX1NDC'] * w);
       var pos_y = Math.round((1.0 - pavetext['fY1NDC']) * h);
       var width = Math.round(Math.abs(pavetext['fX2NDC'] - pavetext['fX1NDC']) * w);
       var height = Math.round(Math.abs(pavetext['fY2NDC'] - pavetext['fY1NDC']) * h);
+
       pos_y -= height;
       var nlines = pavetext['fLines'].arr.length;
       var tcolor = JSROOT.Painter.root_colors[pavetext['fTextColor']];
       var scolor = JSROOT.Painter.root_colors[pavetext['fShadowColor']];
       var fcolor = this.createAttFill(pavetext);
 
-      // align = 10*HorizontalAlign + VerticalAlign
-      // 1=left adjusted, 2=centered, 3=right adjusted
-      // 1=bottom adjusted, 2=centered, 3=top adjusted
-      // "middle", "start", "end"
-      var align = 'start', halign = Math.round(pavetext['fTextAlign'] / 10);
-      var baseline = 'bottom', valign = pavetext['fTextAlign'] % 10;
-      if (halign == 1) align = 'start';
-      else if (halign == 2) align = 'middle';
-      else if (halign == 3) align = 'end';
-      if (valign == 1)  baseline = 'bottom';
-      else if (valign == 2) baseline = 'middle';
-      else if (valign == 3) baseline = 'top';
-
-      var h_margin = Math.round(pavetext['fMargin'] * width); // horizontal margin
-
-      var font = JSROOT.Painter.getFontDetails(pavetext['fTextFont'], height / (nlines * 1.2));
-
       var lwidth = pavetext['fBorderSize'] ? pavetext['fBorderSize'] : 0;
       var attline = JSROOT.Painter.createAttLine(pavetext, lwidth>0 ? 1 : 0);
 
-      var first_stat = 0, num_cols = 0, maxlw = 0;
+      var first_stat = 0, num_cols = 0;
       var lines = new Array;
 
       // adjust font size
       for (var j = 0; j < nlines; ++j) {
-         var line = JSROOT.Painter.translateLaTeX(pavetext['fLines'].arr[j]['fTitle']);
+         var line = pavetext['fLines'].arr[j]['fTitle'];
          lines.push(line);
-         var lw = h_margin + font.stringWidth(this.svg_pad(), line) + h_margin;
-         if (lw > maxlw) maxlw = lw;
-         if ((j == 0) || (line.indexOf('|') < 0)) continue;
+         if (!this.IsStats() || (j == 0) || (line.indexOf('|') < 0)) continue;
          if (first_stat === 0) first_stat = j;
          var parts = line.split("|");
          if (parts.length > num_cols)
             num_cols = parts.length;
       }
 
-      if (maxlw > width)
-         font.size = Math.floor(font.size * (width / maxlw));
-      else
-      if ((nlines==1) && (lwidth==0) && (maxlw < width - 40))  {
-         // adjust invisible size of the pave for comfort resizing
-         var diff = width - maxlw;
-         width -= diff;
-         pos_x += diff/2;
-         pavetext['fX1NDC'] = pos_x / w;
-         pavetext['fX2NDC'] = (pos_x + width) / w;
-      }
-
-      var h_margin = Math.round(pavetext['fMargin'] * width); // horizontal margin again
-      var text_pos_x = h_margin / 2; // position of text inside <g> element
-      if (nlines == 1)
-         switch (halign) {
-            case 1: text_pos_x = h_margin; break;
-            case 2: text_pos_x = width / 2; break;
-            case 3: text_pos_x = width - h_margin; break;
-         }
-
       var pthis = this;
 
       // container used to recalculate coordinates
@@ -2428,7 +2688,7 @@
            .attr("height", height)
            .attr("transform", "translate(" + pos_x + "," + pos_y + ")");
 
-      this.draw_g.append("rect")
+      var rect = this.draw_g.append("rect")
           .attr("x", 0)
           .attr("y", 0)
           .attr("width", width)
@@ -2437,72 +2697,51 @@
           .call(attline.func);
 
       // for characters like 'p' or 'y' several more pixels required to stay in the box when drawn in last line
-      var stepy = (height - 0.2*font.size) / nlines;
+      var stepy = height / nlines;
+      var margin_x = pavetext['fMargin'] * width;
+
+      this.StartTextDrawing(pavetext['fTextFont'], height/(nlines * 1.2));
 
       if (nlines == 1) {
-         this.draw_g.append("text")
-              .attr("text-anchor", align)
-              .attr("x", text_pos_x)
-              .attr("y", ((height / 2) + (font.size / 3)).toFixed(1))
-              .call(font.func)
-              .attr("fill", tcolor)
-              .text(lines[0]);
+         this.DrawText(pavetext['fTextAlign'], 0, 0, width, height, lines[0], tcolor);
       } else {
-
          for (var j = 0; j < nlines; ++j) {
             var jcolor = JSROOT.Painter.root_colors[pavetext['fLines'].arr[j]['fTextColor']];
             if (pavetext['fLines'].arr[j]['fTextColor'] == 0) jcolor = tcolor;
-            var posy = (j+0.5)*stepy + font.size*0.5 - 1;
+            var posy = j*stepy;
 
-            if (pavetext['_typename'] == 'TPaveStats') {
+            if (this.IsStats()) {
                if ((first_stat > 0) && (j >= first_stat)) {
                   var parts = lines[j].split("|");
                   for (var n = 0; n < parts.length; n++)
-                     this.draw_g.append("text")
-                           .attr("text-anchor", "middle")
-                           .attr("x", (width * (n + 0.5) / num_cols).toFixed(1))
-                           .attr("y", posy.toFixed(1))
-                           .call(font.func)
-                           .attr("fill", jcolor)
-                           .text(parts[n]);
+                     this.DrawText("middle",
+                                    width * n / num_cols, posy,
+                                    width/num_cols, stepy, parts[n], jcolor);
                } else if ((j == 0) || (lines[j].indexOf('=') < 0)) {
-                  this.draw_g.append("text")
-                        .attr("text-anchor", (j == 0) ? "middle" : "start")
-                        .attr("x", ((j == 0) ? width / 2 : pavetext['fMargin'] * width).toFixed(1))
-                        .attr("y", posy.toFixed(1))
-                        .call(font.func)
-                        .attr("fill", jcolor)
-                        .text(lines[j]);
+                   this.DrawText((j == 0) ? "middle" : "start",
+                                 margin_x, posy, width-2*margin_x, stepy, lines[j], jcolor);
                } else {
-                  var parts = lines[j].split("=");
+                  var parts = lines[j].split("="), sumw = 0;
                   for (var n = 0; n < 2; n++)
-                     this.draw_g.append("text")
-                            .attr("text-anchor", (n == 0) ? "start" : "end")
-                            .attr("x", ((n == 0) ? pavetext['fMargin'] * width  : (1 - pavetext['fMargin']) * width).toFixed(1))
-                            .attr("y", posy.toFixed(1))
-                            .call(font.func)
-                            .attr("fill", jcolor)
-                            .text(parts[n]);
+                     sumw += this.DrawText((n == 0) ? "start" : "end",
+                                      margin_x, posy, width-2*margin_x, stepy, parts[n], jcolor);
+                  this.TextScaleFactor(sumw/(width-2*margin_x), this.draw_g);
                }
             } else {
-               this.draw_g.append("text")
-                      .attr("text-anchor", "start")
-                      .attr("x", text_pos_x.toFixed(1))
-                      .attr("y", posy.toFixed(1))
-                      .call(font.func)
-                      .attr("fill", jcolor)
-                      .text(lines[j]);
+               this.DrawText(pavetext['fTextAlign'], margin_x, posy, width-2*margin_x, stepy, lines[j], jcolor);
             }
          }
       }
 
+      var maxtw = this.FinishTextDrawing();
+
       if (pavetext['fBorderSize'] && (pavetext['_typename'] == 'TPaveStats')) {
          this.draw_g.append("svg:line")
                     .attr("class", "pavedraw")
                     .attr("x1", 0)
-                    .attr("y1", stepy)
+                    .attr("y1", stepy.toFixed(1))
                     .attr("x2", width)
-                    .attr("y2", stepy)
+                    .attr("y2", stepy.toFixed(1))
                     .call(attline.func);
       }
 
@@ -2510,16 +2749,16 @@
          for (var nrow = first_stat; nrow < nlines; nrow++)
             this.draw_g.append("svg:line")
                        .attr("x1", 0)
-                       .attr("y1", nrow * stepy)
+                       .attr("y1", (nrow * stepy).toFixed(1))
                        .attr("x2", width)
-                       .attr("y2", nrow * stepy)
+                       .attr("y2", (nrow * stepy).toFixed(1))
                        .call(attline.func);
 
          for (var ncol = 0; ncol < num_cols - 1; ncol++)
             this.draw_g.append("svg:line")
-                        .attr("x1", width / num_cols * (ncol + 1))
-                        .attr("y1", first_stat * stepy)
-                        .attr("x2", width / num_cols * (ncol + 1))
+                        .attr("x1", (width / num_cols * (ncol + 1)).toFixed(1))
+                        .attr("y1", (first_stat * stepy).toFixed(1))
+                        .attr("x2", (width / num_cols * (ncol + 1)).toFixed(1))
                         .attr("y2", height)
                         .call(attline.func);
       }
@@ -2541,22 +2780,30 @@
                     .style("stroke-width", lwidth);
       }
 
-      this.AddDrag("stat", this.draw_g, {
-         move : function(x, y, dx, dy) {
-            pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
+      if ((pavetext.fLabel.length>0) && !this.IsStats()) {
+         var lbl_g = this.draw_g.append("svg:g")
+               .attr("x", width*0.25)
+               .attr("y", -h*0.02)
+               .attr("width", width*0.5)
+               .attr("height", h*0.04)
+               .attr("transform", "translate(" + width*0.25 + "," + -h*0.02 + ")");
 
-            pthis.pavetext['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pthis.pavetext['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pthis.pavetext['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-            pthis.pavetext['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-         },
-         resize : function(width, height) {
-            pthis.pavetext['fX2NDC'] = pthis.pavetext['fX1NDC'] + width  / Number(pthis.svg_pad().attr("width"));
-            pthis.pavetext['fY1NDC'] = pthis.pavetext['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
+         var lbl_rect = lbl_g.append("rect")
+               .attr("x", 0)
+               .attr("y", 0)
+               .attr("width", width*0.5)
+               .attr("height", h*0.04)
+               .call(fcolor.func)
+               .call(attline.func);
 
-            pthis.DrawPaveText();
-         }
-      });
+         this.StartTextDrawing(pavetext['fTextFont'], h*0.04/1.5, lbl_g);
+
+         this.DrawText(22, 0, 0, width*0.5, h*0.04, pavetext.fLabel, tcolor, 1, lbl_g);
+
+         this.FinishTextDrawing(null, lbl_g);
+      }
+
+      this.AddDrag({ obj:pavetext, redraw:'DrawPaveText' });
    }
 
    JSROOT.TPavePainter.prototype.AddLine = function(txt) {
@@ -2566,7 +2813,7 @@
 
    JSROOT.TPavePainter.prototype.IsStats = function() {
       if (!this.pavetext) return false;
-      return this.pavetext['fName'] == "stats";
+      return (this.pavetext['fName'] == "stats") && (this.pavetext['_typename'] == 'TPaveStats');
    }
 
    JSROOT.TPavePainter.prototype.FillStatistic = function() {
@@ -2593,24 +2840,16 @@
 
    JSROOT.TPavePainter.prototype.Redraw = function() {
 
-      this.RemoveDrawG();
-
       // if pavetext artificially disabled, do not redraw it
-      if (!this.Enabled) {
-         this.RemoveDrag("stat");
-         return;
+      if (this.Enabled) {
+         this.FillStatistic();
+         this.DrawPaveText();
+      } else {
+         this.RemoveDrawG();
       }
-
-      this.FillStatistic();
-
-      this.DrawPaveText();
    }
 
    JSROOT.Painter.drawPaveText = function(divid, pavetext) {
-      if (pavetext['fX1NDC'] < 0.0 || pavetext['fY1NDC'] < 0.0 ||
-          pavetext['fX1NDC'] > 1.0 || pavetext['fY1NDC'] > 1.0)
-         return null;
-
       var painter = new JSROOT.TPavePainter(pavetext);
 
       painter.SetDivId(divid);
@@ -2896,8 +3135,7 @@
       var nbr1 = axis['fNdiv'] % 100;
       if (nbr1<=0) nbr1 = 8;
 
-      var width = Number(this.svg_pad().attr("width")),
-          height = Number(this.svg_pad().attr("height"));
+      var width = this.pad_width(), height = this.pad_height();
 
       var s_height = Math.round(Math.abs(palette['fY2NDC'] - palette['fY1NDC']) * height);
 
@@ -2972,26 +3210,7 @@
                 .call(titlefont.func);
       }
 
-      var pthis = this;
-
-      this.AddDrag("colz", this.draw_g, {
-         move : function(x, y, dx, dy) {
-
-            pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
-
-            pthis.palette['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pthis.palette['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pthis.palette['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-            pthis.palette['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-         },
-         resize : function(width, height) {
-            pthis.palette['fX2NDC'] = pthis.palette['fX1NDC'] + width / Number(pthis.svg_pad().attr("width"));
-            pthis.palette['fY1NDC'] = pthis.palette['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
-
-            pthis.RemoveDrawG();
-            pthis.DrawPalette();
-         }
-      });
+      this.AddDrag({ obj: palette, redraw: 'DrawPalette' });
    }
 
    JSROOT.TColzPalettePainter.prototype.Redraw = function() {
@@ -3006,7 +3225,6 @@
       } else {
          // if palette artificially disabled, do not redraw it
          this.RemoveDrawG();
-         this.RemoveDrag("colz");
       }
    }
 
@@ -3659,8 +3877,7 @@
          return;
       }
 
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       if (this.histo['fXaxis']['fTimeDisplay']) {
          this.x_time = true;
@@ -3788,7 +4005,7 @@
       // add a grid on x axis, if the option is set
       if (this.options.Gridx) {
 
-         var h = Number(this.svg_frame().attr("height"));
+         var h = this.frame_height();
 
          var xticks = this.x.ticks(this.x_nticks);
 
@@ -3807,7 +4024,7 @@
 
       // add a grid on y axis, if the option is set
       if (this.options.Gridy) {
-         var w = Number(this.svg_frame().attr("width"));
+         var w = this.frame_width();
 
          var yticks = this.y.ticks(this.y_nticks);
 
@@ -3861,8 +4078,7 @@
 
       if (!this.is_main_painter()) return;
 
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       var xax_g = this.svg_frame().selectAll(".xaxis_container");
       if (xax_g.empty())
@@ -3886,39 +4102,35 @@
       var n3ay = ndivy / 10000;
 
       /* X-axis label */
-      var label = JSROOT.Painter.translateLaTeX(this.histo['fXaxis']['fTitle']);
+      var xlabelfont = JSROOT.Painter.getFontDetails(this.histo['fXaxis']['fLabelFont'], this.histo['fXaxis']['fLabelSize'] * h);
+
       var xAxisLabelOffset = 3 + (this.histo['fXaxis']['fLabelOffset'] * h);
 
-      var xlabelfont = JSROOT.Painter.getFontDetails(this.histo['fXaxis']['fLabelFont'], this.histo['fXaxis']['fLabelSize'] * h);
+      if (this.histo['fXaxis']['fTitle'].length > 0) {
+          this.StartTextDrawing(this.histo['fXaxis']['fTitleFont'], this.histo['fXaxis']['fTitleSize'] * h, xax_g);
 
-      var ylabelfont = JSROOT.Painter.getFontDetails(this.histo['fYaxis']['fLabelFont'], this.histo['fYaxis']['fLabelSize'] * h);
+          var res = this.DrawText('end', w, xAxisLabelOffset + xlabelfont.size * (1.+this.histo['fXaxis']['fTitleOffset']),
+                                    0, 0, this.histo['fXaxis']['fTitle'], null, 1, xax_g);
 
-      if (label.length > 0) {
-         var xtitlefont = JSROOT.Painter.getFontDetails(this.histo['fXaxis']['fTitleFont'], this.histo['fXaxis']['fTitleSize'] * h);
-         xax_g.append("text")
-               .attr("class", "x_axis_label")
-               .attr("x", w)
-               .attr("y", xlabelfont.size + xAxisLabelOffset * this.histo['fXaxis']['fTitleOffset'] + xtitlefont.size)
-               .attr("text-anchor", "end")
-               .call(xtitlefont.func)
-               .text(label);
+          if (res<=0) shrink_forbidden = true;
+
+          this.FinishTextDrawing(null, xax_g);
       }
 
       /* Y-axis label */
-      label = JSROOT.Painter.translateLaTeX(this.histo['fYaxis']['fTitle']);
-
       var yAxisLabelOffset = 3 + (this.histo['fYaxis']['fLabelOffset'] * w);
 
-      if (label.length > 0) {
-         var ytitlefont = JSROOT.Painter.getFontDetails(this.histo['fYaxis']['fTitleFont'], this.histo['fYaxis']['fTitleSize'] * h);
-         yax_g.append("text")
-                .attr("class", "y_axis_label")
-                .attr("x", 0)
-                .attr("y", - ylabelfont.size - ytitlefont.size - yAxisLabelOffset * this.histo['fYaxis']['fTitleOffset'])
-                .call(ytitlefont.func)
-                .attr("text-anchor", "end")
-                .text(label)
-                .attr("transform", "rotate(270, 0, 0)");
+      var ylabelfont = JSROOT.Painter.getFontDetails(this.histo['fYaxis']['fLabelFont'], this.histo['fYaxis']['fLabelSize'] * h);
+
+      if (this.histo['fYaxis']['fTitle'].length > 0) {
+         this.StartTextDrawing(this.histo['fYaxis']['fTitleFont'], this.histo['fYaxis']['fTitleSize'] * h, yax_g);
+
+         var res = this.DrawText("end", 0, - yAxisLabelOffset - (1 + this.histo['fYaxis']['fTitleOffset']) * ylabelfont.size - yax_g.property('text_font').size,
+                                   0, -270, this.histo['fYaxis']['fTitle'], null, 1, yax_g);
+
+         if (res<=0) shrink_forbidden = true;
+
+         this.FinishTextDrawing(null, yax_g);
       }
 
       var xAxisColor = this.histo['fXaxis']['fAxisColor'];
@@ -3928,9 +4140,7 @@
 
       var pthis = this;
 
-      /*
-       * Define the scales, according to the information from the pad
-       */
+      /* Define the scales, according to the information from the pad */
 
       delete this['formatx'];
 
@@ -4046,7 +4256,6 @@
          y_axis.tickFormat(function(d) { return pthis.formaty(d); });
 
 
-
       xax_g.append("svg:g").attr("class", "xaxis").call(x_axis);
 
       // this is additional ticks, required in d3.v3
@@ -4072,9 +4281,11 @@
          yax_g.append("svg:g").attr("class", "yaxis").call(y_axis_sub);
       }
 
-      xax_g.selectAll("text").call(xlabelfont.func);
+      // xax_g.selectAll("text").call(xlabelfont.func);
+      // yax_g.selectAll("text").call(ylabelfont.func);
 
-      yax_g.selectAll("text").call(ylabelfont.func);
+      xax_g.call(xlabelfont.func);
+      yax_g.call(ylabelfont.func);
 
       // we will use such rect for zoom selection
       if (JSROOT.gStyle.Zooming) {
@@ -4362,8 +4573,7 @@
 
       // if (!this.draw_content) return;
 
-      var width = Number(this.svg_frame().attr("width")),
-          height = Number(this.svg_frame().attr("height"));
+      var width = this.frame_width(), height = this.frame_height();
       var e, origin, curr = null, rect = null;
       var lasttouch = new Date(0);
 
@@ -4572,17 +4782,8 @@
          d3.event.stopPropagation();
       }
 
-      function detectLeftButton(event) {
-         if ('buttons' in event) return event.buttons === 1;
-         else if ('which' in event) return event.which === 1;
-         else return event.button === 1;
-       }
-
       function startRectSel() {
 
-         // use only left button
-         // if (!detectLeftButton(d3.event)) return;
-
          // ignore when touch selection is actiavated
          if (zoom_kind > 100) return;
 
@@ -5144,8 +5345,7 @@
 
    JSROOT.TH1Painter.prototype.DrawBins = function() {
 
-      var width = Number(this.svg_frame().attr("width")),
-          height = Number(this.svg_frame().attr("height"));
+      var width = this.frame_width(), height = this.frame_height();
 
       if (!this.draw_content || (width<=0) || (height<=0)) {
          this.RemoveDrawG();
@@ -5443,8 +5643,7 @@
       // and at the end try to check how much place will be used by the labels
       // in the palette
 
-      var width = Number(this.svg_frame().attr("width")),
-          height = Number(this.svg_frame().attr("height"));
+      var width = this.frame_width(), height = this.frame_height();
 
       var axisOffset = Math.round(axis['fLabelOffset'] * width);
       var tickSize = Math.round(axis['fTickSize'] * width);
@@ -5837,8 +6036,7 @@
 
       this.RecreateDrawG();
 
-      var w = Number(this.svg_frame().attr("width")),
-          h = Number(this.svg_frame().attr("height"));
+      var w = this.frame_width(), h = this.frame_height();
 
       if ((this.options.Color==2) && !JSROOT.browser.isIE)
          return this.DrawSimpleCanvas(w,h);
@@ -6181,15 +6379,18 @@
       var lwidth = pave['fBorderSize'] ? pave['fBorderSize'] : 0;
       var fill = this.createAttFill(pave);
       var lcolor = JSROOT.Painter.createAttLine(pave, lwidth);
+      var nlines = pave.fPrimitives.arr.length;
 
-      var p = this.draw_g
-                 .attr("x", x)
+      this.draw_g.attr("x", x)
                  .attr("y", y)
                  .attr("width", w)
                  .attr("height", h)
                  .attr("transform", "translate(" + x + "," + y + ")");
 
-      p.append("svg:rect")
+      this.StartTextDrawing(pave['fTextFont'], h / (nlines * 1.2));
+
+      this.draw_g
+           .append("svg:rect")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", w)
@@ -6202,22 +6403,8 @@
       var tpos_x = Math.round(pave['fMargin'] * w);
       var padding_x = Math.round(0.03 * w);
       var padding_y = Math.round(0.03 * h);
-      var nlines = pave.fPrimitives.arr.length;
-      var font = JSROOT.Painter.getFontDetails(pave['fTextFont'], h / (nlines * 1.5));
 
-      var min_fact = 1.;
-      for (var j = 0; j < nlines; ++j) {
-         var leg = pave.fPrimitives.arr[j];
-         var lopt = leg['fOption'].toLowerCase();
-         var label = JSROOT.Painter.translateLaTeX(leg['fLabel']);
-         var lw = font.stringWidth(svg, label);
-         var allowed = w - 2*padding_x;
-         if ((lopt.indexOf("h")<0) && (lopt.length>0)) allowed = w - tpos_x - padding_x;
-         var fact = lw > 5 ? allowed / lw : 1.;
-         if (fact < min_fact) min_fact = fact;
-      }
-
-      if (min_fact<1) font.size = Math.floor(font.size * min_fact);
+      var leg_painter = this;
 
       var step_y = (h - 2*padding_y)/nlines;
 
@@ -6225,9 +6412,8 @@
          var leg = pave.fPrimitives.arr[i];
          var lopt = leg['fOption'].toLowerCase();
 
-         var label = JSROOT.Painter.translateLaTeX(leg['fLabel']);
-
-         var pos_y = padding_y + (i+0.5)*step_y; // middle of each line
+         var pos_y = Math.round(padding_y + i*step_y); // top corner
+         var mid_y = Math.round(padding_y + (i+0.5)*step_y); // top corner
 
          var attfill = leg;
          var attmarker = leg;
@@ -6248,21 +6434,21 @@
          if (lopt.indexOf('f') != -1) {
             // box total height is yspace*0.7
             // define x,y as the center of the symbol for this entry
-            p.append("svg:rect")
+            this.draw_g.append("svg:rect")
                    .attr("x", padding_x)
-                   .attr("y", pos_y-step_y/3)
+                   .attr("y", Math.round(pos_y+step_y*0.1))
                    .attr("width", tpos_x - 2*padding_x)
-                   .attr("height", 2*step_y/3)
+                   .attr("height", Math.round(step_y*0.8))
                    .call(llll.func)
                    .call(fill.func);
          }
          // Draw line
          if (lopt.indexOf('l') != -1) {
-            p.append("svg:line")
+            this.draw_g.append("svg:line")
                .attr("x1", padding_x)
-               .attr("y1", pos_y)
+               .attr("y1", mid_y)
                .attr("x2", tpos_x - padding_x)
-               .attr("y2", pos_y)
+               .attr("y2", mid_y)
                .call(llll.func);
          }
          // Draw error only
@@ -6271,71 +6457,28 @@
          // Draw Polymarker
          if (lopt.indexOf('p') != -1) {
             var marker = JSROOT.Painter.createAttMarker(attmarker);
-            p.append("svg:path")
-                .attr("transform", function(d) { return "translate(" + tpos_x/2 + "," + pos_y + ")"; })
+            this.draw_g.append("svg:path")
+                .attr("transform", function(d) { return "translate(" + tpos_x/2 + "," + mid_y + ")"; })
                 .call(marker.func);
          }
 
          var pos_x = tpos_x;
          if ((lopt.indexOf('h')>=0) || (lopt.length==0)) pos_x = padding_x;
 
-         if ((JSROOT.gStyle.MathJax < 1) || (label.indexOf("#frac")<0)) {
-           p.append("text")
-              .attr("class", "text")
-              .attr("text-anchor", "start")
-              .attr("dominant-baseline", "central")
-              .attr("x", pos_x)
-              .attr("y", pos_y /*+ font.size*0.3*/)
-              .call(font.func)
-              .attr("fill", tcolor)
-              .text(label);
-         } else {
-
-            var fo_x = Math.round(pos_x);
-            var fo_y = Math.round(pos_y - 0.5*step_y);
-            var fo_w = Math.round(w - padding_x - pos_x);
-            var fo_h = Math.round(step_y);
-
-            var fo = this.draw_g.append("foreignObject").attr("width", fo_w).attr("height", fo_h);
-            this.SetForeignObjectPosition(fo, fo_x, fo_y);
-
-            // this is just workaround, one need real parser to find all #frac and so on
-            label = label.replace("#frac","\\(\\frac") + "\\)";
-
-            var body = fo.append("xhtml:body")
-                         .style("display", "table")
-                         .append("xhtml:div")
-                         .style("display", "table-cell")
-                         .style('vertical-align', 'middle') // force to align in the center
-                         .style("font", font.asStyle())
-                         .html(label);
-
-            JSROOT.AssertPrerequisites('mathjax', function() {
-               if (typeof MathJax != 'object') return;
-
-               MathJax.Hub.Queue(function() {
-                  MathJax.Hub.Typeset(body.node());
-                  // rescale one again
-                  var rect = body.node().getBoundingClientRect();
-                  var fact_x = parseInt(rect.right - rect.left) / fo_w;
-                  var fact_y = parseInt(rect.bottom - rect.top) / fo_h;
-                  if (Math.max(fact_x, fact_y) > 1)
-                     body.style("font", font.asStyle(Math.round(font.size/Math.max(fact_x, fact_y))));
-               });
-            });
-
+         this.DrawText("start", pos_x, pos_y, w-pos_x-padding_x, step_y, leg['fLabel'], tcolor);
+      }
 
-         }
+      // rescale after all entries are shown
+      this.FinishTextDrawing();
 
-      }
       if (lwidth && lwidth > 1) {
-         p.append("svg:line")
+         this.draw_g.append("svg:line")
             .attr("x1", w + (lwidth / 2))
             .attr("y1", lwidth + 1)
             .attr("x2", w + (lwidth / 2))
             .attr("y2",  h + lwidth - 1)
             .call(lcolor.func);
-         p.append("svg:line")
+         this.draw_g.append("svg:line")
             .attr("x1", lwidth + 1)
             .attr("y1", h + (lwidth / 2))
             .attr("x2", w + lwidth - 1)
@@ -6343,24 +6486,7 @@
             .call(lcolor.func);
       }
 
-      var pthis = this;
-
-      this.AddDrag('leg', this.draw_g, {
-         move : function(x, y, dx, dy) {
-            pthis.draw_g.attr("transform", "translate(" + x + "," + y + ")");
-
-            pave['fX1NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pave['fX2NDC'] += dx / Number(pthis.svg_pad().attr("width"));
-            pave['fY1NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-            pave['fY2NDC'] -= dy / Number(pthis.svg_pad().attr("height"));
-         },
-         resize : function(width, height) {
-            pave['fX2NDC'] = pave['fX1NDC'] + width  / Number(pthis.svg_pad().attr("width"));
-            pave['fY1NDC'] = pave['fY2NDC'] - height / Number(pthis.svg_pad().attr("height"));
-
-            pthis.drawLegend();
-         }
-      });
+      this.AddDrag({ obj:pave, redraw: 'drawLegend' });
    }
 
    JSROOT.TLegendPainter.prototype.Redraw = function() {
@@ -6539,8 +6665,7 @@
 
       var pavelabel = this.text;
 
-      var w = Number(this.svg_pad().attr("width")),
-          h = Number(this.svg_pad().attr("height"));
+      var w = this.pad_width(), h = this.pad_height();
 
       var pos_x = pavelabel['fX1NDC'] * w;
       var pos_y = (1.0 - pavelabel['fY1NDC']) * h;
@@ -6562,18 +6687,14 @@
       if (valign == 1) baseline = 'bottom';
       else if (valign == 2) baseline = 'middle';
       else if (valign == 3) baseline = 'top';
-      var lmargin = 0;
-      switch (halign) {
-         case 1: lmargin = pavelabel['fMargin'] * width; break;
-         case 2: lmargin = width / 2; break;
-         case 3: lmargin = width - (pavelabel['fMargin'] * width); break;
-      }
+
       var lwidth = pavelabel['fBorderSize'] ? pavelabel['fBorderSize'] : 0;
-      var font = JSROOT.Painter.getFontDetails(pavelabel['fTextFont'], height / 1.9);
 
       var lcolor = JSROOT.Painter.createAttLine(pavelabel, lwidth);
 
       var pave = this.draw_g
+                   .attr("x", pos_x)
+                   .attr("y", pos_y)
                    .attr("width", width)
                    .attr("height", height)
                    .attr("transform", "translate(" + pos_x + "," + pos_y + ")");
@@ -6587,19 +6708,11 @@
              .style("stroke-width", lwidth ? 1 : 0)
              .style("stroke", lcolor.color);
 
-      var line = JSROOT.Painter.translateLaTeX(pavelabel['fLabel']);
+      this.StartTextDrawing(pavelabel['fTextFont'], height / 1.7);
 
-      var lw = font.stringWidth(this.svg_pad(), line);
-      if (lw > width) font.size = Math.floor(font.size * (width / lw));
+      this.DrawText(align, 0.02*width, 0, 0.96*width, height, pavelabel['fLabel'], tcolor);
 
-      pave.append("text")
-             .attr("class", "text")
-             .attr("text-anchor", align)
-             .attr("x", lmargin)
-             .attr("y", (height / 2) + (font.size / 3))
-             .call(font.func)
-             .attr("fill", tcolor)
-             .text(line);
+      this.FinishTextDrawing();
 
       if (lwidth && lwidth > 1) {
          pave.append("svg:line")
@@ -6615,35 +6728,24 @@
                .attr("y2", height + (lwidth / 2))
                .call(lcolor.func);
       }
+
+      var pave_painter = this;
+
+      this.AddDrag({ obj : pavelabel, redraw:'drawPaveLabel' });
    }
 
    JSROOT.TTextPainter.prototype.drawText = function() {
-      this.RecreateDrawG(true, ".text_layer");
 
       var kTextNDC = JSROOT.BIT(14);
 
-      var w = Number(this.svg_pad().attr("width")),
-          h = Number(this.svg_pad().attr("height"));
-      var align = 'start', halign = Math.round(this.text['fTextAlign'] / 10);
-      var baseline = 'bottom', valign = this.text['fTextAlign'] % 10;
-      if (halign == 1) align = 'start';
-      else if (halign == 2) align = 'middle';
-      else if (halign == 3) align = 'end';
-      if (valign == 1) baseline = 'bottom';
-      else if (valign == 2) baseline = 'middle';
-      else if (valign == 3) baseline = 'top';
-      var lmargin = 0;
-      switch (halign) {
-         case 1: lmargin = this.text['fMargin'] * w; break;
-         case 2: lmargin = w / 2; break;
-         case 3: lmargin = w - (this.text['fMargin'] * w); break;
-      }
+      var w = this.pad_width(), h = this.pad_height(), use_pad = true;
       var pos_x = this.text['fX'], pos_y = this.text['fY'];
       if (this.text.TestBit(kTextNDC)) {
          pos_x = pos_x * w;
          pos_y = (1 - pos_y) * h;
       } else
       if (this.main_painter()!=null) {
+         w = this.frame_width(); h = this.frame_height(); use_pad = false;
          pos_x = this.main_painter().grx(pos_x);
          pos_y = this.main_painter().gry(pos_y);
       } else
@@ -6657,27 +6759,24 @@
          pos_x = ((Math.abs(pad['fX1']) + pos_x) / (pad['fX2'] - pad['fX1'])) * w;
          pos_y = (1 - ((Math.abs(pad['fY1']) + pos_y) / (pad['fY2'] - pad['fY1']))) * h;
       } else {
-         alert("Cannot draw text at x/y coordinates without real TPad object");
+         console.log("Cannot draw text at x/y coordinates without real TPad object");
          pos_x = w/2;
          pos_y = h/2;
       }
 
+      this.RecreateDrawG(use_pad, use_pad ? ".text_layer" : ".axis_layer");
+
       var tcolor = JSROOT.Painter.root_colors[this.text['fTextColor']];
-      var font = JSROOT.Painter.getFontDetails(this.text['fTextFont'], this.text['fTextSize'] * Math.min(w,h));
 
-      var string = this.text['fTitle'];
-      // translate the LaTeX symbols
-      if (this.text['_typename'] == 'TLatex')
-         string = JSROOT.Painter.translateLaTeX(string);
+      var latex_kind = 0, fact = 1.;
+      if (this.text['_typename'] == 'TLatex') { latex_kind = 1; fact = 0.9; } else
+      if (this.text['_typename'] == 'TMathText') { latex_kind = 2; fact = 0.8; }
+
+      this.StartTextDrawing(this.text['fTextFont'], this.text['fTextSize'] * Math.min(w,h) * fact);
+
+      this.DrawText(this.text.fTextAlign, pos_x, pos_y, 0, 0, this.text['fTitle'], tcolor, latex_kind);
 
-      this.draw_g.append("text")
-              .attr("class", "text")
-              .attr("x", pos_x.toFixed(1))
-              .attr("y", pos_y.toFixed(1))
-              .call(font.func)
-              .attr("text-anchor", align)
-              .attr("fill", tcolor)
-              .text(string);
+      this.FinishTextDrawing();
    }
 
    JSROOT.TTextPainter.prototype.UpdateObject = function(obj) {
@@ -8166,6 +8265,7 @@
    JSROOT.addDrawFunc("TPaveText", JSROOT.Painter.drawPaveText);
    JSROOT.addDrawFunc("TPaveStats", JSROOT.Painter.drawPaveText);
    JSROOT.addDrawFunc("TLatex", JSROOT.Painter.drawText);
+   JSROOT.addDrawFunc("TMathText", JSROOT.Painter.drawText);
    JSROOT.addDrawFunc("TText", JSROOT.Painter.drawText);
    JSROOT.addDrawFunc("TPaveLabel", JSROOT.Painter.drawText);
    JSROOT.addDrawFunc(/^TH1/, JSROOT.Painter.drawHistogram1D, ";P;P0;same");

From 46ef11661497b3af2b089d25f058c89e95903fdd Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 10:26:27 +0100
Subject: [PATCH 126/200] GetObjectInfo did not display the right value form
 "Sum" for histograms plotted with option SAME on top of an histogram
 displayed with a subrange. This was reported in ROOT-7124.

---
 hist/histpainter/src/THistPainter.cxx | 30 ++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx
index 41908e23a73be..c66446cf625ff 100644
--- a/hist/histpainter/src/THistPainter.cxx
+++ b/hist/histpainter/src/THistPainter.cxx
@@ -3551,12 +3551,12 @@ char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
    Double_t x  = gPad->PadtoX(gPad->AbsPixeltoX(px));
    Double_t y  = gPad->PadtoY(gPad->AbsPixeltoY(py));
    Double_t x1 = gPad->PadtoX(gPad->AbsPixeltoX(px+1));
-   const char *drawOption = fH->GetDrawOption();
+   TString drawOption = fH->GetDrawOption();
+   drawOption.ToLower();
    Double_t xmin, xmax, uxmin,uxmax;
    Double_t ymin, ymax, uymin,uymax;
    if (fH->GetDimension() == 2) {
-      if (gPad->GetView() || strncmp(drawOption,"cont",4) == 0
-                          || strncmp(drawOption,"CONT",4) == 0) {
+      if (gPad->GetView() || drawOption.Index("cont") >= 0) {
          uxmin=gPad->GetUxmin();
          uxmax=gPad->GetUxmax();
          xmin = fXaxis->GetBinLowEdge(fXaxis->GetFirst());
@@ -3572,7 +3572,17 @@ char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
    Int_t binx,biny,binmin,binx1;
    if (gPad->IsVertical()) {
       binx   = fXaxis->FindFixBin(x);
-      binmin = fXaxis->GetFirst();
+      if (drawOption.Index("same") >= 0) {
+         TH1 *h1;
+         TIter next(gPad->GetListOfPrimitives());
+         while ((h1 = (TH1 *)next())) {
+            if (!h1->InheritsFrom(TH1::Class())) continue;
+            binmin = h1->GetXaxis()->GetFirst();
+            break;
+         }
+      } else {
+         binmin = fXaxis->GetFirst();
+      }
       binx1  = fXaxis->FindFixBin(x1);
       // special case if more than 1 bin in x per pixel
       if (binx1-binx>1 && fH->GetDimension() == 1) {
@@ -3590,7 +3600,17 @@ char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
    } else {
       x1 = gPad->PadtoY(gPad->AbsPixeltoY(py+1));
       binx   = fXaxis->FindFixBin(y);
-      binmin = fXaxis->GetFirst();
+      if (drawOption.Index("same") >= 0) {
+         TH1 *h1;
+         TIter next(gPad->GetListOfPrimitives());
+         while ((h1 = (TH1 *)next())) {
+            if (!h1->InheritsFrom(TH1::Class())) continue;
+            binmin = h1->GetXaxis()->GetFirst();
+            break;
+         }
+      } else {
+         binmin = fXaxis->GetFirst();
+      }
       binx1  = fXaxis->FindFixBin(x1);
       // special case if more than 1 bin in x per pixel
       if (binx1-binx>1 && fH->GetDimension() == 1) {

From 89c0268eeb4a701d72613edc9ae8014281ce828c Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 10:28:31 +0100
Subject: [PATCH 127/200] THistPainter

---
 hist/doc/v604/index.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hist/doc/v604/index.md b/hist/doc/v604/index.md
index 0ee32b19105c1..34ae505c20bd4 100644
--- a/hist/doc/v604/index.md
+++ b/hist/doc/v604/index.md
@@ -46,6 +46,9 @@
     ![COLZ0 plot example](colzo.png "COLZ0 plot example")
 - The parameter `gStyle->SetHistTopMargin()` was ignored when plotting a 2D histogram
   using the option `E`. This can be seen plotting the histogram with `"LEGO E"`.
+- GetObjectInfo did not display the right value form "Sum" for histograms plotted
+  with option SAME on top of an histogram displayed with a subrange. This was
+  reported in ROOT-7124.
 
 ### TGraph2D
 

From dd548dfe066de647d96c0ef75ebb61181ec964cf Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 10:56:57 +0100
Subject: [PATCH 128/200] Fix uninitialised variable.

---
 hist/histpainter/src/THistPainter.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hist/histpainter/src/THistPainter.cxx b/hist/histpainter/src/THistPainter.cxx
index c66446cf625ff..d6d1034858e6e 100644
--- a/hist/histpainter/src/THistPainter.cxx
+++ b/hist/histpainter/src/THistPainter.cxx
@@ -3569,7 +3569,7 @@ char *THistPainter::GetObjectInfo(Int_t px, Int_t py) const
          y = ymin +(ymax-ymin)*(y-uymin)/(uymax-uymin);
       }
    }
-   Int_t binx,biny,binmin,binx1;
+   Int_t binx,biny,binmin=0,binx1;
    if (gPad->IsVertical()) {
       binx   = fXaxis->FindFixBin(x);
       if (drawOption.Index("same") >= 0) {

From 7814043fddffcf52709565292f23d53fdef2ee76 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 11:20:23 +0100
Subject: [PATCH 129/200] Move the PROJECT_NUMBER back up, remove trailing
 blancks (and please, Olivier, stop using the Doxywizard GUI)

---
 documentation/doxygen/Doxyfile | 124 ++++++++++++++++-----------------
 1 file changed, 62 insertions(+), 62 deletions(-)

diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile
index 6ebc66d539de2..8a3c0b3d3f652 100644
--- a/documentation/doxygen/Doxyfile
+++ b/documentation/doxygen/Doxyfile
@@ -17,6 +17,12 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 6.03/03
+
 # This tag specifies the encoding used for all characters in the config file
 # that follow. The default is UTF-8 which is also the encoding used for all text
 # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
@@ -34,12 +40,6 @@ DOXYFILE_ENCODING      = UTF-8
 
 PROJECT_NAME           = ROOT
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = 6.03/03
-
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
 # quick idea about the purpose of the project. Keep the description short.
@@ -154,7 +154,7 @@ FULL_PATH_NAMES        = YES
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH        = 
+STRIP_FROM_PATH        =
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
@@ -163,7 +163,7 @@ STRIP_FROM_PATH        =
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH    = 
+STRIP_FROM_INC_PATH    =
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -230,13 +230,13 @@ TAB_SIZE               = 4
 # "Side Effects:". You can put \n's in the value part of an alias to insert
 # newlines.
 
-ALIASES                = 
+ALIASES                =
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
 # will allow you to use the command class in the itcl::class meaning.
 
-TCL_SUBST              = 
+TCL_SUBST              =
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
 # only. Doxygen will then generate output that is more tailored for C. For
@@ -280,7 +280,7 @@ OPTIMIZE_OUTPUT_VHDL   = NO
 # Note that for custom extensions you also need to set FILE_PATTERNS otherwise
 # the files are not read by doxygen.
 
-EXTENSION_MAPPING      = 
+EXTENSION_MAPPING      =
 
 # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
 # according to the Markdown format, which allows for more readable
@@ -616,7 +616,7 @@ GENERATE_DEPRECATEDLIST= YES
 # sections, marked by \if <section_label> ... \endif and \cond <section_label>
 # ... \endcond blocks.
 
-ENABLED_SECTIONS       = 
+ENABLED_SECTIONS       =
 
 # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
 # initial value of a variable or macro / define can have for it to appear in the
@@ -658,7 +658,7 @@ SHOW_NAMESPACES        = NO
 # by doxygen. Whatever the program writes to standard output is used as the file
 # version. For an example see the documentation.
 
-FILE_VERSION_FILTER    = 
+FILE_VERSION_FILTER    =
 
 # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
 # by doxygen. The layout file controls the global structure of the generated
@@ -682,7 +682,7 @@ LAYOUT_FILE            = DoxygenLayout.xml
 # search path. Do not use file names with spaces, bibtex cannot handle them. See
 # also \cite for info how to create references.
 
-CITE_BIB_FILES         = 
+CITE_BIB_FILES         =
 
 #---------------------------------------------------------------------------
 # Configuration options related to warning and progress messages
@@ -741,7 +741,7 @@ WARN_FORMAT            = "$file:$line: $text"
 # messages should be written. If left blank the output is written to standard
 # error (stderr).
 
-WARN_LOGFILE           = 
+WARN_LOGFILE           =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the input files
@@ -754,7 +754,7 @@ WARN_LOGFILE           =
 # Note: If this tag is empty the current directory is searched.
 
 INPUT                  = ../../graf2d/graf \
-                         ../../hist/hitspainter
+                         ../../hist/histpainter
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -830,7 +830,7 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                = 
+EXCLUDE                =
 
 # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
 # directories that are symbolic links (a Unix file system feature) are excluded
@@ -846,7 +846,7 @@ EXCLUDE_SYMLINKS       = NO
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories for example use the pattern */test/*
 
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       =
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -857,7 +857,7 @@ EXCLUDE_PATTERNS       =
 # Note that the wildcards are matched against the file with absolute path, so to
 # exclude all test directories use the pattern */test/*
 
-EXCLUDE_SYMBOLS        = 
+EXCLUDE_SYMBOLS        =
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or directories
 # that contain example code fragments that are included (see the \include
@@ -883,7 +883,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = /tmp/doxygen/rootdoc/images
+IMAGE_PATH             =
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -909,7 +909,7 @@ INPUT_FILTER           = ./filter
 # filters are used. If the FILTER_PATTERNS tag is empty or if none of the
 # patterns match the file name, INPUT_FILTER is applied.
 
-FILTER_PATTERNS        = 
+FILTER_PATTERNS        =
 
 # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
 # INPUT_FILTER ) will also be used to filter the input files that are used for
@@ -924,14 +924,14 @@ FILTER_SOURCE_FILES    = YES
 # *.ext= (so without naming a filter).
 # This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
 
-FILTER_SOURCE_PATTERNS = 
+FILTER_SOURCE_PATTERNS =
 
 # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
 # is part of the input, its contents will be placed on the main page
 # (index.html). This can be useful if you have a project on for instance GitHub
 # and want to reuse the introduction page also for the doxygen output.
 
-USE_MDFILE_AS_MAINPAGE = 
+USE_MDFILE_AS_MAINPAGE =
 
 #---------------------------------------------------------------------------
 # Configuration options related to source browsing
@@ -1036,7 +1036,7 @@ CLANG_ASSISTED_PARSING = NO
 # specified with INPUT and INCLUDE_PATH.
 # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
 
-CLANG_OPTIONS          = 
+CLANG_OPTIONS          =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the alphabetical class index
@@ -1062,7 +1062,7 @@ COLS_IN_ALPHA_INDEX    = 5
 # while generating the index headers.
 # This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
 
-IGNORE_PREFIX          = 
+IGNORE_PREFIX          =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the HTML output
@@ -1106,7 +1106,7 @@ HTML_FILE_EXTENSION    = .html
 # of the possible markers and block names see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_HEADER            = 
+HTML_HEADER            =
 
 # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
 # generated HTML page. If the tag is left blank doxygen will generate a standard
@@ -1128,7 +1128,7 @@ HTML_FOOTER            = htmlfooter.html
 # obsolete.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_STYLESHEET        = 
+HTML_STYLESHEET        =
 
 # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
 # defined cascading style sheet that is included after the standard style sheets
@@ -1139,7 +1139,7 @@ HTML_STYLESHEET        =
 # see the documentation.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-HTML_EXTRA_STYLESHEET  = 
+HTML_EXTRA_STYLESHEET  =
 
 # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the HTML output directory. Note
@@ -1277,7 +1277,7 @@ GENERATE_HTMLHELP      = NO
 # written to the html output directory.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_FILE               = 
+CHM_FILE               =
 
 # The HHC_LOCATION tag can be used to specify the location (absolute path
 # including file name) of the HTML help compiler ( hhc.exe). If non-empty
@@ -1285,7 +1285,7 @@ CHM_FILE               =
 # The file has to be specified with full path.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-HHC_LOCATION           = 
+HHC_LOCATION           =
 
 # The GENERATE_CHI flag controls if a separate .chi index file is generated (
 # YES) or that it should be included in the master .chm file ( NO).
@@ -1298,7 +1298,7 @@ GENERATE_CHI           = NO
 # and project file content.
 # This tag requires that the tag GENERATE_HTMLHELP is set to YES.
 
-CHM_INDEX_ENCODING     = 
+CHM_INDEX_ENCODING     =
 
 # The BINARY_TOC flag controls whether a binary table of contents is generated (
 # YES) or a normal table of contents ( NO) in the .chm file.
@@ -1328,7 +1328,7 @@ GENERATE_QHP           = NO
 # the HTML output folder.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QCH_FILE               = 
+QCH_FILE               =
 
 # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
 # Project output. For more information please see Qt Help Project / Namespace
@@ -1353,7 +1353,7 @@ QHP_VIRTUAL_FOLDER     = doc
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_NAME   = 
+QHP_CUST_FILTER_NAME   =
 
 # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
 # custom filter to add. For more information please see Qt Help Project / Custom
@@ -1361,21 +1361,21 @@ QHP_CUST_FILTER_NAME   =
 # filters).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_CUST_FILTER_ATTRS  = 
+QHP_CUST_FILTER_ATTRS  =
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
 # project's filter section matches. Qt Help Project / Filter Attributes (see:
 # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHP_SECT_FILTER_ATTRS  = 
+QHP_SECT_FILTER_ATTRS  =
 
 # The QHG_LOCATION tag can be used to specify the location of Qt's
 # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
 # generated .qhp file.
 # This tag requires that the tag GENERATE_QHP is set to YES.
 
-QHG_LOCATION           = 
+QHG_LOCATION           =
 
 # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
 # generated, together with the HTML files, they form an Eclipse help plugin. To
@@ -1508,7 +1508,7 @@ MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
 # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_EXTENSIONS     = 
+MATHJAX_EXTENSIONS     =
 
 # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
 # of code that will be used on startup of the MathJax code. See the MathJax site
@@ -1516,7 +1516,7 @@ MATHJAX_EXTENSIONS     =
 # example see the documentation.
 # This tag requires that the tag USE_MATHJAX is set to YES.
 
-MATHJAX_CODEFILE       = 
+MATHJAX_CODEFILE       =
 
 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for
 # the HTML output. The underlying search engine uses javascript and DHTML and
@@ -1576,7 +1576,7 @@ EXTERNAL_SEARCH        = NO
 # Searching" for details.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-SEARCHENGINE_URL       = 
+SEARCHENGINE_URL       =
 
 # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
 # search data is written to a file for indexing by an external tool. With the
@@ -1592,7 +1592,7 @@ SEARCHDATA_FILE        = searchdata.xml
 # projects and redirect the results back to the right project.
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTERNAL_SEARCH_ID     = 
+EXTERNAL_SEARCH_ID     =
 
 # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
 # projects other than the one defined by this configuration file, but that are
@@ -1602,7 +1602,7 @@ EXTERNAL_SEARCH_ID     =
 # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
 # This tag requires that the tag SEARCHENGINE is set to YES.
 
-EXTRA_SEARCH_MAPPINGS  = 
+EXTRA_SEARCH_MAPPINGS  =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the LaTeX output
@@ -1663,7 +1663,7 @@ PAPER_TYPE             = a4
 # If left blank no extra packages will be included.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-EXTRA_PACKAGES         = 
+EXTRA_PACKAGES         =
 
 # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
 # generated LaTeX document. The header should contain everything until the first
@@ -1679,7 +1679,7 @@ EXTRA_PACKAGES         =
 # PROJECT_NAME), or the project number (see PROJECT_NUMBER).
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_HEADER           = 
+LATEX_HEADER           =
 
 # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
 # generated LaTeX document. The footer should contain everything after the last
@@ -1688,7 +1688,7 @@ LATEX_HEADER           =
 # Note: Only use a user-defined footer if you know what you are doing!
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_FOOTER           = 
+LATEX_FOOTER           =
 
 # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
 # other source files which should be copied to the LATEX_OUTPUT output
@@ -1696,7 +1696,7 @@ LATEX_FOOTER           =
 # markers available.
 # This tag requires that the tag GENERATE_LATEX is set to YES.
 
-LATEX_EXTRA_FILES      = 
+LATEX_EXTRA_FILES      =
 
 # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
 # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
@@ -1796,14 +1796,14 @@ RTF_HYPERLINKS         = NO
 # default style sheet that doxygen normally uses.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_STYLESHEET_FILE    = 
+RTF_STYLESHEET_FILE    =
 
 # Set optional variables used in the generation of an RTF document. Syntax is
 # similar to doxygen's config file. A template extensions file can be generated
 # using doxygen -e rtf extensionFile.
 # This tag requires that the tag GENERATE_RTF is set to YES.
 
-RTF_EXTENSIONS_FILE    = 
+RTF_EXTENSIONS_FILE    =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the man page output
@@ -1864,13 +1864,13 @@ XML_OUTPUT             = xml
 # validating XML parser to check the syntax of the XML files.
 # This tag requires that the tag GENERATE_XML is set to YES.
 
-XML_SCHEMA             = 
+XML_SCHEMA             =
 
 # The XML_DTD tag can be used to specify a XML DTD, which can be used by a
 # validating XML parser to check the syntax of the XML files.
 # This tag requires that the tag GENERATE_XML is set to YES.
 
-XML_DTD                = 
+XML_DTD                =
 
 # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
 # listings (including syntax highlighting and cross-referencing information) to
@@ -1947,7 +1947,7 @@ PERLMOD_PRETTY         = YES
 # overwrite each other's variables.
 # This tag requires that the tag GENERATE_PERLMOD is set to YES.
 
-PERLMOD_MAKEVAR_PREFIX = 
+PERLMOD_MAKEVAR_PREFIX =
 
 #---------------------------------------------------------------------------
 # Configuration options related to the preprocessor
@@ -1988,7 +1988,7 @@ SEARCH_INCLUDES        = YES
 # preprocessor.
 # This tag requires that the tag SEARCH_INCLUDES is set to YES.
 
-INCLUDE_PATH           = 
+INCLUDE_PATH           =
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -1996,7 +1996,7 @@ INCLUDE_PATH           =
 # used.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-INCLUDE_FILE_PATTERNS  = 
+INCLUDE_FILE_PATTERNS  =
 
 # The PREDEFINED tag can be used to specify one or more macro names that are
 # defined before the preprocessor is started (similar to the -D option of e.g.
@@ -2006,7 +2006,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             = 
+PREDEFINED             =
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
@@ -2015,7 +2015,7 @@ PREDEFINED             =
 # definition found in the source code.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_AS_DEFINED      = 
+EXPAND_AS_DEFINED      =
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
 # remove all refrences to function-like macros that are alone on a line, have an
@@ -2044,13 +2044,13 @@ SKIP_FUNCTION_MACROS   = YES
 # the path). If a tag file is not located in the directory in which doxygen is
 # run, you must also specify the path to the tagfile here.
 
-TAGFILES               = 
+TAGFILES               =
 
 # When a file name is specified after GENERATE_TAGFILE, doxygen will create a
 # tag file that is based on the input files it reads. See section "Linking to
 # external documentation" for more information about the usage of tag files.
 
-GENERATE_TAGFILE       = 
+GENERATE_TAGFILE       =
 
 # If the ALLEXTERNALS tag is set to YES all external class will be listed in the
 # class index. If set to NO only the inherited external classes will be listed.
@@ -2098,14 +2098,14 @@ CLASS_DIAGRAMS         = NO
 # the mscgen tool resides. If left empty the tool is assumed to be found in the
 # default search path.
 
-MSCGEN_PATH            = 
+MSCGEN_PATH            =
 
 # You can include diagrams made with dia in doxygen documentation. Doxygen will
 # then run dia to produce the diagram and insert it in the documentation. The
 # DIA_PATH tag allows you to specify the directory where the dia binary resides.
 # If left empty dia is assumed to be found in the default search path.
 
-DIA_PATH               = 
+DIA_PATH               =
 
 # If set to YES, the inheritance and collaboration graphs will hide inheritance
 # and usage relations if the target is undocumented or is not a class.
@@ -2154,7 +2154,7 @@ DOT_FONTSIZE           = 10
 # the path where dot can find it using this tag.
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOT_FONTPATH           = 
+DOT_FONTPATH           =
 
 # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
 # each documented class showing the direct and indirect inheritance relations.
@@ -2299,19 +2299,19 @@ DOT_PATH               = /usr/local/bin/dot
 # command).
 # This tag requires that the tag HAVE_DOT is set to YES.
 
-DOTFILE_DIRS           = 
+DOTFILE_DIRS           =
 
 # The MSCFILE_DIRS tag can be used to specify one or more directories that
 # contain msc files that are included in the documentation (see the \mscfile
 # command).
 
-MSCFILE_DIRS           = 
+MSCFILE_DIRS           =
 
 # The DIAFILE_DIRS tag can be used to specify one or more directories that
 # contain dia files that are included in the documentation (see the \diafile
 # command).
 
-DIAFILE_DIRS           = 
+DIAFILE_DIRS           =
 
 # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
 # that will be shown in the graph. If the number of nodes in a graph becomes

From 1d29bd5e892608bd267d5c1831a5f54c622bb5e5 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 11:25:43 +0100
Subject: [PATCH 130/200] More progresses...

---
 documentation/doxygen/Makefile    |  4 ---
 documentation/doxygen/filter.cxx  | 59 +++++++++++++++++++++++++++++--
 documentation/doxygen/makeimage.C | 13 +++++++
 3 files changed, 69 insertions(+), 7 deletions(-)
 create mode 100644 documentation/doxygen/makeimage.C

diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index f9a6172766ed5..c765c3304b914 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -2,8 +2,6 @@
 .PHONY: filter doxygen clean
 
 docdir="$(shell ./makedocdir.sh)"
-imgdir="$(shell ./makeimgdir.sh)"
-macdir="$(shell ./makemacrodir.sh)"
 
 all: filter doxygen
 
@@ -14,7 +12,5 @@ doxygen:
 	doxygen
 
 clean:
-	rm -r $(macdir)
-	rm -r $(imgdir)
 	rm -r $(docdir)
 	rm filter
diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index 7192f551d0780..d6b57729a1ba3 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -58,6 +58,8 @@
 
 // Auxiliary functions
 void GetClassName();
+void StandardizeKeywords();
+void ExecuteMacro();
 
 // Global variables.
 char    gLine[255];
@@ -67,6 +69,9 @@ TString gClassName;
 Bool_t  gHeader;
 Bool_t  gSource;
 Bool_t  gInClassDef;
+Bool_t  gClass;
+Int_t   gInMacro;
+Int_t   gImageID;
 
 
 //______________________________________________________________________________
@@ -75,10 +80,14 @@ int main(int argc, char *argv[])
    // Filter ROOT files for Doxygen.
 
    // Initialisation
+
    gFileName   = argv[1];
    gHeader     = kFALSE;
    gSource     = kFALSE;
    gInClassDef = kFALSE;
+   gClass      = kFALSE;
+   gInMacro    = 0;
+   gImageID    = 0;
    if (gFileName.EndsWith(".cxx")) gSource = kTRUE;
    if (gFileName.EndsWith(".h"))   gHeader = kTRUE;
    GetClassName();
@@ -106,15 +115,36 @@ int main(int argc, char *argv[])
    if (gSource) {
       while (fgets(gLine,255,f)) {
          gLineString = gLine;
+         StandardizeKeywords();
+
+         if (gLineString.Index("begin_html") >= 0) {
+            if (!gClass) {
+               gLineString = TString::Format("/*! \\class %s\n",gClassName.Data());
+               gClass = kTRUE;
+            } else {
+               gLineString.ReplaceAll("begin_html","");
+            }
+         }
+
+         if (gLineString.Index("end_html") >= 0) {
+            gLineString.ReplaceAll("end_html","");
+         }
 
-         if (gLineString.Index("Begin_Html") >= 0) {
-            gLineString = TString::Format("/*! \\class %s\n",gClassName.Data());
+         if (gInMacro) {
+            if (gInMacro == 1) {
+               if (gLineString.EndsWith(".C\n")) ExecuteMacro();
+            }
+            gInMacro++;
          }
 
          if (gLineString.Index("Begin_Macro") >= 0) {
+            gLineString = "<pre lang=\"cpp\">\n";
+            gInMacro++;
          }
 
          if (gLineString.Index("End_Macro") >= 0) {
+            gLineString = "</pre>\n";
+            gInMacro = 0;
          }
 
          printf("%s",gLineString.Data());
@@ -124,7 +154,7 @@ int main(int argc, char *argv[])
    TString opt1,opt0;
    opt0 = argv[0];
    opt1 = argv[1];
-   printf("DEBUG %d : %s - %s %d %d - %s\n",argc,opt0.Data(),opt1.Data(),gSource,gHeader,gClassName.Data());
+   //printf("DEBUG %d : %s - %s %d %d - %s\n",argc,opt0.Data(),opt1.Data(),gSource,gHeader,gClassName.Data());
    fclose(f);
 
    return 1;
@@ -172,3 +202,26 @@ void GetClassName()
    fclose(f);
    return;
 }
+
+
+//______________________________________________________________________________
+void StandardizeKeywords()
+{
+   gLineString.ReplaceAll("End_Html","end_html");
+   gLineString.ReplaceAll("End_html","end_html");
+   gLineString.ReplaceAll("end_html ","end_html");
+   gLineString.ReplaceAll("Begin_Html","begin_html");
+   gLineString.ReplaceAll("Begin_html","begin_html");
+   gLineString.ReplaceAll("<big>","");
+   gLineString.ReplaceAll("</big>","");
+}
+
+
+//______________________________________________________________________________
+void ExecuteMacro()
+{
+   gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
+   Int_t l = gLineString.Length();
+   gLineString.Replace(l-2,2,TString::Format(".C\\\",\\\"%s\\\",%d)\"",gClassName.Data(),gImageID++));
+   gSystem->Exec(gLineString.Data());
+}
\ No newline at end of file
diff --git a/documentation/doxygen/makeimage.C b/documentation/doxygen/makeimage.C
new file mode 100644
index 0000000000000..e3d62822fe0ed
--- /dev/null
+++ b/documentation/doxygen/makeimage.C
@@ -0,0 +1,13 @@
+// Generates the png output of the macro "macroname" located in "dirname"
+
+void makeimage(const char *macroname, const char *classname, int id)
+{
+   gROOT->ProcessLine(Form(".x %s",macroname));
+
+   TIter iCanvas(gROOT->GetListOfCanvases());
+   TVirtualPad* pad = 0;
+
+   while ((pad = (TVirtualPad*) iCanvas())) {
+      pad->SaveAs(TString::Format("%s_%3.3d.png", classname,id));
+   }
+}

From bc33f20f906e0ec4fcbbc33b0f968cc70c596c38 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 11:31:06 +0100
Subject: [PATCH 131/200] Generate the images for macros in external files.

---
 documentation/doxygen/filter.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index d6b57729a1ba3..d3b5f05e9346c 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -222,6 +222,6 @@ void ExecuteMacro()
 {
    gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
    Int_t l = gLineString.Length();
-   gLineString.Replace(l-2,2,TString::Format(".C\\\",\\\"%s\\\",%d)\"",gClassName.Data(),gImageID++));
+   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s\\\",%d)\"",gClassName.Data(),gImageID++));
    gSystem->Exec(gLineString.Data());
 }
\ No newline at end of file

From fbd55074cfac1bc0ead8deb1dd1ae2cc07ec0a32 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 14:13:00 +0100
Subject: [PATCH 132/200] Make sur the output of the executed macros will not
 polute the final documentation.

---
 documentation/doxygen/Makefile   | 3 +++
 documentation/doxygen/filter.cxx | 6 ++++++
 2 files changed, 9 insertions(+)

diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index c765c3304b914..1d2da5870b4a5 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -14,3 +14,6 @@ doxygen:
 clean:
 	rm -r $(docdir)
 	rm filter
+	rm c1*
+	rm *.png
+	rm stdout.dat
diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index d3b5f05e9346c..3ca9ffd83f223 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -223,5 +223,11 @@ void ExecuteMacro()
    gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
    Int_t l = gLineString.Length();
    gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s\\\",%d)\"",gClassName.Data(),gImageID++));
+
+   // Execute the ROOT command making sure stdout will not go in the doxygen file.
+   int o = dup(fileno(stdout));
+   freopen("stdout.dat","a",stdout);
    gSystem->Exec(gLineString.Data());
+   dup2(o,fileno(stdout));
+   close(o);
 }
\ No newline at end of file

From 66ffbb7005e54b34dff6c62bbf3a1946a872c8aa Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 14:38:07 +0100
Subject: [PATCH 133/200] Build the image name in filter.cxx (instead in make
 image.C) because it will be needed later in filter.cxx.

---
 documentation/doxygen/filter.cxx  | 15 +++++++--------
 documentation/doxygen/makeimage.C |  8 ++++----
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index 3ca9ffd83f223..e2ff51a2b14d1 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -66,6 +66,7 @@ char    gLine[255];
 TString gFileName;
 TString gLineString;
 TString gClassName;
+TString gImageName;
 Bool_t  gHeader;
 Bool_t  gSource;
 Bool_t  gInClassDef;
@@ -143,7 +144,7 @@ int main(int argc, char *argv[])
          }
 
          if (gLineString.Index("End_Macro") >= 0) {
-            gLineString = "</pre>\n";
+            gLineString.ReplaceAll("End_Macro","</pre>\n");
             gInMacro = 0;
          }
 
@@ -151,12 +152,6 @@ int main(int argc, char *argv[])
       }
    }
 
-   TString opt1,opt0;
-   opt0 = argv[0];
-   opt1 = argv[1];
-   //printf("DEBUG %d : %s - %s %d %d - %s\n",argc,opt0.Data(),opt1.Data(),gSource,gHeader,gClassName.Data());
-   fclose(f);
-
    return 1;
 }
 
@@ -220,9 +215,13 @@ void StandardizeKeywords()
 //______________________________________________________________________________
 void ExecuteMacro()
 {
+   // Name of the next Image to be generated
+   gImageName = TString::Format("%s_%3.3d.png",gClassName.Data(),gImageID++);
+
+   // Build the ROOT command to be executed.
    gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
    Int_t l = gLineString.Length();
-   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s\\\",%d)\"",gClassName.Data(),gImageID++));
+   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s\\\")\"",gImageName.Data()));
 
    // Execute the ROOT command making sure stdout will not go in the doxygen file.
    int o = dup(fileno(stdout));
diff --git a/documentation/doxygen/makeimage.C b/documentation/doxygen/makeimage.C
index e3d62822fe0ed..44d389e0c775c 100644
--- a/documentation/doxygen/makeimage.C
+++ b/documentation/doxygen/makeimage.C
@@ -1,13 +1,13 @@
-// Generates the png output of the macro "macroname" located in "dirname"
+// Generates the ImageName output of the macro MacroName
 
-void makeimage(const char *macroname, const char *classname, int id)
+void makeimage(const char *MacroName, const char *ImageName)
 {
-   gROOT->ProcessLine(Form(".x %s",macroname));
+   gROOT->ProcessLine(Form(".x %s",MacroName));
 
    TIter iCanvas(gROOT->GetListOfCanvases());
    TVirtualPad* pad = 0;
 
    while ((pad = (TVirtualPad*) iCanvas())) {
-      pad->SaveAs(TString::Format("%s_%3.3d.png", classname,id));
+      pad->SaveAs(ImageName);
    }
 }

From 324f81b5eb0b3d1a1d2d03b2276cf6a4620ab32e Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Wed, 4 Mar 2015 17:39:54 +0100
Subject: [PATCH 134/200] Images from external macros are properly generated
 and included in the Doxygen pages

---
 documentation/doxygen/Makefile      |  4 ++--
 documentation/doxygen/filter.cxx    | 33 +++++++++++++++++++++++------
 documentation/doxygen/makedocdir.sh |  1 +
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index 1d2da5870b4a5..2f1df66910941 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -1,7 +1,8 @@
 
 .PHONY: filter doxygen clean
 
-docdir="$(shell ./makedocdir.sh)"
+docdir="$(shell . ./makedocdir.sh)"
+export OUTPUT_DIRECTORY=$(docdir)
 
 all: filter doxygen
 
@@ -15,5 +16,4 @@ clean:
 	rm -r $(docdir)
 	rm filter
 	rm c1*
-	rm *.png
 	rm stdout.dat
diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index e2ff51a2b14d1..7ef69b79cad21 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -56,10 +56,13 @@
 #include <TMath.h>
 #include <TSystem.h>
 
+
 // Auxiliary functions
-void GetClassName();
-void StandardizeKeywords();
-void ExecuteMacro();
+void    GetClassName();
+void    StandardizeKeywords();
+void    ExecuteMacro();
+void    ExecuteCommand(TString);
+
 
 // Global variables.
 char    gLine[255];
@@ -202,6 +205,8 @@ void GetClassName()
 //______________________________________________________________________________
 void StandardizeKeywords()
 {
+   // Standardize the THTML keywords to ease the parsing.
+
    gLineString.ReplaceAll("End_Html","end_html");
    gLineString.ReplaceAll("End_html","end_html");
    gLineString.ReplaceAll("end_html ","end_html");
@@ -215,18 +220,32 @@ void StandardizeKeywords()
 //______________________________________________________________________________
 void ExecuteMacro()
 {
+   // Execute the macro in gLineString and produce the corresponding picture
+
    // Name of the next Image to be generated
-   gImageName = TString::Format("%s_%3.3d.png",gClassName.Data(),gImageID++);
+   gImageName = TString::Format("%s_%3.3d.png", gClassName.Data()
+                                              , gImageID++);
 
    // Build the ROOT command to be executed.
    gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
    Int_t l = gLineString.Length();
-   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s\\\")\"",gImageName.Data()));
+   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s/html/%s\\\")\"", gSystem->Getenv("OUTPUT_DIRECTORY")
+                                                                          , gImageName.Data()));
+
+   ExecuteCommand(gLineString);
+
+   gLineString = TString::Format("\\image html %s\n",gImageName.Data());
+}
+
+
+//______________________________________________________________________________
+void ExecuteCommand(TString command)
+{
+   // Execute a command making sure stdout will not go in the doxygen file.
 
-   // Execute the ROOT command making sure stdout will not go in the doxygen file.
    int o = dup(fileno(stdout));
    freopen("stdout.dat","a",stdout);
-   gSystem->Exec(gLineString.Data());
+   gSystem->Exec(command.Data());
    dup2(o,fileno(stdout));
    close(o);
 }
\ No newline at end of file
diff --git a/documentation/doxygen/makedocdir.sh b/documentation/doxygen/makedocdir.sh
index 818ca2d154268..c3c6ea6c3caad 100755
--- a/documentation/doxygen/makedocdir.sh
+++ b/documentation/doxygen/makedocdir.sh
@@ -1,4 +1,5 @@
 # Make the ouput directory for the doxygen output
+
 outdir=`grep "^OUTPUT_DIRECTORY" Doxyfile | sed -e "s/^.*= //"`
 
 if [ ! -d "$outdir" ]

From 1b537006e96f8c8c729ffca4767d5d076318fc93 Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Wed, 4 Mar 2015 18:03:07 +0100
Subject: [PATCH 135/200] Fix handling of operator ^ in case of complicated
 expressions (with several bracket levels). This fixes ROOT-7122

---
 hist/hist/src/TFormula.cxx | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hist/hist/src/TFormula.cxx b/hist/hist/src/TFormula.cxx
index beae569159782..f4407e4c91fab 100644
--- a/hist/hist/src/TFormula.cxx
+++ b/hist/hist/src/TFormula.cxx
@@ -835,6 +835,7 @@ void TFormula::HandleExponentiation(TString &formula)
       TString right,left;
       Int_t temp = caretPos;
       temp--;
+      // get the expression in ( ) which has the operator^ applied
       if(formula[temp] == ')')
       {
          Int_t depth = 1;
@@ -847,14 +848,18 @@ void TFormula::HandleExponentiation(TString &formula)
                depth--;
             temp--;
          }
-         temp++;
+         if (depth == 0) temp++;
       }
-      while(temp >= 0 && !IsOperator(formula[temp]))
+      // this in case of someting like sin(x+2)^2
+      temp--;  // go down one
+      assert(temp+1 >= 0); 
+      while(temp >= 0 && !IsOperator(formula[temp]) && !IsBracket(formula[temp]) )
       {
          temp--;
       }
       left = formula(temp + 1, caretPos - (temp + 1));
 
+      // look now at the expression after the ^ operator 
       temp = caretPos;
       temp++;
       if(formula[temp] == '(')
@@ -879,6 +884,9 @@ void TFormula::HandleExponentiation(TString &formula)
 
       TString pattern = TString::Format("%s^%s",left.Data(),right.Data());
       TString replacement = TString::Format("pow(%s,%s)",left.Data(),right.Data());
+
+      // std::cout << "pattern : " << pattern << std::endl;
+      // std::cout << "replacement : " << replacement << std::endl;
       formula.ReplaceAll(pattern,replacement);
 
       caretPos = formula.Last('^');

From 80d02bc17ed77c124916738f8944eed48b28c0a5 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Wed, 4 Mar 2015 19:30:42 +0100
Subject: [PATCH 136/200] More fixes for ROOT-7120 - cmake warnings 3.1

---
 math/vc/tests/CMakeLists.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/math/vc/tests/CMakeLists.txt b/math/vc/tests/CMakeLists.txt
index 7800c90844906..c93fb60bfba14 100644
--- a/math/vc/tests/CMakeLists.txt
+++ b/math/vc/tests/CMakeLists.txt
@@ -2,6 +2,9 @@ include(AddFileDependencies)
 if(CMAKE_VERSION VERSION_GREATER 3.0.0)
   cmake_policy(SET CMP0042 OLD)
 endif()
+if(POLICY CMP0054)
+  cmake_policy(SET CMP0054 NEW)
+endif()
 
 add_custom_target(build_tests ALL VERBATIM)
 

From c90bd27f68ba45e5244ac61be3d56016e3778a2d Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 11:41:34 -0600
Subject: [PATCH 137/200] Disable llvm's threads support.

This is not yet necessary since we take a lock whenever accessing llvm/clang and is 'confusing' helgrind
in regard to the order in which lock are being taken (during TROOT initialization, the llvm lock is taken
before there is any chance to take the ROOT locks ... later on the order is always reverse)
---
 interpreter/CMakeLists.txt | 4 ++++
 interpreter/llvm/Module.mk | 1 +
 2 files changed, 5 insertions(+)

diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt
index d11a14c767884..9229d24b99597 100644
--- a/interpreter/CMakeLists.txt
+++ b/interpreter/CMakeLists.txt
@@ -5,6 +5,10 @@ set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
 set(LLVM_INCLUDE_EXAMPLES OFF)
 set(LLVM_BUILD_TOOLS OFF)
 set(LLVM_FORCE_USE_OLD_TOOLCHAIN ON)
+# We only use llvm/clang through TCling which is (with the help of core/meta) already taking a lock
+# to serialize access to llvm.  We can later review how to make this finer grained by using llvm's own locking
+# mechanism.
+set(LLVM_ENABLE_THREADS OFF)
 
 if(ROOT_ARCHITECTURE MATCHES linuxarm64)
   set(ROOT_CLING_TARGET "AArch64")
diff --git a/interpreter/llvm/Module.mk b/interpreter/llvm/Module.mk
index a39e1e49185c4..7c917a3c1e0e6 100644
--- a/interpreter/llvm/Module.mk
+++ b/interpreter/llvm/Module.mk
@@ -180,6 +180,7 @@ $(LLVMDEPO): $(LLVMDEPS)
 		--disable-clang-rewriter --disable-clang-static-analyzer \
 		--disable-clang-arcmt \
 		--disable-compiler-version-checks \
+                --disable-threads \
 		$$LLVMLIBCXX \
 		$(LLVMOPTFLAGS) \
 		--enable-targets=host \

From 1649fae535805b52f8e7473059ddea7b51d4fc38 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Sun, 22 Feb 2015 21:25:35 +0100
Subject: [PATCH 138/200] Made TIsAProxy thread safe

The TIsAProxy does late initialization and caching, both of which
need to be done in a thread-safe manner.
---
 core/meta/inc/TIsAProxy.h   |  26 +++---
 core/meta/src/TIsAProxy.cxx | 172 ++++++++++++++++++++----------------
 2 files changed, 109 insertions(+), 89 deletions(-)

diff --git a/core/meta/inc/TIsAProxy.h b/core/meta/inc/TIsAProxy.h
index d89ff67a84f08..a4a1e6105de48 100644
--- a/core/meta/inc/TIsAProxy.h
+++ b/core/meta/inc/TIsAProxy.h
@@ -18,7 +18,7 @@
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
 #endif
-
+#include <atomic>
 
 class TClass;
 
@@ -28,20 +28,22 @@ class TClass;
 //                                                                      //
 //////////////////////////////////////////////////////////////////////////
 class TIsAProxy  : public TVirtualIsAProxy {
-
 private:
-   const type_info   *fType;         //Actual typeid of the proxy
-   const type_info   *fLastType;     //Last used subtype
-   TClass            *fClass;        //Actual TClass
-   TClass            *fLastClass;    //Last used TClass
-   Char_t             fSubTypes[72]; //map of known sub-types
-   Bool_t             fVirtual;      //Flag if class is virtual
-   void              *fContext;      //Optional user contex
-   Bool_t             fInit;         //Initialization flag
+   const type_info          *fType;        //Actual typeid of the proxy
+   std::atomic<TClass*>     fClass;        //Actual TClass
+   std::atomic<void*>       fLast;         //points into fSubTypes map for last used values
+   Char_t                   fSubTypes[72]; //map of known sub-types
+   void                     *fContext;     //Optional user contex
+   mutable std::atomic<unsigned int> fSubTypesReaders; //number of readers of fSubTypes
+   std::atomic<bool>      fSubTypesWriteLockTaken; //True if there is a writer
+   Bool_t                   fVirtual;      //Flag if class is virtual
+   std::atomic<bool>      fInit;         //Initialization flag
 
+   void* FindSubType(const type_info*) const;
+   void* CacheSubType(const type_info*, TClass*);
 protected:
-   TIsAProxy(const TIsAProxy&);
-   TIsAProxy& operator=(const TIsAProxy&);
+   TIsAProxy(const TIsAProxy&) = delete;
+   TIsAProxy& operator=(const TIsAProxy&) = delete;
 
 public:
    // Standard initializing constructor
diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index b67b2ae7f00e8..dc6788cf5168c 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -15,7 +15,7 @@
 #include "TIsAProxy.h"
 
 #include <map>
-
+#include <type_traits>
 
 //////////////////////////////////////////////////////////////////////////
 //                                                                      //
@@ -32,60 +32,29 @@ namespace {
       //    typeid( * (DynamicType*) void_ptr );
       virtual ~DynamicType() {}
    };
-}
 
-typedef std::map<Long_t, TClass*> ClassMap_t; // Internal type map
-inline ClassMap_t *GetMap(void* p)
-{
-   return (ClassMap_t*)p;
+   typedef std::map<const void*, TClass*> ClassMap_t; // Internal type map
+   inline ClassMap_t *GetMap(const void* p)
+   {
+      return (ClassMap_t*)p;
+   }
+
+   inline ClassMap_t::value_type* ToPair(void*p) 
+   {
+     return (ClassMap_t::value_type*)p;
+   }
 }
 
 //______________________________________________________________________________
 TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
-   : fType(&typ), fLastType(&typ), fClass(0), fLastClass(0),
-     fVirtual(false), fContext(ctxt), fInit(false)
+   : fType(&typ), fClass(nullptr), fLast(nullptr), fContext(ctxt),
+     fSubTypesReaders(0), fSubTypesWriteLockTaken(false),
+     fVirtual(false), fInit(false)
 {
    // Standard initializing constructor
 
    ::new(fSubTypes) ClassMap_t();
-   if ( sizeof(ClassMap_t) > sizeof(fSubTypes) ) {
-      Fatal("TIsAProxy::TIsAProxy",
-         "Classmap size is badly adjusted: it needs %u instead of %u bytes.",
-         (UInt_t)sizeof(ClassMap_t), (UInt_t)sizeof(fSubTypes));
-   }
-}
-
-//______________________________________________________________________________
-TIsAProxy::TIsAProxy(const TIsAProxy& iap) :
-  TVirtualIsAProxy(iap),
-  fType(iap.fType),
-  fLastType(iap.fLastType),
-  fClass(iap.fClass),
-  fLastClass(iap.fLastClass),
-  fVirtual(iap.fVirtual),
-  fContext(iap.fContext),
-  fInit(iap.fInit)
-{
-   //copy constructor
-   for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
-}
-
-//______________________________________________________________________________
-TIsAProxy& TIsAProxy::operator=(const TIsAProxy& iap)
-{
-   //assignement operator
-   if(this!=&iap) {
-      TVirtualIsAProxy::operator=(iap);
-      fType=iap.fType;
-      fLastType=iap.fLastType;
-      fClass=iap.fClass;
-      fLastClass=iap.fLastClass;
-      for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
-      fVirtual=iap.fVirtual;
-      fContext=iap.fContext;
-      fInit=iap.fInit;
-   }
-   return *this;
+   static_assert(sizeof(ClassMap_t)<=sizeof(fSubTypes), "ClassMap size is to large for array");
 }
 
 //______________________________________________________________________________
@@ -102,8 +71,10 @@ TIsAProxy::~TIsAProxy()
 void TIsAProxy::SetClass(TClass *cl)
 {
    // Set class pointer
+   //   This method is not thread safe
    GetMap(fSubTypes)->clear();
-   fClass = fLastClass = cl;
+   fClass = cl;
+   fLast = nullptr;
 }
 
 //______________________________________________________________________________
@@ -112,38 +83,85 @@ TClass* TIsAProxy::operator()(const void *obj)
    // IsA callback
 
    if ( !fInit )  {
+      if ( !fClass && fType ) {
+         auto cls = TClass::GetClass(*fType);
+         TClass* expected = nullptr;
+         fClass.compare_exchange_strong(expected,cls);
+      }
+      if ( !fClass) return nullptr;
+      fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
       fInit = kTRUE;
-      if ( !fClass && fType ) fClass = TClass::GetClass(*fType);
-      if ( !fClass) return 0;
-      fVirtual = fClass->ClassProperty() & kClassHasVirtual;
    }
    if ( !obj || !fVirtual )  {
-      return fClass;
-   } else  {
-      // Avoid the case that the first word is a virtual_base_offset_table instead of
-      // a virtual_function_table
-      Long_t offset = **(Long_t**)obj;
-      if ( offset == 0 ) return fClass;
-
-      DynamicType* ptr = (DynamicType*)obj;
-      const std::type_info* typ = &typeid(*ptr);
-
-      if ( typ == fType )  {
-         return fClass;
-      }
-      else if ( typ == fLastType )  {
-         return fLastClass;
-      }
-      // Check if type is already in sub-class cache
-      else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) )  {
-         fLastType = typ;
-      }
-      // Last resort: lookup root class
-      else   {
-         fLastClass = TClass::GetClass(*typ);
-         fLastType = typ;
-         (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
-      }
+      return fClass.load();
+   }
+   // Avoid the case that the first word is a virtual_base_offset_table instead of
+   // a virtual_function_table
+   Long_t offset = **(Long_t**)obj;
+   if ( offset == 0 ) return fClass.load();
+   
+   DynamicType* ptr = (DynamicType*)obj;
+   const std::type_info* typ = &typeid(*ptr);
+   
+   if ( typ == fType )  {
+     return fClass.load();
+   }
+   auto last = ToPair(fLast.load());
+   if ( last && typ == last->first )  {
+     return last->second;
+   }
+   // Check if type is already in sub-class cache
+   if ( nullptr == (last = ToPair(FindSubType(typ)) ) )  {
+     
+     // Last resort: lookup root class
+     auto cls = TClass::GetClass(*typ);
+     last = ToPair(CacheSubType(typ,cls));
+   }
+   fLast.store(last);
+
+   return last == nullptr? nullptr: last->second;
+}
+//______________________________________________________________________________
+inline void* TIsAProxy::FindSubType(const type_info* type) const
+{
+   bool needToWait = true;
+   do {
+     ++fSubTypesReaders;
+
+     //See if there is a writer, if there is we need to release
+     // our reader count so that the writer can proceed
+     if(fSubTypesWriteLockTaken) {
+       --fSubTypesReaders;
+       while(fSubTypesWriteLockTaken) {}
+     } else {
+       needToWait = false;
+     }
+   } while(needToWait);
+
+   void* returnValue =nullptr;
+   auto const map = GetMap(fSubTypes);
+
+   auto found = map->find(type);
+   if(found != map->end()) {
+      returnValue = &(*found);
    }
-   return fLastClass;
+   --fSubTypesReaders;
+   return returnValue;
+}
+
+//______________________________________________________________________________
+void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
+{
+   //See if another thread has the write lock, wait if it does
+   bool expected = false;
+   while(not fSubTypesWriteLockTaken.compare_exchange_strong(expected,true) ) {expected = false;};
+
+   //See if there are any readers
+   while(fSubTypesReaders > 0);
+
+   auto map = GetMap(fSubTypes);
+   auto ret = map->emplace(type,cls);
+
+   fSubTypesWriteLockTaken = false;
+   return &(*(ret.first));
 }

From ceff4e69db368c284f5c73778c4d23e580eb4d3e Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 12:23:06 -0600
Subject: [PATCH 139/200] Coding conventions

---
 core/meta/inc/TIsAProxy.h   | 16 +++++++++-------
 core/meta/src/TIsAProxy.cxx | 36 ++++++++++++++++++++++--------------
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/core/meta/inc/TIsAProxy.h b/core/meta/inc/TIsAProxy.h
index a4a1e6105de48..dcbfb474033f9 100644
--- a/core/meta/inc/TIsAProxy.h
+++ b/core/meta/inc/TIsAProxy.h
@@ -29,15 +29,17 @@ class TClass;
 //////////////////////////////////////////////////////////////////////////
 class TIsAProxy  : public TVirtualIsAProxy {
 private:
+   template <typename T> using Atomic_t = std::atomic<T>;
+
    const type_info          *fType;        //Actual typeid of the proxy
-   std::atomic<TClass*>     fClass;        //Actual TClass
-   std::atomic<void*>       fLast;         //points into fSubTypes map for last used values
-   Char_t                   fSubTypes[72]; //map of known sub-types
+   Atomic_t<TClass*>         fClass;       //Actual TClass
+   Atomic_t<void*>           fLast;        //points into fSubTypes map for last used values
+   Char_t                    fSubTypes[72];//map of known sub-types
    void                     *fContext;     //Optional user contex
-   mutable std::atomic<unsigned int> fSubTypesReaders; //number of readers of fSubTypes
-   std::atomic<bool>      fSubTypesWriteLockTaken; //True if there is a writer
-   Bool_t                   fVirtual;      //Flag if class is virtual
-   std::atomic<bool>      fInit;         //Initialization flag
+   mutable Atomic_t<UInt_t>  fSubTypesReaders; //number of readers of fSubTypes
+   Atomic_t<Bool_t>          fSubTypesWriteLockTaken; //True if there is a writer
+   Bool_t                    fVirtual;     //Flag if class is virtual
+   Atomic_t<Bool_t>          fInit;        //Initialization flag
 
    void* FindSubType(const type_info*) const;
    void* CacheSubType(const type_info*, TClass*);
diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index dc6788cf5168c..0cca695c385a7 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -39,22 +39,23 @@ namespace {
       return (ClassMap_t*)p;
    }
 
-   inline ClassMap_t::value_type* ToPair(void*p) 
+   inline ClassMap_t::value_type* ToPair(void*p)
    {
-     return (ClassMap_t::value_type*)p;
+      return (ClassMap_t::value_type*)p;
    }
 }
 
 //______________________________________________________________________________
 TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
    : fType(&typ), fClass(nullptr), fLast(nullptr), fContext(ctxt),
-     fSubTypesReaders(0), fSubTypesWriteLockTaken(false),
-     fVirtual(false), fInit(false)
+     fSubTypesReaders(0), fSubTypesWriteLockTaken(kFALSE),
+     fVirtual(kFALSE), fInit(kFALSE)
 {
    // Standard initializing constructor
 
-   ::new(fSubTypes) ClassMap_t();
    static_assert(sizeof(ClassMap_t)<=sizeof(fSubTypes), "ClassMap size is to large for array");
+
+   ::new(fSubTypes) ClassMap_t();
 }
 
 //______________________________________________________________________________
@@ -99,10 +100,10 @@ TClass* TIsAProxy::operator()(const void *obj)
    // a virtual_function_table
    Long_t offset = **(Long_t**)obj;
    if ( offset == 0 ) return fClass.load();
-   
+
    DynamicType* ptr = (DynamicType*)obj;
    const std::type_info* typ = &typeid(*ptr);
-   
+
    if ( typ == fType )  {
      return fClass.load();
    }
@@ -112,7 +113,7 @@ TClass* TIsAProxy::operator()(const void *obj)
    }
    // Check if type is already in sub-class cache
    if ( nullptr == (last = ToPair(FindSubType(typ)) ) )  {
-     
+
      // Last resort: lookup root class
      auto cls = TClass::GetClass(*typ);
      last = ToPair(CacheSubType(typ,cls));
@@ -121,10 +122,13 @@ TClass* TIsAProxy::operator()(const void *obj)
 
    return last == nullptr? nullptr: last->second;
 }
+
 //______________________________________________________________________________
 inline void* TIsAProxy::FindSubType(const type_info* type) const
 {
-   bool needToWait = true;
+   // See if we have already cached the TClass that correspond to this type_info.
+
+   bool needToWait = kTRUE;
    do {
      ++fSubTypesReaders;
 
@@ -134,11 +138,11 @@ inline void* TIsAProxy::FindSubType(const type_info* type) const
        --fSubTypesReaders;
        while(fSubTypesWriteLockTaken) {}
      } else {
-       needToWait = false;
+       needToWait = kFALSE;
      }
    } while(needToWait);
 
-   void* returnValue =nullptr;
+   void* returnValue = nullptr;
    auto const map = GetMap(fSubTypes);
 
    auto found = map->find(type);
@@ -152,9 +156,13 @@ inline void* TIsAProxy::FindSubType(const type_info* type) const
 //______________________________________________________________________________
 void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
 {
+   // Record the TClass found for a type_info, so that we can retrieved it faster.
+
    //See if another thread has the write lock, wait if it does
-   bool expected = false;
-   while(not fSubTypesWriteLockTaken.compare_exchange_strong(expected,true) ) {expected = false;};
+   Bool_t expected = kFALSE;
+   while(! fSubTypesWriteLockTaken.compare_exchange_strong(expected,kTRUE) ) {
+      expected = kFALSE;
+   };
 
    //See if there are any readers
    while(fSubTypesReaders > 0);
@@ -162,6 +170,6 @@ void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
    auto map = GetMap(fSubTypes);
    auto ret = map->emplace(type,cls);
 
-   fSubTypesWriteLockTaken = false;
+   fSubTypesWriteLockTaken = kFALSE;
    return &(*(ret.first));
 }

From bd55d3be105daed26d7df7cd1cc89c1776b12d50 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 15:51:57 -0600
Subject: [PATCH 140/200] Readd support for late loading of TClass in IsAProxy.

When the cached value is nullptr, we need to check if the TClass has been loaded since.
---
 core/meta/src/TIsAProxy.cxx | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index 0cca695c385a7..c10faeac50ab0 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -99,7 +99,9 @@ TClass* TIsAProxy::operator()(const void *obj)
    // Avoid the case that the first word is a virtual_base_offset_table instead of
    // a virtual_function_table
    Long_t offset = **(Long_t**)obj;
-   if ( offset == 0 ) return fClass.load();
+   if ( offset == 0 ) {
+      return fClass.load();
+   }
 
    DynamicType* ptr = (DynamicType*)obj;
    const std::type_info* typ = &typeid(*ptr);
@@ -109,14 +111,14 @@ TClass* TIsAProxy::operator()(const void *obj)
    }
    auto last = ToPair(fLast.load());
    if ( last && typ == last->first )  {
-     return last->second;
+      return last->second;
    }
    // Check if type is already in sub-class cache
-   if ( nullptr == (last = ToPair(FindSubType(typ)) ) )  {
-
-     // Last resort: lookup root class
-     auto cls = TClass::GetClass(*typ);
-     last = ToPair(CacheSubType(typ,cls));
+   last = ToPair(FindSubType(typ));
+   if ( last == nullptr || last->second == nullptr )  {
+      // Last resort: lookup root class
+      auto cls = TClass::GetClass(*typ);
+      last = ToPair(CacheSubType(typ,cls));
    }
    fLast.store(last);
 
@@ -169,6 +171,10 @@ void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
 
    auto map = GetMap(fSubTypes);
    auto ret = map->emplace(type,cls);
+   if (!ret.second) {
+      // type is already in the map, let's update it.
+      (*ret.first).second = cls;
+   }
 
    fSubTypesWriteLockTaken = kFALSE;
    return &(*(ret.first));

From 43d3c852e87a784f0141b9b94327ba7831d7bf2b Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 16:32:45 -0600
Subject: [PATCH 141/200] Remove unused data member from TIsAProxy

---
 core/doc/v604/index.md            | 8 +++++++-
 core/meta/inc/TIsAProxy.h         | 3 +--
 core/meta/src/TIsAProxy.cxx       | 4 ++--
 core/metautils/src/TMetaUtils.cxx | 2 +-
 4 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/core/doc/v604/index.md b/core/doc/v604/index.md
index 4434cc1c6e359..180b14f74dac6 100644
--- a/core/doc/v604/index.md
+++ b/core/doc/v604/index.md
@@ -1,4 +1,3 @@
-
 ## Core Libraries
 
 ### Interpreter
@@ -7,6 +6,12 @@ The new interface `TInterpreter::Declare(const char* code)` will declare the
 code to the interpreter with all interpreter extensions disabled, i.e. as
 "proper" C++ code. No autoloading or synamic lookup will be performed.
 
+### Meta library
+
+#### Backward Incompatibilities
+
+TIsAProxy's constructor no longer take the optional and unused 2nd argument which was reserved for a 'context'.  This context was unused in TIsAProxy itself and was not accessible from derived classes.
+
 ### TROOT
 
 Implemented new gROOT->GetTutorialsDir() static method to return the actual location of the tutorials directory.
@@ -22,3 +27,4 @@ Introduced new overload for calculating the TClass CheckSum:
 
 which indicates via the 'isvalid' boolean whether the checksum could be
 calculated correctly or not.
+
diff --git a/core/meta/inc/TIsAProxy.h b/core/meta/inc/TIsAProxy.h
index dcbfb474033f9..ef0fd782337ad 100644
--- a/core/meta/inc/TIsAProxy.h
+++ b/core/meta/inc/TIsAProxy.h
@@ -35,7 +35,6 @@ class TIsAProxy  : public TVirtualIsAProxy {
    Atomic_t<TClass*>         fClass;       //Actual TClass
    Atomic_t<void*>           fLast;        //points into fSubTypes map for last used values
    Char_t                    fSubTypes[72];//map of known sub-types
-   void                     *fContext;     //Optional user contex
    mutable Atomic_t<UInt_t>  fSubTypesReaders; //number of readers of fSubTypes
    Atomic_t<Bool_t>          fSubTypesWriteLockTaken; //True if there is a writer
    Bool_t                    fVirtual;     //Flag if class is virtual
@@ -49,7 +48,7 @@ class TIsAProxy  : public TVirtualIsAProxy {
 
 public:
    // Standard initializing constructor
-   TIsAProxy(const type_info &typ, void *ctxt = 0);
+   TIsAProxy(const type_info &typ);
    // Standard destructor
    virtual ~TIsAProxy();
    // Callbacl to set the class
diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index c10faeac50ab0..44d57d98d0b80 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -46,8 +46,8 @@ namespace {
 }
 
 //______________________________________________________________________________
-TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
-   : fType(&typ), fClass(nullptr), fLast(nullptr), fContext(ctxt),
+TIsAProxy::TIsAProxy(const std::type_info& typ)
+   : fType(&typ), fClass(nullptr), fLast(nullptr),
      fSubTypesReaders(0), fSubTypesWriteLockTaken(kFALSE),
      fVirtual(kFALSE), fInit(kFALSE)
 {
diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx
index 5b7cef848b581..6bc2791d52869 100644
--- a/core/metautils/src/TMetaUtils.cxx
+++ b/core/metautils/src/TMetaUtils.cxx
@@ -1747,7 +1747,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
       finalString << "      static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< "  << csymbol << " >(0);" << "\n";
    }
    else {
-      finalString << "      static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol << "),0);" << "\n";
+      finalString << "      static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol << "));" << "\n";
    }
    finalString << "      static ::ROOT::TGenericClassInfo " << "\n" << "         instance(\"" << classname.c_str() << "\", ";
 

From 5cfd53bf51557f0184df3458fd58c0acf1acffe5 Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Wed, 4 Mar 2015 23:40:33 +0100
Subject: [PATCH 142/200] Fix in Formula the exponential notations of numbers.
 More fixes for ROOT-7122

---
 hist/hist/src/TFormula.cxx | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/hist/hist/src/TFormula.cxx b/hist/hist/src/TFormula.cxx
index f4407e4c91fab..778f8557ac5a6 100644
--- a/hist/hist/src/TFormula.cxx
+++ b/hist/hist/src/TFormula.cxx
@@ -437,6 +437,9 @@ void TFormula::FillDefaults()
          {"loge",TMath::LogE()}, {"c",TMath::C()}, {"g",TMath::G()},
          {"h",TMath::H()}, {"k",TMath::K()},{"sigma",TMath::Sigma()},
          {"r",TMath::R()}, {"eg",TMath::EulerGamma()},{"true",1},{"false",0} };
+   // const pair<TString,Double_t> defconsts[] = { {"pi",TMath::Pi()}, {"sqrt2",TMath::Sqrt2()},
+   //       {"infinity",TMath::Infinity()}, {"ln10",TMath::Ln10()},
+   //       {"loge",TMath::LogE()}, {"true",1},{"false",0} };
    const pair<TString,TString> funShortcuts[] = { {"sin","TMath::Sin" },
          {"cos","TMath::Cos" }, {"exp","TMath::Exp"}, {"log","TMath::Log"}, {"log10","TMath::Log10"},
          {"tan","TMath::Tan"}, {"sinh","TMath::SinH"}, {"cosh","TMath::CosH"},
@@ -1021,10 +1024,18 @@ void TFormula::ExtractFunctors(TString &formula)
             i++;
          } while(formula[i] != '\"');
       }
+      // case of e or E for numbers in exponential notaton (e.g. 2.2e-3)
+      if ( (formula[i] == 'e' || formula[i] == 'E')  &&  (i > 0 && i <  formula.Length()-1) )  {
+         // handle cases:  2e+3 2e-3 2e3 and 2.e+3 
+         if ( (isdigit(formula[i-1]) || formula[i-1] == '.') && ( isdigit(formula[i+1]) || formula[i+1] == '+' || formula[i+1] == '-' ) )
+            continue;
+      }
+
       if(isalpha(formula[i]) && !IsOperator(formula[i]))
       {
          //std::cout << "character : " << i << " " << formula[i] << " is not an operator and is alpha " << std::endl;
 
+
          while( IsFunctionNameChar(formula[i]) && i < formula.Length())
          {
             name.Append(formula[i++]);

From 52611aa973403417e377cae99f33a46b8570975a Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 09:40:41 +0100
Subject: [PATCH 143/200] Avoid autoparsing when grabbing non scoped TEnums
 from the typesystem.

---
 core/meta/src/TEnum.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx
index bb1bb20844f3d..bc2852caf9513 100644
--- a/core/meta/src/TEnum.cxx
+++ b/core/meta/src/TEnum.cxx
@@ -221,7 +221,7 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
          }
          theEnum = searchEnum(scopeName, enName, kAutoload);
       }
-      if (!theEnum && (sa == kALoadAndInterpLookup)) {
+      if (!theEnum && (sa & kALoadAndInterpLookup)) {
          if (gDebug > 0) {
             printf("TEnum::GetEnum: Header Parsing - The enumerator %s is not known to the typesystem: an interpreter lookup will be performed. This can imply parsing of headers. This can be avoided selecting the numerator in the linkdef/selection file.\n", enumName);
          }
@@ -233,7 +233,7 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
    } else {
       // We don't have any scope: this is a global enum
       theEnum = findEnumInList(gROOT->GetListOfEnums(), enumName, kNone);
-      if (!theEnum && (sa == kAutoload)) {
+      if (!theEnum && (sa & kAutoload)) {
          gInterpreter->AutoLoad(enumName);
          theEnum = findEnumInList(gROOT->GetListOfEnums(), enumName, kAutoload);
       }

From 376d56ea5d4bcae2a1b908c65885362347e3791a Mon Sep 17 00:00:00 2001
From: Liza Sakellari <elisavet.sakellari@cern.ch>
Date: Thu, 5 Mar 2015 10:46:33 +0100
Subject: [PATCH 144/200] Added (void)para for unused parameter in file
 Converters.cxx.

---
 bindings/pyroot/src/Converters.cxx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bindings/pyroot/src/Converters.cxx b/bindings/pyroot/src/Converters.cxx
index 34e8c85d2cc8d..fbb94eac7d3ff 100644
--- a/bindings/pyroot/src/Converters.cxx
+++ b/bindings/pyroot/src/Converters.cxx
@@ -232,6 +232,7 @@ Bool_t PyROOT::TLongRefConverter::SetArg(
    para.fTypeCode = 'v';
    return kTRUE;
 #else
+   (void)para;
    PyErr_SetString( PyExc_NotImplementedError, "int pass-by-ref not implemented in p3" );
    return kFALSE; // there no longer is a PyIntObject in p3
 #endif

From 8b21ed05132192b54e9ca3ff47338b323fc5eda4 Mon Sep 17 00:00:00 2001
From: Sergey Linev <S.Linev@gsi.de>
Date: Thu, 5 Mar 2015 09:42:54 +0100
Subject: [PATCH 145/200] jsroot: use SVG output in MathJax

Instead of foreignObject and HTML output of MathJax
'misuse' SVG convertion of MathJax. Main workaround behind - after
MathJax SVG element produced, it is extracted from hidden
HTML element and inserted into ROOT SVG hierarchy.
Works with Firefox, IE9, Chrome

Signed-off-by: Bertrand Bellenot <bertrand.bellenot@cern.ch>
---
 etc/http/changes.md               |   3 +-
 etc/http/scripts/JSRootCore.js    |   5 +-
 etc/http/scripts/JSRootPainter.js | 240 +++++++++++++++---------------
 3 files changed, 127 insertions(+), 121 deletions(-)

diff --git a/etc/http/changes.md b/etc/http/changes.md
index 915c69737ec78..939063494f064 100644
--- a/etc/http/changes.md
+++ b/etc/http/changes.md
@@ -10,7 +10,8 @@ Many old problems and errors are fixed, new functions are provided.
    usage of jquery.js in core JSROOT classes
 3. Implement main graphics without jquery at all,
    such mode used in `nobrowser` mode.
-4. Implement MathJax support in JSROOT, TMathText always drawn with MathJax
+4. Provide optional latex drawing with MathJax SVG.
+   TMathText always drawn with MathJax,
    other classes require `mathjax` option in URL
 5. Improve drawing of different text classes, correctly handle
    their alignment and scaling
diff --git a/etc/http/scripts/JSRootCore.js b/etc/http/scripts/JSRootCore.js
index dc691863607a7..e66553fdc29bc 100644
--- a/etc/http/scripts/JSRootCore.js
+++ b/etc/http/scripts/JSRootCore.js
@@ -14,7 +14,7 @@
 
    JSROOT = {};
 
-   JSROOT.version = "3.4 dev 3/03/2015";
+   JSROOT.version = "3.4 dev 5/03/2015";
 
    JSROOT.source_dir = "";
    JSROOT.source_min = false;
@@ -566,7 +566,8 @@
       }
 
       if (kind.indexOf("mathjax;")>=0) {
-         allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML;";
+         //allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML;";
+         allfiles += "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG;";
          if (JSROOT.MathJax == 0) JSROOT.MathJax = 1;
       }
 
diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index 26d574c067e67..aa11c85261564 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -752,7 +752,9 @@
       '#Box' : '',
       '#parallel' : '',
       '#perp' : '\u22A5',
-      '#odot' : ''
+      '#odot' : '',
+      '#left' : '',
+      '#right' : ''
    };
 
    JSROOT.Painter.translateLaTeX = function(string) {
@@ -811,12 +813,6 @@
       // function translate ROOT TLatex into MathJax format
 
       if (kind!=2) {
-
-         for (var x in JSROOT.Painter.symbols_map) {
-            var y = "\\" + x.substr(1);
-            str = str.replace(new RegExp(x,'g'), y);
-         }
-
          str = str.replace(/#frac/g, "\\frac");
          str = str.replace(/#left{/g, "\\left\\{");
          str = str.replace(/#right}/g, "\\right\\}");
@@ -824,6 +820,11 @@
          str = str.replace(/#right/g, "\\right");
          // processing of #[] #{} should be done
          str = str.replace(/#\[\]/g, "\\[]");
+
+         for (var x in JSROOT.Painter.symbols_map) {
+            var y = "\\" + x.substr(1);
+            str = str.replace(new RegExp(x,'g'), y);
+         }
       } else {
          str = str.replace(/\\\^/g, "\\hat");
       }
@@ -918,7 +919,7 @@
       }
    }
 
-   JSROOT.TObjectPainter.prototype.RecreateDrawG = function(take_pad, layer) {
+   JSROOT.TObjectPainter.prototype.RecreateDrawG = function(take_pad, layer, normalg) {
       //this.RemoveDrawG();
 
       if (this.draw_g)
@@ -936,15 +937,19 @@
 
          if (!this.draw_g) {
             if (layer==null) layer = ".main_layer";
-            this.draw_g = frame.select(layer).append("svg");
+            if (normalg)
+               this.draw_g = frame.select(layer).append("g");
+            else
+               this.draw_g = frame.select(layer).append("svg");
          }
 
-         this.draw_g.attr("x", 0)
-                    .attr("y", 0)
-                    .attr("width",w)
-                    .attr("height", h)
-                    .attr("viewBox", "0 0 " + w + " " + h)
-                    .attr('overflow', 'hidden');
+         if (!normalg)
+            this.draw_g.attr("x", 0)
+                       .attr("y", 0)
+                       .attr("width",w)
+                       .attr("height", h)
+                       .attr("viewBox", "0 0 " + w + " " + h)
+                       .attr('overflow', 'hidden');
       }
    }
 
@@ -1425,7 +1430,7 @@
       draw_g.call(font.func);
 
       draw_g.property('text_font', font);
-      draw_g.property('mathjax_cnt', 1); // one should wait until last call
+      draw_g.property('mathjax_use', false);
       draw_g.property('text_factor', 0.);
       draw_g.property('max_text_width', 0); // keep maximal text width, use it later
    }
@@ -1436,73 +1441,62 @@
       if (value && (value > draw_g.property('text_factor'))) draw_g.property('text_factor', value);
    }
 
-   JSROOT.TObjectPainter.prototype.FinishTextDrawing = function(entry, draw_g) {
+   JSROOT.TObjectPainter.prototype.FinishTextDrawing = function(draw_g) {
+
       if (!draw_g) draw_g = this.draw_g;
 
-      if (entry != null) {
-
-         MathJax.Hub.Typeset(entry.node());
-
-         var scale = entry.property('_scale');
-         var fo = entry.property('_fo'); entry.property('_fo', null);
-         var align = entry.property('_align');
-
-         var prnt = entry.node();
-         if (scale) prnt = prnt.parentNode;
-         // getBoundingClientRect do not work for div with width/height attributes, check childs
-         // var rect = prnt.getBoundingClientRect();
-         var chlds = prnt.childNodes;
-         var left = 100000000, right = 0, top = 100000000, bottom = 0;
-         for (var n=0;n<chlds.length+1;n++) {
-            var rrr = null;
-            if (n<chlds.length) {
-               if (typeof chlds[n]['getBoundingClientRect'] != 'function') continue;
-               rrr = chlds[n].getBoundingClientRect();
-            } else {
-               if ((left<right) && (top<bottom)) continue;
-               rrr = prnt.getBoundingClientRect();
-            }
+      var svgs = null;
 
-            if ((rrr.left==rrr.right) || (rrr.top==rrr.bottom)) continue;
+      if (draw_g.property('mathjax_use')) {
+         draw_g.property('mathjax_use', false);
+         draw_g.property('_painter', this);
 
-            left = Math.min(left, parseInt(rrr.left));
-            right = Math.max(right, parseInt(rrr.right));
-            top = Math.min(top,parseInt(rrr.top));
-            bottom = Math.max(bottom, parseInt(rrr.bottom));
-            //console.log(n+ "  left = " + rrr.left + " right = " + rrr.right + " top = " + rrr.top + " bottom = " + rrr.bottom);
-         }
-         var real_w = right - left, real_h = bottom - top;
+         var missing = false;
+         svgs = draw_g.selectAll(".math_svg");
 
-         // console.log("childs width = " + real_w + "  left = " +left + " right = " + right + " rotate = " + rotate);
-         // console.log("childs height = " + real_h + " top = " + top + " bottom = " + bottom);
+         svgs.each(function() {
+            var fo_g = d3.select(this);
+            if (fo_g.node().parentNode !== draw_g.node()) return;
+            var entry = fo_g.property('_element');
+            if (d3.select(entry).select("svg").empty()) missing = true;
+         });
 
-         if (real_w > draw_g.property('max_text_width')) draw_g.property('max_text_width', real_w);
-         if (!scale) {
-            // only after drawing performed one could calculate size and adjust position
-            var dx = 0, dy = 0;
-            if (entry.property('_rotate')) {
-               if (align[1] == 'middle') dy = -real_w/2; else
-               if (align[1] == 'top') dy = -real_w;
-               if (align[0] == 'middle') dx = -real_h/2; else
-               if (align[0] == 'end') dx = -real_h;
-            } else {
-               if (align[1] == 'middle') dy = -real_h/2; else
-               if (align[1] == 'top') dy = -real_h;
-               if (align[0] == 'middle') dx = -real_w/2; else
-               if (align[0] == 'end') dx = -real_w;
-            }
-            if (dx != 0) { dx += parseInt(fo.attr('x')); fo.attr('x', dx); }
-            if (dy != 0) { dy += parseInt(fo.attr('y')); fo.attr('y', dy); }
-            return; // no need to continue when scaling not performed
+         // is any svg missing we shold wait until drawing is really finished
+         if (missing)
+            return JSROOT.AssertPrerequisites('mathjax', { _this:draw_g, func: function() {
+               if (typeof MathJax != 'object') return;
+               MathJax.Hub.Queue(["FinishTextDrawing", this.property('_painter'), this]);
+            }});
+      }
+
+      if (svgs==null) svgs = draw_g.selectAll(".math_svg");
+
+      var painter = this;
+
+      // first remove dummy divs and check scaling coefficient
+      svgs.each(function() {
+         var fo_g = d3.select(this);
+         if (fo_g.node().parentNode !== draw_g.node()) return;
+         var entry = fo_g.property('_element'); fo_g.property('_element', null);
+
+         var vvv = d3.select(entry).select("svg");
+         if (vvv.empty()) {
+            console.log('MathJax SVG ouptut error');
+            return;
          }
 
-         this.TextScaleFactor(1.*real_w / parseInt(fo.attr('width')), draw_g);
-         this.TextScaleFactor(1.*real_h / parseInt(fo.attr('height')), draw_g);
-      }
+         vvv.remove();
+         document.body.removeChild(entry);
 
-      var cnt = draw_g.property('mathjax_cnt') - 1;
-      draw_g.property('mathjax_cnt', cnt);
-      if (cnt > 0) return 0;
+         fo_g.append(function() { return vvv.node(); });
+
+         if (fo_g.property('_scale')) {
+            var box = fo_g.node().getBBox();
+            var real_w = parseInt(box.width), real_h = parseInt(box.height);
+            painter.TextScaleFactor(1.*real_w / parseInt(fo_g.attr('width')), draw_g);
+            painter.TextScaleFactor(1.*real_h / parseInt(fo_g.attr('height')), draw_g);
+         }
+      });
 
       var f = draw_g.property('text_factor');
       var font = draw_g.property('text_font');
@@ -1511,6 +1505,33 @@
          draw_g.call(font.func);
       }
 
+      svgs.each(function() {
+         var fo_g = d3.select(this);
+         // only direct parent
+         if (fo_g.node().parentNode !== draw_g.node()) return;
+         var box = fo_g.node().getBBox();
+         var real_w = parseInt(box.width), real_h = parseInt(box.height);
+         var align = fo_g.property('_align');
+         var fo_w = parseInt(fo_g.attr('width')), fo_h = parseInt(fo_g.attr('height'));
+         var fo_x = parseInt(fo_g.attr('x')), fo_y = parseInt(fo_g.attr('y'));
+
+         if (fo_g.property('_scale')) {
+            if (align[0] == 'middle') fo_x += (fo_w - real_w)/2; else
+            if (align[0] == 'end') fo_x +=  (fo_w - real_w);
+            if (align[1] == 'middle') fo_y += (fo_h - real_h)/2; else
+            if (align[1] == 'bottom') fo_y += (fo_h - real_h);
+         } else {
+            if (align[0] == 'middle') fo_x -= real_w/2; else
+            if (align[0] == 'end') fo_x -= real_w;
+            if (align[1] == 'middle') fo_y -= real_h/2; else
+            if (align[1] == 'top') fo_y -= real_h;
+         }
+
+         fo_g.attr('x', fo_x).attr('y', fo_y)  // use x/y while transform used for rotation
+             .attr('width', real_w+10).attr('height', real_h+10)  // width and height required by Chrome
+             .attr('visibility', null);
+      });
+
       return draw_g.property('max_text_width');
    }
 
@@ -1525,6 +1546,7 @@
          align = ['start', 'middle'];
          if ((align_arg / 10) >= 3) align[0] = 'end'; else
          if ((align_arg / 10) >= 2) align[0] = 'middle';
+         if ((align_arg % 10) == 0) align[1] = 'top'; else
          if ((align_arg % 10) == 1) align[1] = 'top'; else
          if ((align_arg % 10) == 3) align[1] = 'bottom';
       }
@@ -1571,8 +1593,7 @@
             // if (align[0]=="end") txt.attr("x", (x + real_w).toFixed(1));
             // if (align[1]=="middle") txt.attr("y", (y-real_h/2).toFixed(1)); else
 
-            if ((align[1]=="bottom") && (h==0)) { txt.attr("y", (y-real_h).toFixed(1)); console.log('shift y due to vertical align'); }
-
+            if ((align[1]=="bottom") && (h==0)) txt.attr("y", (y+real_h).toFixed(1));
          }
 
          if (real_w > draw_g.property('max_text_width')) draw_g.property('max_text_width', real_w);
@@ -1592,48 +1613,30 @@
          w = this.pad_width(); h = this.pad_height(); // artifical values, big enough to see output
       }
 
-      var fo = draw_g.append("foreignObject").attr("width", w).attr("height", h);
-      this.SetForeignObjectPosition(fo, x, y);
-      if (rotate) fo.attr("transform", "rotate(270, 0, 0)");
-
-      label = JSROOT.Painter.translateMath(label, latex_kind);
-
-      var entry = fo.append("xhtml:div");
-      if (scale) {
-         var tr = "";
-         entry = entry.style("width", w+"px")
-                      .style("height", h+"px")
-                      .append("xhtml:div")
-                      .style('position','absolute');
-         switch (align[0]) {
-            case 'left' : entry.style('left','0%'); break;
-            case 'middle' : entry.style('left','50%'); tr = "translateX(-50%) "; break;
-            case 'right' :  entry.style('left','100%'); tr = "translateX(-100%) "; break;
-         }
-         switch (align[1]) {
-            case 'top': entry.style('top','0%'); break;
-            case 'middle' : entry.style('top','50%'); tr+="translateY(-50%)"; break;
-            case 'bottom' :  entry.style('top','100%'); tr+="translateY(-100%)"; break;
-         }
-         if (tr.length>0) entry.style('transform', tr);
-      }
-
+      var fo_g = draw_g.append("svg")
+                       .attr('x',x).attr('y',y)  // set x,y, width,height attribute to be able apply alignment later
+                       .attr('width',w).attr('height',h)
+                       .attr('class', 'math_svg')
+                       .attr('visibility','hidden')
+                       .property('_scale', scale)
+                       .property('_rotate', rotate)
+                       .property('_align', align);
 
-      entry.style("color", tcolor ? tcolor : null);
+      if (rotate) fo_g.attr("transform", "rotate(270, 0, 0)");
 
-      entry.property("_painter", this)
-          .property("_scale", scale)
-          .property("_align", align) // keep align for the end
-          .property("_fo", fo) // keep foreign object till the end
-          .property("_rotate", rotate) // keep rotate attr the end
-          .html(label);
+      var element = document.createElement("div");
+      d3.select(element).style("visibility", "hidden")
+                        .style("overflow", "hidden")
+                        .style("position", "absolute")
+                        .html(JSROOT.Painter.translateMath(label, latex_kind));
+      document.body.appendChild(element)
 
-      var cnt = draw_g.property('mathjax_cnt')+1;
-      draw_g.property('mathjax_cnt', cnt);
+      draw_g.property('mathjax_use', true);  // one need to know that mathjax is used
+      fo_g.property('_element', element);
 
-      JSROOT.AssertPrerequisites('mathjax', { _this:entry, func: function() {
-         if (typeof MathJax != 'object') return;
-         MathJax.Hub.Queue(["FinishTextDrawing", this.property('_painter'), this]);
+      JSROOT.AssertPrerequisites('mathjax', { _this:element, func: function() {
+         if (typeof MathJax == 'object')
+            MathJax.Hub.Queue(["Typeset", MathJax.Hub, this]);
       }});
 
       return 0;
@@ -1734,6 +1737,7 @@
          frame_g.append('svg:g').attr('class','grid_layer');
          frame_g.append('svg:g').attr('class','main_layer');
          frame_g.append('svg:g').attr('class','axis_layer');
+         frame_g.append('svg:g').attr('class','upper_layer');
       } else {
          top_rect = frame_g.select("rect");
       }
@@ -2800,7 +2804,7 @@
 
          this.DrawText(22, 0, 0, width*0.5, h*0.04, pavetext.fLabel, tcolor, 1, lbl_g);
 
-         this.FinishTextDrawing(null, lbl_g);
+         this.FinishTextDrawing(lbl_g);
       }
 
       this.AddDrag({ obj:pavetext, redraw:'DrawPaveText' });
@@ -4114,7 +4118,7 @@
 
           if (res<=0) shrink_forbidden = true;
 
-          this.FinishTextDrawing(null, xax_g);
+          this.FinishTextDrawing(xax_g);
       }
 
       /* Y-axis label */
@@ -4130,7 +4134,7 @@
 
          if (res<=0) shrink_forbidden = true;
 
-         this.FinishTextDrawing(null, yax_g);
+         this.FinishTextDrawing(yax_g);
       }
 
       var xAxisColor = this.histo['fXaxis']['fAxisColor'];
@@ -6764,7 +6768,7 @@
          pos_y = h/2;
       }
 
-      this.RecreateDrawG(use_pad, use_pad ? ".text_layer" : ".axis_layer");
+      this.RecreateDrawG(use_pad, use_pad ? ".text_layer" : ".upper_layer", true);
 
       var tcolor = JSROOT.Painter.root_colors[this.text['fTextColor']];
 

From 54817ead943887faa5799f27aa452333afeab091 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 12:24:48 +0100
Subject: [PATCH 146/200] Use the std::atomic load() method to access its
 content (fix compilation errors on Windows)

---
 core/meta/src/TIsAProxy.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index 44d57d98d0b80..cacc6d98e6382 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -84,12 +84,12 @@ TClass* TIsAProxy::operator()(const void *obj)
    // IsA callback
 
    if ( !fInit )  {
-      if ( !fClass && fType ) {
+      if ( !fClass.load() && fType ) {
          auto cls = TClass::GetClass(*fType);
          TClass* expected = nullptr;
          fClass.compare_exchange_strong(expected,cls);
       }
-      if ( !fClass) return nullptr;
+      if ( !fClass.load() ) return nullptr;
       fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
       fInit = kTRUE;
    }

From 56a9c6133a94c4a9782f906bc8465bfc04267b8d Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 12:27:58 +0100
Subject: [PATCH 147/200] Implement proper solutions for the thread_local issue
 on Windows

---
 core/meta/src/TStreamerElement.cxx | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/core/meta/src/TStreamerElement.cxx b/core/meta/src/TStreamerElement.cxx
index 198792fd62cca..1a8c66e6be366 100644
--- a/core/meta/src/TStreamerElement.cxx
+++ b/core/meta/src/TStreamerElement.cxx
@@ -39,15 +39,17 @@
 #include <string>
 namespace std {} using namespace std;
 
-#ifdef R__WIN32
-#define thread_local static
-#endif
-
 const Int_t kMaxLen = 1024;
 
 static TString &IncludeNameBuffer() {
+#ifdef R__WIN32
+   thread_local TString *includeNamePtr = 0;
+   if (!includeNamePtr) includeNamePtr = new TString(kMaxLen);
+   return *includeNamePtr;
+#else
    thread_local TString includeName(kMaxLen);
    return includeName;
+#endif
 }
 
 extern void *gMmallocDesc;
@@ -311,7 +313,13 @@ const char *TStreamerElement::GetFullName() const
    // Note that this function stores the name into a static array.
    // You should copy the result.
 
+#ifdef R__WIN32
+   thread_local TString *namePtr = 0;
+   if (!namePtr) namePtr = new TString(kMaxLen);
+   TString &name = *namePtr;
+#else
    thread_local TString name(kMaxLen);
+#endif
    char cdim[20];
    name = GetName();
    for (Int_t i=0;i<fArrayDim;i++) {

From cdf02c0c2076e0c707445866752a0f0d4233f7d3 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Thu, 5 Mar 2015 12:25:12 +0100
Subject: [PATCH 148/200] Fix for ROOT-7002 - Backtrace on MacOS X 10.10 broken
 / atos

---
 core/unix/src/TUnixSystem.cxx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/core/unix/src/TUnixSystem.cxx b/core/unix/src/TUnixSystem.cxx
index f12fce83140ef..1e20ba7ff18c1 100644
--- a/core/unix/src/TUnixSystem.cxx
+++ b/core/unix/src/TUnixSystem.cxx
@@ -2348,8 +2348,10 @@ void TUnixSystem::StackTrace()
                Bool_t nodebug = kTRUE;
 #ifdef R__MACOSX
                if (libaddr) { }  // use libaddr
-#if defined(MAC_OS_X_VERSION_10_9)
-               // suppress deprecation warning with option -d
+#if defined(MAC_OS_X_VERSION_10_10)
+               snprintf(buffer, sizeof(buffer), "%s -p %d 0x%016lx", addr2line, GetPid(), addr);
+#elif defined(MAC_OS_X_VERSION_10_9)
+               // suppress deprecation warning with opti
                snprintf(buffer, sizeof(buffer), "%s -d -p %d 0x%016lx", addr2line, GetPid(), addr);
 #else
                snprintf(buffer, sizeof(buffer), "%s -p %d 0x%016lx", addr2line, GetPid(), addr);

From 2fd192e1fc3408f2d073215f08e15bb1c2a41318 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Thu, 5 Mar 2015 14:15:13 +0100
Subject: [PATCH 149/200] Generate pictures for macros in ../doc/macros

---
 documentation/doxygen/filter.cxx | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index 7ef69b79cad21..dfaf0ece04874 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -70,6 +70,7 @@ TString gFileName;
 TString gLineString;
 TString gClassName;
 TString gImageName;
+TString gCwd;
 Bool_t  gHeader;
 Bool_t  gSource;
 Bool_t  gInClassDef;
@@ -95,6 +96,7 @@ int main(int argc, char *argv[])
    if (gFileName.EndsWith(".cxx")) gSource = kTRUE;
    if (gFileName.EndsWith(".h"))   gHeader = kTRUE;
    GetClassName();
+   gCwd = gFileName(0, gFileName.Last('/'));
 
    // Loop on file.
    FILE *f = fopen(gFileName.Data(),"r");
@@ -136,9 +138,13 @@ int main(int argc, char *argv[])
 
          if (gInMacro) {
             if (gInMacro == 1) {
-               if (gLineString.EndsWith(".C\n")) ExecuteMacro();
+               if (gLineString.EndsWith(".C\n")) {
+                  ExecuteMacro();
+                  gInMacro++;
+               } else {
+               }
+            } else {
             }
-            gInMacro++;
          }
 
          if (gLineString.Index("Begin_Macro") >= 0) {
@@ -198,6 +204,7 @@ void GetClassName()
    }
 
    fclose(f);
+
    return;
 }
 
@@ -227,10 +234,17 @@ void ExecuteMacro()
                                               , gImageID++);
 
    // Build the ROOT command to be executed.
-   gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
+   if (gLineString.Index("../../..") >= 0) {
+      gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
+   } else {
+      gLineString.Prepend(TString::Format("root -l -b -q \"makeimage.C(\\\"%s/../doc/macros/",gCwd.Data()));
+   }
    Int_t l = gLineString.Length();
-   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s/html/%s\\\")\"", gSystem->Getenv("OUTPUT_DIRECTORY")
-                                                                          , gImageName.Data()));
+   TString OutDir = gSystem->Getenv("OUTPUT_DIRECTORY");
+   OutDir.ReplaceAll("\"","");
+   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s/html/%s\\\")\"",
+                                             OutDir.Data(),
+                                             gImageName.Data()));
 
    ExecuteCommand(gLineString);
 

From a4e64073cbfd7fa8002befa5e9ba6d16b0cc6513 Mon Sep 17 00:00:00 2001
From: Christopher Jones <chrisdjones15@gmail.com>
Date: Thu, 21 Aug 2014 15:41:05 -0500
Subject: [PATCH 150/200] Make TMVA thread-safe with respect to use of Reader

It is now possible to create independent TMVA::Readers and use
them simultaneously on different threads.
Training of MVAs is still only safe single-threaded. In addition,
it is not safe to use multiple instances of MethodCFMlpANN either
single or multi-threaded because of a global 'this' pointer.

Danilo:
Properly take care of the deletion of some atomic pointers

Signed-off-by: Danilo Piparo <danilo.piparo@cern.ch>
---
 tmva/inc/TMVA/BDTEventWrapper.h      |   4 +
 tmva/inc/TMVA/BinaryTree.h           |   3 +-
 tmva/inc/TMVA/Config.h               |  19 +-
 tmva/inc/TMVA/DataSetFactory.h       |   8 +-
 tmva/inc/TMVA/DataSetManager.h       |   4 +-
 tmva/inc/TMVA/DecisionTreeNode.h     |   2 +-
 tmva/inc/TMVA/Interval.h             |   3 +-
 tmva/inc/TMVA/LogInterval.h          |   3 +-
 tmva/inc/TMVA/MethodBase.h           |   5 +-
 tmva/inc/TMVA/MethodCFMlpANN_Utils.h |  12 +-
 tmva/inc/TMVA/MethodPDERS.h          |   4 +
 tmva/inc/TMVA/ModulekNN.h            |   5 +-
 tmva/inc/TMVA/MsgLogger.h            |  20 +-
 tmva/inc/TMVA/Option.h               |  15 +-
 tmva/inc/TMVA/PDF.h                  |   4 +
 tmva/inc/TMVA/TNeuron.h              |   3 +-
 tmva/inc/TMVA/TSynapse.h             |   3 +-
 tmva/inc/TMVA/Tools.h                |   7 +
 tmva/inc/TMVA/Types.h                |   7 +
 tmva/src/BDTEventWrapper.cxx         |   4 +
 tmva/src/BinaryTree.cxx              |  13 +-
 tmva/src/Config.cxx                  |  20 ++
 tmva/src/DataSetManager.cxx          |  14 +-
 tmva/src/DecisionTreeNode.cxx        |  48 ++---
 tmva/src/Interval.cxx                |  14 +-
 tmva/src/LogInterval.cxx             |  99 +++++-----
 tmva/src/MethodANNBase.cxx           |  13 +-
 tmva/src/MethodBase.cxx              |   8 +
 tmva/src/MethodCFMlpANN_Utils.cxx    |  12 +-
 tmva/src/MethodMLP.cxx               |   5 +
 tmva/src/MethodPDERS.cxx             |   8 +
 tmva/src/MethodTMlpANN.cxx           |  11 +-
 tmva/src/ModulekNN.cxx               |   8 +
 tmva/src/MsgLogger.cxx               |  91 +++++----
 tmva/src/Option.cxx                  |  12 +-
 tmva/src/PDF.cxx                     |   4 +
 tmva/src/TNeuron.cxx                 |  14 +-
 tmva/src/TSynapse.cxx                |  26 ++-
 tmva/src/Tools.cxx                   | 273 +++++++++++++++------------
 tmva/src/Types.cxx                   |  69 +++++--
 40 files changed, 572 insertions(+), 325 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index 8a2ec791bcf72..cc3d0ae17814e 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -67,7 +67,11 @@ namespace TMVA {
     
    private:
 
+#if __cplusplus > 199711L
+      static thread_local Int_t fVarIndex;  // index of the variable to sort on
+#else
       static Int_t fVarIndex;  // index of the variable to sort on
+#endif
       const Event* fEvent;     // pointer to the event
     
       Double_t     fBkgWeight; // cumulative background weight for splitting
diff --git a/tmva/inc/TMVA/BinaryTree.h b/tmva/inc/TMVA/BinaryTree.h
index 81fe591789c4c..d76ed44a1214a 100644
--- a/tmva/inc/TMVA/BinaryTree.h
+++ b/tmva/inc/TMVA/BinaryTree.h
@@ -123,8 +123,7 @@ namespace TMVA {
       UInt_t     fNNodes;           // total number of nodes in the tree (counted)
       UInt_t     fDepth;            // maximal depth in tree reached
 
-      static MsgLogger* fgLogger;   // message logger, static to save resources    
-      MsgLogger& Log() const { return *fgLogger; }
+      MsgLogger& Log() const;
 
       ClassDef(BinaryTree,0) // Base class for BinarySearch and Decision Trees
    };  
diff --git a/tmva/inc/TMVA/Config.h b/tmva/inc/TMVA/Config.h
index 08e55ff89e47d..d8d56fa33bc90 100644
--- a/tmva/inc/TMVA/Config.h
+++ b/tmva/inc/TMVA/Config.h
@@ -36,7 +36,9 @@
 // Singleton class for global configuration settings used by TMVA       //
 //                                                                      //
 //////////////////////////////////////////////////////////////////////////
-
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
 #endif
@@ -103,16 +105,27 @@ namespace TMVA {
 
       // private constructor
       Config();
+      Config( const Config& );
+      Config& operator=( const Config&);
       virtual ~Config();
+#if __cplusplus > 199711L
+      static std::atomic<Config*> fgConfigPtr;
+#else
       static Config* fgConfigPtr;
-                  
+#endif                  
    private:
 
+#if __cplusplus > 199711L
+      std::atomic<Bool_t> fUseColoredConsole;     // coloured standard output
+      std::atomic<Bool_t> fSilent;                // no output at all
+      std::atomic<Bool_t> fWriteOptionsReference; // if set true: Configurable objects write file with option reference
+      std::atomic<Bool_t> fDrawProgressBar;       // draw progress bar to indicate training evolution
+#else
       Bool_t fUseColoredConsole;     // coloured standard output
       Bool_t fSilent;                // no output at all
       Bool_t fWriteOptionsReference; // if set true: Configurable objects write file with option reference
       Bool_t fDrawProgressBar;       // draw progress bar to indicate training evolution
-
+#endif
       mutable MsgLogger* fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }
          
diff --git a/tmva/inc/TMVA/DataSetFactory.h b/tmva/inc/TMVA/DataSetFactory.h
index bfd54f04830a1..de1d85fbc5496 100644
--- a/tmva/inc/TMVA/DataSetFactory.h
+++ b/tmva/inc/TMVA/DataSetFactory.h
@@ -254,6 +254,8 @@ namespace TMVA {
 
       DataSet* CreateDataSet( DataSetInfo &, DataInputHandler& );
 
+      static DataSetFactory* NewInstance() { return new DataSetFactory(); }
+      static void destroyNewInstance(DataSetFactory* iOther) { delete iOther;}
    protected:
 
       ~DataSetFactory();
@@ -314,8 +316,8 @@ namespace TMVA {
       Bool_t                     fScaleWithPreselEff; //! how to deal with requested #events in connection with preselection cuts 
 
       // the event
-      mutable TTree*             fCurrentTree;       //! the tree, events are currently read from
-      mutable UInt_t             fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
+      TTree*                     fCurrentTree;       //! the tree, events are currently read from
+      UInt_t                     fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
 
       // the formulas for reading the original tree
       std::vector<TTreeFormula*> fInputFormulas;   //! input variables
@@ -324,7 +326,7 @@ namespace TMVA {
       std::vector<TTreeFormula*> fWeightFormula;   //! weights
       std::vector<TTreeFormula*> fSpectatorFormulas; //! spectators
 
-      mutable MsgLogger*         fLogger;          //! message logger
+      MsgLogger*                 fLogger;          //! message logger
       MsgLogger& Log() const { return *fLogger; }
    };
 }
diff --git a/tmva/inc/TMVA/DataSetManager.h b/tmva/inc/TMVA/DataSetManager.h
index 864a5e5ab161b..6bef1c6d579b1 100644
--- a/tmva/inc/TMVA/DataSetManager.h
+++ b/tmva/inc/TMVA/DataSetManager.h
@@ -84,14 +84,14 @@ namespace TMVA {
 /*       DataSetManager(); */ // DSMTEST
 /*       DataSetManager( DataInputHandler& dataInput ); */ // DSMTEST
 
-// //      TMVA::DataSetFactory* fDatasetFactory; // DSMTEST
+      TMVA::DataSetFactory* fDatasetFactory;
 
       // access to input data
       DataInputHandler& DataInput() { return fDataInput; }
 
       DataInputHandler&          fDataInput;             //! source of input data
       TList                      fDataSetInfoCollection; //! all registered dataset definitions
-      mutable MsgLogger*         fLogger;   // message logger
+      MsgLogger*                 fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }    
    };
 }
diff --git a/tmva/inc/TMVA/DecisionTreeNode.h b/tmva/inc/TMVA/DecisionTreeNode.h
index 8e1935a42fe58..0b590ef79f41e 100644
--- a/tmva/inc/TMVA/DecisionTreeNode.h
+++ b/tmva/inc/TMVA/DecisionTreeNode.h
@@ -355,7 +355,7 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger* fgLogger;    // static because there is a huge number of nodes...
+      static MsgLogger& Log();
 
       std::vector<Double_t>       fFisherCoeff;    // the fisher coeff (offset at the last element)
 
diff --git a/tmva/inc/TMVA/Interval.h b/tmva/inc/TMVA/Interval.h
index c057bb883dc6e..b1afa1bf29a18 100644
--- a/tmva/inc/TMVA/Interval.h
+++ b/tmva/inc/TMVA/Interval.h
@@ -90,8 +90,7 @@ namespace TMVA {
       Int_t    fNbins;        // when >0 : number of bins (discrete interval); when ==0 continuous interval
 
    private:
-      static MsgLogger* fgLogger;   // message logger
-      MsgLogger& Log() const { return *fgLogger; }          
+      MsgLogger& Log() const;          
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/LogInterval.h b/tmva/inc/TMVA/LogInterval.h
index f251e81cd1c67..687705a8e6b47 100644
--- a/tmva/inc/TMVA/LogInterval.h
+++ b/tmva/inc/TMVA/LogInterval.h
@@ -105,8 +105,7 @@ namespace TMVA {
       void SetMax( Double_t m ) { fMax = m; }
       void SetMin( Double_t m ) { fMin = m; }
 
-      static MsgLogger* fgLogger;   // message logger
-      MsgLogger& Log() const { return *fgLogger; }          
+      MsgLogger& Log() const;
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 02bffb8ac9df5..8a1c2d28610b9 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -629,8 +629,11 @@ namespace TMVA {
    private:
 
       // this carrier
+#if __cplusplus > 199711L
+      static thread_local MethodBase* fgThisBase;         // this pointer
+#else
       static MethodBase* fgThisBase;         // this pointer
-
+#endif
 
       // ===== depreciated options, kept for backward compatibility  =====
    private:
diff --git a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
index 3d1fa1a1ae62c..d0f9ba4f08578 100644
--- a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
+++ b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
@@ -99,12 +99,12 @@ namespace TMVA {
 
    protected:
 
-      static Int_t       fg_100;          // constant
-      static Int_t       fg_0;            // constant
-      static Int_t       fg_max_nVar_;    // static maximum number of input variables
-      static Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
-      static Int_t       fg_999;          // constant
-      static const char* fg_MethodName;   // method name for print
+      static Int_t             fg_100;          // constant
+      static Int_t             fg_0;            // constant
+      static const Int_t       fg_max_nVar_;    // static maximum number of input variables
+      static const Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
+      static Int_t             fg_999;          // constant
+      static const char* const fg_MethodName;   // method name for print
 
       Double_t W_ref(const Double_t wNN[], Int_t a_1, Int_t a_2, Int_t a_3) const {
          return wNN [(a_3*max_nNodes_ + a_2)*max_nLayers_ + a_1 - 187];
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index 3ae5d497451eb..9d1a4f7bd1e61 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -220,7 +220,11 @@ namespace TMVA {
                                  Float_t sumW2S, Float_t sumW2B ) const;
 
       // this carrier
+#if __cplusplus > 199711L
+      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+#else
       static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+#endif
       void UpdateThis();
 
       void Init( void );
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index 1851491e408f5..569ee5e80b46c 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -148,8 +148,11 @@ namespace TMVA {
 
       private:
 
+#if __cplusplus > 199711L
+         static thread_local TRandom3 fgRndm;
+#else
          static TRandom3 fgRndm;
-
+#endif
          UInt_t fDimn;
 
          Node<Event> *fTree;
diff --git a/tmva/inc/TMVA/MsgLogger.h b/tmva/inc/TMVA/MsgLogger.h
index d93e3f6c00469..44505dd03d50f 100644
--- a/tmva/inc/TMVA/MsgLogger.h
+++ b/tmva/inc/TMVA/MsgLogger.h
@@ -43,6 +43,9 @@
 #include <sstream>
 #include <iostream>
 #include <map>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 // ROOT include(s)
 #ifndef ROOT_TObject
@@ -75,7 +78,7 @@ namespace TMVA {
       std::string GetPrintedSource()   const;
       std::string GetFormattedSource() const;
 
-      static UInt_t GetMaxSourceSize()                    { return (UInt_t)fgMaxSourceSize; }
+      static UInt_t GetMaxSourceSize()                    { return (const UInt_t)fgMaxSourceSize; }
 
       // Needed for copying
       MsgLogger& operator= ( const MsgLogger& parent );
@@ -113,13 +116,20 @@ namespace TMVA {
       static const std::string fgPrefix;          // the prefix of the source name
       static const std::string fgSuffix;          // suffix following source name
       EMsgType                 fActiveType;       // active type
-      static UInt_t            fgMaxSourceSize;   // maximum length of source name
+      static const UInt_t      fgMaxSourceSize;   // maximum length of source name
+#if __cplusplus > 199711L
+      static std::atomic<Bool_t> fgOutputSupressed; // disable the output globaly (used by generic booster)
+      static std::atomic<Bool_t> fgInhibitOutput;   // flag to suppress all output
+
+      static std::atomic<const std::map<EMsgType, std::string>*> fgTypeMap;   // matches output types with strings
+      static std::atomic<const std::map<EMsgType, std::string>*> fgColorMap;  // matches output types with terminal colors
+#else
       static Bool_t            fgOutputSupressed; // disable the output globaly (used by generic booster)
       static Bool_t            fgInhibitOutput;   // flag to suppress all output
-      static Int_t             fgInstanceCounter; // counts open MsgLogger instances
 
-      static std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
-      static std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
+      static const std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
+      static const std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
+#endif
       EMsgType                                fMinType;    // minimum type for output
 
       ClassDef(MsgLogger,0) // Ostringstream derivative to redirect and format logging output
diff --git a/tmva/inc/TMVA/Option.h b/tmva/inc/TMVA/Option.h
index 458b3acb8ac1a..4a0d80e8b41eb 100644
--- a/tmva/inc/TMVA/Option.h
+++ b/tmva/inc/TMVA/Option.h
@@ -93,8 +93,7 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger* fgLogger;  // message logger
-
+      static MsgLogger& Log();
    };
       
    // ---------------------------------------------------------------------------
@@ -249,16 +248,16 @@ namespace TMVA {
    inline void TMVA::Option<Bool_t>::AddPreDefVal( const Bool_t& ) 
    {
       // template specialization for Bool_t 
-      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
-                << Endl;
+      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
+	    << Endl;
    }
 
    template<>
    inline void TMVA::Option<Float_t>::AddPreDefVal( const Float_t& ) 
    {
       // template specialization for Float_t 
-      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
-                << Endl;
+      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
+	    << Endl;
    }
 
    template<class T>
@@ -358,8 +357,8 @@ namespace TMVA {
          this->Value() = false;
       }
       else {
-         *fgLogger << kFATAL << "<SetValueLocal> value \'" << val 
-                   << "\' can not be interpreted as boolean" << Endl;
+         Log() << kFATAL << "<SetValueLocal> value \'" << val 
+	       << "\' can not be interpreted as boolean" << Endl;
       }
    }
 }
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index 9962198ec37d8..e6387c99b496d 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -205,7 +205,11 @@ namespace TMVA {
       MsgLogger&               Log() const { return *fLogger; }    
 
       // static pointer to this object
+#if __cplusplus > 199711L
+      static thread_local PDF* fgThisPDF;             // this PDF pointer 
+#else
       static PDF*              fgThisPDF;             // this PDF pointer 
+#endif
       static PDF*              ThisPDF( void ); 
 
       // external auxiliary functions 
diff --git a/tmva/inc/TMVA/TNeuron.h b/tmva/inc/TMVA/TNeuron.h
index 101b1413319e8..eff915cfbc569 100644
--- a/tmva/inc/TMVA/TNeuron.h
+++ b/tmva/inc/TMVA/TNeuron.h
@@ -163,8 +163,7 @@ namespace TMVA {
       TActivation*  fActivation;              // activation equation
       TNeuronInput* fInputCalculator;         // input calculator
 
-      static MsgLogger* fgLogger;                     //! message logger, static to save resources
-      MsgLogger& Log() const { return *fgLogger; }                       
+      MsgLogger& Log() const;
 
       ClassDef(TNeuron,0) // Neuron class used by MethodANNBase derivative ANNs
    };
diff --git a/tmva/inc/TMVA/TSynapse.h b/tmva/inc/TMVA/TSynapse.h
index 66107687d25c5..d8bf444c30d7d 100644
--- a/tmva/inc/TMVA/TSynapse.h
+++ b/tmva/inc/TMVA/TSynapse.h
@@ -102,8 +102,7 @@ namespace TMVA {
       TNeuron* fPreNeuron;         // pointer to pre-neuron
       TNeuron* fPostNeuron;        // pointer to post-neuron
 
-      static MsgLogger* fgLogger;                     //! message logger, static to save resources
-      MsgLogger& Log() const { return *fgLogger; }                       
+      MsgLogger& Log() const;
 
       ClassDef(TSynapse,0) // Synapse class used by MethodANNBase and derivatives
    };
diff --git a/tmva/inc/TMVA/Tools.h b/tmva/inc/TMVA/Tools.h
index 011196cd3e0eb..cb6d51722a280 100644
--- a/tmva/inc/TMVA/Tools.h
+++ b/tmva/inc/TMVA/Tools.h
@@ -41,6 +41,9 @@
 #include <sstream>
 #include <iostream>
 #include <iomanip>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #ifndef ROOT_TXMLEngine
 #include "TXMLEngine.h"
@@ -238,7 +241,11 @@ namespace TMVA {
       const TString fRegexp;
       mutable MsgLogger*    fLogger;
       MsgLogger& Log() const { return *fLogger; }
+#if __cplusplus > 199711L
+      static std::atomic<Tools*> fgTools;
+#else
       static Tools* fgTools;
+#endif
 
       // xml tools
 
diff --git a/tmva/inc/TMVA/Types.h b/tmva/inc/TMVA/Types.h
index cb5f45ce67039..e245cf0c2abf4 100644
--- a/tmva/inc/TMVA/Types.h
+++ b/tmva/inc/TMVA/Types.h
@@ -38,6 +38,9 @@
 //////////////////////////////////////////////////////////////////////////
 
 #include <map>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
@@ -154,7 +157,11 @@ namespace TMVA {
    private:
 
       Types();
+#if __cplusplus > 199711L
+      static std::atomic<Types*> fgTypesPtr;
+#else
       static Types* fgTypesPtr;
+#endif
 
    private:
 
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index c7429e0bcb13b..0820339c01c41 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -26,7 +26,11 @@
 
 using namespace TMVA;
 
+#if __cplusplus > 199711L
+thread_local Int_t BDTEventWrapper::fVarIndex = 0;
+#else
 Int_t BDTEventWrapper::fVarIndex = 0;
+#endif
 
 BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
    // constuctor
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index 4b3b7d2d5e27b..dca177c92dbd2 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -46,8 +46,6 @@
 
 ClassImp(TMVA::BinaryTree)
 
-TMVA::MsgLogger* TMVA::BinaryTree::fgLogger = 0;
-
 //_______________________________________________________________________
 TMVA::BinaryTree::BinaryTree( void )
    : fRoot  ( NULL ),
@@ -55,7 +53,6 @@ TMVA::BinaryTree::BinaryTree( void )
      fDepth ( 0 )
 {
    // constructor for a yet "empty" tree. Needs to be filled afterwards
-   if (!fgLogger) fgLogger =  new MsgLogger("BinaryTree");
 }
 
 //_______________________________________________________________________
@@ -221,3 +218,13 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 
    return;
 }
+
+//_______________________________________________________________________
+TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("BinaryTree");
+#else
+  static MsgLogger logger("BinaryTree");
+#endif
+  return logger;
+}
diff --git a/tmva/src/Config.cxx b/tmva/src/Config.cxx
index de124def90151..6dd287a9c51d1 100644
--- a/tmva/src/Config.cxx
+++ b/tmva/src/Config.cxx
@@ -31,7 +31,11 @@
 
 ClassImp(TMVA::Config)
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Config*> TMVA::Config::fgConfigPtr{ 0 };
+#else
 TMVA::Config* TMVA::Config::fgConfigPtr = 0;
+#endif
 
 TMVA::Config& TMVA::gConfig() { return TMVA::Config::Instance(); }
 
@@ -71,13 +75,29 @@ TMVA::Config::~Config()
 void TMVA::Config::DestroyInstance()
 {
    // static function: destroy TMVA instance
+#if __cplusplus > 199711L
+  delete fgConfigPtr.exchange(0);
+#else
    if (fgConfigPtr != 0) { delete fgConfigPtr; fgConfigPtr = 0;}
+#endif
 }
 
 //_______________________________________________________________________
 TMVA::Config& TMVA::Config::Instance()
 {
    // static function: returns  TMVA instance
+#if __cplusplus > 199711L
+  if(!fgConfigPtr) {
+    TMVA::Config* tmp = new Config();
+    TMVA::Config* expected = 0;
+    if(! fgConfigPtr.compare_exchange_strong(expected,tmp) ) {
+      //another thread beat us to the switch
+      delete tmp;
+    }
+  }
+  return *fgConfigPtr;
+#else
    return fgConfigPtr ? *fgConfigPtr :*(fgConfigPtr = new Config());
+#endif
 }
 
diff --git a/tmva/src/DataSetManager.cxx b/tmva/src/DataSetManager.cxx
index 63c81e0ea142d..9ed04df3ee4d0 100644
--- a/tmva/src/DataSetManager.cxx
+++ b/tmva/src/DataSetManager.cxx
@@ -52,7 +52,8 @@ using std::endl;
 
 //_______________________________________________________________________
 TMVA::DataSetManager::DataSetManager( DataInputHandler& dataInput )
-   : fDataInput(dataInput),
+   : fDatasetFactory(0),
+     fDataInput(dataInput),
      fDataSetInfoCollection(),
      fLogger( new MsgLogger("DataSetManager", kINFO) )
 {
@@ -65,8 +66,8 @@ TMVA::DataSetManager::~DataSetManager()
    // destructor
 //   fDataSetInfoCollection.SetOwner(); // DSMTEST --> created a segfault because the DataSetInfo-objects got deleted twice
 
-   TMVA::DataSetFactory::destroyInstance();
-   
+   DataSetFactory::destroyNewInstance(fDatasetFactory);
+
    delete fLogger;
 }
 
@@ -78,18 +79,19 @@ TMVA::DataSet* TMVA::DataSetManager::CreateDataSet( const TString& dsiName )
    if (!dsi) Log() << kFATAL << "DataSetInfo object '" << dsiName << "' not found" << Endl;
 
    // factory to create dataset from datasetinfo and datainput
-   return TMVA::DataSetFactory::Instance().CreateDataSet( *dsi, fDataInput );
+   if(!fDatasetFactory) { fDatasetFactory = DataSetFactory::NewInstance(); }
+   return fDatasetFactory->CreateDataSet( *dsi, fDataInput );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName) 
+TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName)
 {
    // returns datasetinfo object for given name
    return (DataSetInfo*)fDataSetInfoCollection.FindObject( dsiName );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi) 
+TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi)
 {
    // stores a copy of the dataset info object
 
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index 235ebeb396948..37425a83b94f7 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -50,7 +50,6 @@ using std::string;
 
 ClassImp(TMVA::DecisionTreeNode)
 
-TMVA::MsgLogger* TMVA::DecisionTreeNode::fgLogger = 0;
 bool     TMVA::DecisionTreeNode::fgIsTraining = false;
 UInt_t   TMVA::DecisionTreeNode::fgTmva_Version_Code = 0;
 //_______________________________________________________________________
@@ -66,8 +65,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode()
      fIsTerminalNode( kFALSE )
 {
    // constructor of an essentially "empty" node floating in space
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -91,8 +88,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode(TMVA::Node* p, char pos)
      fIsTerminalNode( kFALSE )
 {
    // constructor of a daughter node as a daughter of 'p'
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -118,8 +113,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode(const TMVA::DecisionTreeNode &n,
 {
    // copy constructor of a node. It will result in an explicit copy of
    // the node and recursively all it's daughters
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    this->SetParent( parent );
    if (n.GetLeft() == 0 ) this->SetLeft(NULL);
    else this->SetLeft( new DecisionTreeNode( *((DecisionTreeNode*)(n.GetLeft())),this));
@@ -151,11 +144,11 @@ Bool_t TMVA::DecisionTreeNode::GoesRight(const TMVA::Event & e) const
    Bool_t result;
    // first check if the fisher criterium is used or ordinary cuts:
    if (GetNFisherCoeff() == 0){
-      
+
       result = (e.GetValue(this->GetSelector()) >= this->GetCutValue() );
 
    }else{
-      
+
       Double_t fisher = this->GetFisherCoeff(fFisherCoeff.size()-1); // the offset
       for (UInt_t ivar=0; ivar<fFisherCoeff.size()-1; ivar++)
          fisher += this->GetFisherCoeff(ivar)*(e.GetValue(ivar));
@@ -187,8 +180,8 @@ void TMVA::DecisionTreeNode::SetPurity( void )
       fPurity = this->GetNSigEvents() / ( this->GetNSigEvents() + this->GetNBkgEvents());
    }
    else {
-      *fgLogger << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
-      this->Print(*fgLogger);
+      Log() << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
+      this->Print(Log());
       fPurity = 0.5;
    }
    return;
@@ -205,7 +198,7 @@ void TMVA::DecisionTreeNode::Print(std::ostream& os) const
       << "NCoef: "  << this->GetNFisherCoeff();
    for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) { os << "fC"<<i<<": " << this->GetFisherCoeff(i);}
    os << " ivar: "  << this->GetSelector()
-      << " cut: "   << this->GetCutValue() 
+      << " cut: "   << this->GetCutValue()
       << " cType: " << this->GetCutType()
       << " s: "     << this->GetNSigEvents()
       << " b: "     << this->GetNBkgEvents()
@@ -390,7 +383,7 @@ void TMVA::DecisionTreeNode::PrintRecPrune( std::ostream& os ) const {
 void TMVA::DecisionTreeNode::SetCC(Double_t cc)
 {
    if (fTrainInfo) fTrainInfo->fCC = cc;
-   else *fgLogger << kFATAL << "call to SetCC without trainingInfo" << Endl;
+   else Log() << kFATAL << "call to SetCC without trainingInfo" << Endl;
 }
 
 //_______________________________________________________________________
@@ -398,8 +391,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMin(UInt_t ivar) const {
    // return the minimum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMin[ivar];
-   else *fgLogger << kFATAL << "You asked for Min of the event sample in node for variable "
-                  << ivar << " that is out of range" << Endl;
+   else Log() << kFATAL << "You asked for Min of the event sample in node for variable "
+              << ivar << " that is out of range" << Endl;
    return -9999;
 }
 
@@ -408,8 +401,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMax(UInt_t ivar) const {
    // return the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMax[ivar];
-   else *fgLogger << kFATAL << "You asked for Max of the event sample in node for variable "
-                  << ivar << " that is out of range" << Endl;
+   else Log() << kFATAL << "You asked for Max of the event sample in node for variable "
+              << ivar << " that is out of range" << Endl;
    return 9999;
 }
 
@@ -428,7 +421,7 @@ void TMVA::DecisionTreeNode::SetSampleMax(UInt_t ivar, Float_t xmax){
    // set the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if( ! fTrainInfo ) return;
-   if ( ivar >= fTrainInfo->fSampleMax.size() ) 
+   if ( ivar >= fTrainInfo->fSampleMax.size() )
       fTrainInfo->fSampleMax.resize(ivar+1);
    fTrainInfo->fSampleMax[ivar]=xmax;
 }
@@ -452,10 +445,10 @@ void TMVA::DecisionTreeNode::ReadAttributes(void* node, UInt_t /* tmva_Version_C
    }
    gTools().ReadAttr(node, "IVar",  fSelector               );
    gTools().ReadAttr(node, "Cut",   fCutValue               );
-   gTools().ReadAttr(node, "cType", fCutType                );               
+   gTools().ReadAttr(node, "cType", fCutType                );
    if (gTools().HasAttr(node,"res")) gTools().ReadAttr(node, "res",   fResponse);
    if (gTools().HasAttr(node,"rms")) gTools().ReadAttr(node, "rms",   fRMS);
-   //   else { 
+   //   else {
    if( gTools().HasAttr(node, "purity") ) {
       gTools().ReadAttr(node, "purity",fPurity );
    } else {
@@ -473,7 +466,7 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 {
    // add attribute to xml
    gTools().AddAttr(node, "NCoef", GetNFisherCoeff());
-   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) 
+   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++)
       gTools().AddAttr(node, Form("fC%d",i),  this->GetFisherCoeff(i));
 
    gTools().AddAttr(node, "IVar",  GetSelector());
@@ -494,8 +487,8 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 void  TMVA::DecisionTreeNode::SetFisherCoeff(Int_t ivar, Double_t coeff)
 {
    // set fisher coefficients
-   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ; 
-   fFisherCoeff[ivar]=coeff;      
+   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ;
+   fFisherCoeff[ivar]=coeff;
 }
 
 //_______________________________________________________________________
@@ -513,3 +506,12 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
    // and somehow I guess someone programmed it such that we need this in
    // this tree too, although we don't..)
 }
+//_______________________________________________________________________
+TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+#else
+  static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+#endif
+  return logger;
+}
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index e37ac0ac02c5f..d89b023679f49 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -75,16 +75,12 @@ End_Html */
 
 ClassImp(TMVA::Interval)
 
-TMVA::MsgLogger* TMVA::Interval::fgLogger = 0;
-
 //_______________________________________________________________________
 TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
    fMin(min),
    fMax(max),
    fNbins(nbins)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("Interval");
-
    // defines minimum and maximum of an interval
    // when nbins > 0, interval describes a discrete distribution (equally distributed in the interval)
    // when nbins == 0, interval describes a continous interval
@@ -105,7 +101,6 @@ TMVA::Interval::Interval( const Interval& other ) :
    fMax  ( other.fMax ),
    fNbins( other.fNbins )
 {
-   if (!fgLogger) fgLogger = new MsgLogger("Interval");
 }
 
 //_______________________________________________________________________
@@ -168,3 +163,12 @@ void TMVA::Interval::Print(std::ostream &os) const
       os << "| " << GetElement(i)<<" |" ;
    }  
 }
+
+TMVA::MsgLogger& TMVA::Interval::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("Interval");   // message logger
+#else
+  static MsgLogger logger("Interval");   // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 6bdbb1c0c20c3..922ae5ace5991 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -13,8 +13,8 @@
  *      Helge Voss <helge.voss@cern.ch>  - MPI-K Heidelberg, Germany              *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      MPI-K Heidelberg, Germany                                                 *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -35,39 +35,39 @@
    </ul>
 </ul>
 <pre>
-    Example:             
- LogInterval(1,10000,5)                                          
-     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!  
-     i=1 --> 10                    StepSize(ibin=1) = 9              
-     i=2 --> 100                   StepSize(ibin=2) = 99                         
-     i=3 --> 1000                  StepSize(ibin=3) = 999                     
-     i=4 --> 10000                 StepSize(ibin=4) = 9999                 
-                                                
- LogInterval(1,1000,11)                     
-    i=0 --> 1                           
-    i=1 --> 1.99526                 
-    i=2 --> 3.98107             
-    i=3 --> 7.94328         
-    i=4 --> 15.8489      
-    i=5 --> 31.6228      
-    i=6 --> 63.0957      
-    i=7 --> 125.893      
-    i=8 --> 251.189      
-    i=9 --> 501.187      
-    i=10 --> 1000        
-                         
- LogInterval(1,1024,11)  
-    i=0 --> 1            
-    i=1 --> 2            
-    i=2 --> 4            
-    i=3 --> 8            
-    i=4 --> 16           
-    i=5 --> 32           
-    i=6 --> 64           
-    i=7 --> 128          
-    i=8 --> 256          
-    i=9 --> 512          
-    i=10 --> 1024        
+    Example:
+ LogInterval(1,10000,5)
+     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!
+     i=1 --> 10                    StepSize(ibin=1) = 9
+     i=2 --> 100                   StepSize(ibin=2) = 99
+     i=3 --> 1000                  StepSize(ibin=3) = 999
+     i=4 --> 10000                 StepSize(ibin=4) = 9999
+
+ LogInterval(1,1000,11)
+    i=0 --> 1
+    i=1 --> 1.99526
+    i=2 --> 3.98107
+    i=3 --> 7.94328
+    i=4 --> 15.8489
+    i=5 --> 31.6228
+    i=6 --> 63.0957
+    i=7 --> 125.893
+    i=8 --> 251.189
+    i=9 --> 501.187
+    i=10 --> 1000
+
+ LogInterval(1,1024,11)
+    i=0 --> 1
+    i=1 --> 2
+    i=2 --> 4
+    i=3 --> 8
+    i=4 --> 16
+    i=5 --> 32
+    i=6 --> 64
+    i=7 --> 128
+    i=8 --> 256
+    i=9 --> 512
+    i=10 --> 1024
 
 
 </pre>
@@ -81,19 +81,16 @@ End_Html */
 
 ClassImp(TMVA::LogInterval)
 
-TMVA::MsgLogger* TMVA::LogInterval::fgLogger = 0;
 //_______________________________________________________________________
 TMVA::LogInterval::LogInterval( Double_t min, Double_t max, Int_t nbins ) :
 TMVA::Interval(min,max,nbins)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
    if (min<=0) Log() << kFATAL << "logarithmic intervals have to have Min>0 !!" << Endl;
 }
 
 TMVA::LogInterval::LogInterval( const LogInterval& other ) :
    TMVA::Interval(other)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
 }
 
 //_______________________________________________________________________
@@ -105,9 +102,9 @@ TMVA::LogInterval::~LogInterval()
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval. 
+   // calculates the value of the "number" bin in a discrete interval.
    // Parameters:
-   //        Double_t position 
+   //        Double_t position
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
@@ -123,7 +120,7 @@ Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete LogInterval" 
+   // retuns the step size between the numbers of a "discrete LogInterval"
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
    }
@@ -141,12 +138,20 @@ Double_t TMVA::LogInterval::GetRndm( TRandom3& rnd )  const
    return TMath::Exp(rnd.Rndm()*(TMath::Log(fMax/fMin) - TMath::Log(fMin)) + TMath::Log(fMin));
 }
 
-Double_t TMVA::LogInterval::GetWidth() const 
-{ 
-   return fMax - fMin; 
+Double_t TMVA::LogInterval::GetWidth() const
+{
+   return fMax - fMin;
 }
-Double_t TMVA::LogInterval::GetMean()  const 
-{ 
-   return (fMax + fMin)/2; 
+Double_t TMVA::LogInterval::GetMean()  const
+{
+   return (fMax + fMin)/2;
 }
 
+TMVA::MsgLogger& TMVA::LogInterval::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("LogInterval");   // message logger
+#else
+  static MsgLogger logger("LogInterval");   // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/MethodANNBase.cxx b/tmva/src/MethodANNBase.cxx
index 0cc220816b585..ede12dc7d443b 100644
--- a/tmva/src/MethodANNBase.cxx
+++ b/tmva/src/MethodANNBase.cxx
@@ -40,6 +40,9 @@
 #include <vector>
 #include <cstdlib>
 #include <stdexcept>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #include "TString.h"
 #include "TTree.h"
@@ -980,13 +983,17 @@ void TMVA::MethodANNBase::WriteMonitoringHistosToFile() const
    CreateWeightMonitoringHists( "weights_hist" );
 
    // now save all the epoch-wise monitoring information
+#if __cplusplus > 199711L
+   static std::atomic<int> epochMonitoringDirectoryNumber{0};
+#else
    static int epochMonitoringDirectoryNumber = 0;
+#endif
+   int epochVal = epochMonitoringDirectoryNumber++;
    TDirectory* epochdir = NULL;
-   if( epochMonitoringDirectoryNumber == 0 )
+   if( epochVal == 0 )
       epochdir = BaseDir()->mkdir( "EpochMonitoring" );
    else
-      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochMonitoringDirectoryNumber) );
-   ++epochMonitoringDirectoryNumber;
+      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochVal) );
 
    epochdir->cd();
    for (std::vector<TH1*>::const_iterator it = fEpochMonHistS.begin(); it != fEpochMonHistS.end(); it++) {
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index 99589d559eea2..71b7af726cd1a 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -2171,7 +2171,11 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmin = effhist->GetXaxis()->GetXmin();
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
+#if __cplusplus > 199711L
+   static thread_local Double_t nevtS;
+#else
    static Double_t nevtS;
+#endif
 
    // first round ? --> create histograms
    if (results->DoesExist("MVA_EFF_S")==0) {
@@ -3085,7 +3089,11 @@ void TMVA::MethodBase::PrintHelpMessage() const
 
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
+#if __cplusplus > 199711L
+thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
+#else
 TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
+#endif
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::IGetEffForRoot( Double_t theCut )
diff --git a/tmva/src/MethodCFMlpANN_Utils.cxx b/tmva/src/MethodCFMlpANN_Utils.cxx
index c35521acc8055..ecbdafb7b5eb4 100644
--- a/tmva/src/MethodCFMlpANN_Utils.cxx
+++ b/tmva/src/MethodCFMlpANN_Utils.cxx
@@ -72,12 +72,12 @@ using std::endl;
 
 ClassImp(TMVA::MethodCFMlpANN_Utils)
    
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
-const char* TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
+const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
+const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
+const char* const TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
 
 TMVA::MethodCFMlpANN_Utils::MethodCFMlpANN_Utils()
 {
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 18797d2025370..9e4f58143e1b5 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -1583,8 +1583,13 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
    ((MethodMLP*)GetThisPtr())->FCN( npars, grad, f, fitPars, iflag );
 }
 
+#if __cplusplus > 199711L
+static thread_local Int_t  nc   = 0;
+static thread_local double minf = 1000000;
+#else
 static Int_t  nc   = 0;
 static double minf = 1000000;
+#endif
 
 void TMVA::MethodMLP::FCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t* fitPars, Int_t iflag )
 {
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 368b769728068..96d03cc58b61f 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -87,7 +87,11 @@ namespace TMVA {
    const Bool_t MethodPDERS_UseFindRoot = kFALSE;
 };
 
+#if __cplusplus > 199711L
+thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
+#else
 TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
+#endif
 
 REGISTER_METHOD(PDERS)
 
@@ -953,7 +957,11 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 
    // Caching jammed to disable function. 
    // It's not really useful afterall, badly implemented and untested :-)
+#if __cplusplus > 199711L
+   static thread_local Double_t ret = 1.0; 
+#else
    static Double_t ret = 1.0; 
+#endif
    
    if (ret != 0.0) return ret*pdf; 
 
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index 7027d4658c6a4..e6ee4baca6918 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -223,7 +223,11 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
 {
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
+#if __cplusplus > 199711L
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
+#else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
+#endif
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
       d[ivar] = (Double_t)ev->GetValue(ivar);
    }
@@ -412,8 +416,13 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
 
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
+#if __cplusplus > 199711L
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
+   static thread_local Int_t type;
+#else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
+#endif
 
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -442,7 +451,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
    Double_t* d = new Double_t[Data()->GetNVariables()] ; 
-   static Int_t type;
+   Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index 0018a579bc104..2160b5dfee708 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -153,7 +153,11 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
 
 
 
+#if __cplusplus > 199711L
+thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
+#else
 TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
+#endif
 
 //-------------------------------------------------------------------------------------------
 TMVA::kNN::ModulekNN::ModulekNN()
@@ -378,7 +382,11 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       return kFALSE;
    }
    
+#if __cplusplus > 199711L
+   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+#else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+#endif
 
    if (cit == fCount.end()) {
       cit = fCount.begin();
diff --git a/tmva/src/MsgLogger.cxx b/tmva/src/MsgLogger.cxx
index 5db9cfd190c93..86093c0189a53 100644
--- a/tmva/src/MsgLogger.cxx
+++ b/tmva/src/MsgLogger.cxx
@@ -40,20 +40,30 @@
 
 #include <assert.h>
 
+#include <memory>
+
 // ROOT include(s):
 
 ClassImp(TMVA::MsgLogger)
 
 // declaration of global variables
 // this is the hard-coded maximum length of the source names
-UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
-Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;
+const UInt_t                           TMVA::MsgLogger::fgMaxSourceSize = 25;
 
 const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
 const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
-std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
-std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
-Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;
+#if __cplusplus > 199711L
+std::atomic<Bool_t>                                       TMVA::MsgLogger::fgInhibitOutput{kFALSE};
+std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgTypeMap{0};
+std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgColorMap{0};
+#else
+Bool_t                                       TMVA::MsgLogger::fgInhibitOutput = kFALSE;
+const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
+const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
+#endif
+static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnTypeMap;
+static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnColorMap;
+ 
 
 void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
 void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
@@ -65,7 +75,6 @@ TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();   
 }
 
@@ -77,7 +86,6 @@ TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -89,7 +97,6 @@ TMVA::MsgLogger::MsgLogger( EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -101,7 +108,6 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
      fObjSource(0)
 {
    // copy constructor
-   fgInstanceCounter++;
    InitMaps();
    *this = parent;
 }
@@ -110,12 +116,6 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
 TMVA::MsgLogger::~MsgLogger()
 {
    // destructor
-   fgInstanceCounter--;
-   if (fgInstanceCounter == 0) {
-      // last MsgLogger instance has been deleted, can also delete the maps
-      delete fgTypeMap;  fgTypeMap  = 0;
-      delete fgColorMap; fgColorMap = 0;
-   }
 }
 
 //_______________________________________________________________________
@@ -202,14 +202,14 @@ void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
 
    std::map<EMsgType, std::string>::const_iterator stype;
 
-   if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
+   if ((stype = fgTypeMap.load()->find( type )) != fgTypeMap.load()->end()) {
       if (!gConfig().IsSilent() || type==kFATAL) {
          if (gConfig().UseColor()) {
             // no text for INFO or VERBOSE
             if (type == kINFO || type == kVERBOSE)
                std::cout << fgPrefix << line << std::endl; // no color for info
             else
-               std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
+ 	       std::cout << fgColorMap.load()->find( type )->second << fgPrefix << "<"
                          << stype->second << "> " << line  << "\033[0m" << std::endl;
          }
          else {
@@ -239,24 +239,45 @@ TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
 void TMVA::MsgLogger::InitMaps()
 {
    // Create the message type and color maps
-   if (fgTypeMap != 0 && fgColorMap != 0) return;
 
-   fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
-   fgColorMap = new std::map<TMVA::EMsgType, std::string>();
+   if(!fgTypeMap) {
+     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
    
-   (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
-   (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
-   (*fgTypeMap)[kINFO]     = std::string("INFO");
-   (*fgTypeMap)[kWARNING]  = std::string("WARNING");
-   (*fgTypeMap)[kERROR]    = std::string("ERROR");
-   (*fgTypeMap)[kFATAL]    = std::string("FATAL");
-   (*fgTypeMap)[kSILENT]   = std::string("SILENT");
-
-   (*fgColorMap)[kVERBOSE] = std::string("");
-   (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
-   (*fgColorMap)[kINFO]    = std::string("");
-   (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
-   (*fgColorMap)[kERROR]   = std::string("\033[31m");
-   (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
-   (*fgColorMap)[kSILENT]  = std::string("\033[30m");
+     (*tmp)[kVERBOSE]  = std::string("VERBOSE");
+     (*tmp)[kDEBUG]    = std::string("DEBUG");
+     (*tmp)[kINFO]     = std::string("INFO");
+     (*tmp)[kWARNING]  = std::string("WARNING");
+     (*tmp)[kERROR]    = std::string("ERROR");
+     (*tmp)[kFATAL]    = std::string("FATAL");
+     (*tmp)[kSILENT]   = std::string("SILENT");
+     const std::map<TMVA::EMsgType, std::string>* expected=0;
+     if(fgTypeMap.compare_exchange_strong(expected,tmp)) {
+       //Have the global own this
+       gOwnTypeMap.reset(tmp);
+     } else {
+       //Another thread beat us in creating the instance
+       delete tmp;
+     }
+   }
+
+   if(!fgColorMap) {
+     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
+
+     (*tmp)[kVERBOSE] = std::string("");
+     (*tmp)[kDEBUG]   = std::string("\033[34m");
+     (*tmp)[kINFO]    = std::string("");
+     (*tmp)[kWARNING] = std::string("\033[1;31m");
+     (*tmp)[kERROR]   = std::string("\033[31m");
+     (*tmp)[kFATAL]   = std::string("\033[37;41;1m");
+     (*tmp)[kSILENT]  = std::string("\033[30m");
+
+     const std::map<TMVA::EMsgType, std::string>* expected=0;
+     if(fgColorMap.compare_exchange_strong(expected,tmp)) {
+       //Have the global own this
+       gOwnColorMap.reset(tmp);
+     } else {
+       //Another thread beat us in creating the instance
+       delete tmp;
+     }
+   }
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index b56c920e516a6..8f6bbf3d68e40 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -28,8 +28,6 @@
 
 #include "TMVA/Option.h"
 
-TMVA::MsgLogger* TMVA::OptionBase::fgLogger = 0;
-
 //______________________________________________________________________
 TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
    : TObject(), 
@@ -39,7 +37,6 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
      fIsSet       ( kFALSE )
 {
    // constructor
-   if (!fgLogger) fgLogger = new MsgLogger("Option",kDEBUG);
    fNameAllLower.ToLower();
 }
 
@@ -52,3 +49,12 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
    return kTRUE;
 }
 
+TMVA::MsgLogger& TMVA::OptionBase::Log()
+{
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
+#else
+  static MsgLogger logger("Option",kDEBUG);  // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 3495c4d369f26..875ca43f4b04b 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -49,7 +49,11 @@
 const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
+#if __cplusplus > 199711L
+thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
+#else
 TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
+#endif
 
 ClassImp(TMVA::PDF)
 
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index f7506064c7e05..1099a9caa3ff1 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -51,13 +51,10 @@ using std::vector;
 
 ClassImp(TMVA::TNeuron)
 
-TMVA::MsgLogger* TMVA::TNeuron::fgLogger = 0;
-
 //______________________________________________________________________________
 TMVA::TNeuron::TNeuron()
 {
    // standard constructor
-   if (!fgLogger) fgLogger = new MsgLogger("TNeuron",kDEBUG);
    InitNeuron();
 }
 
@@ -334,3 +331,14 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
    // print message, for debugging
    Log() << type << message << Endl;
 }
+
+//______________________________________________________________________________
+TMVA::MsgLogger& TMVA::TNeuron::Log() const 
+{
+  #if __cplusplus > 199711L
+  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
+#else
+  static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
+#endif
+  return logger;
+}
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index da3c0a84646bc..ab03d79f8b173 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Matt Jachowski 
+// Author: Matt Jachowski
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -20,10 +20,10 @@
  * modification, are permitted according to the terms listed in LICENSE           *
  * (http://tmva.sourceforge.net/LICENSE)                                          *
  **********************************************************************************/
-   
+
 //_______________________________________________________________________
-//                                                                      
-// Synapse class used by TMVA artificial neural network methods      
+//
+// Synapse class used by TMVA artificial neural network methods
 //_______________________________________________________________________
 
 #include "TMVA/TSynapse.h"
@@ -40,8 +40,6 @@ static const Int_t fgUNINITIALIZED = -1;
 
 ClassImp(TMVA::TSynapse);
 
-TMVA::MsgLogger* TMVA::TSynapse::fgLogger = 0;
-
 //______________________________________________________________________________
 TMVA::TSynapse::TSynapse()
   : fWeight( 0 ),
@@ -54,7 +52,6 @@ TMVA::TSynapse::TSynapse()
 {
    // constructor
    fWeight     = fgUNINITIALIZED;
-   if (!fgLogger) fgLogger = new MsgLogger("TSynapse");
 }
 
 
@@ -75,7 +72,7 @@ void TMVA::TSynapse::SetWeight(Double_t weight)
 Double_t TMVA::TSynapse::GetWeightedValue()
 {
    // get output of pre-neuron weighted by synapse weight
-   if (fPreNeuron == NULL) 
+   if (fPreNeuron == NULL)
       Log() << kFATAL << "<GetWeightedValue> synapse not connected to neuron" << Endl;
 
    return (fWeight * fPreNeuron->GetActivationValue());
@@ -86,7 +83,7 @@ Double_t TMVA::TSynapse::GetWeightedDelta()
 {
    // get error field of post-neuron weighted by synapse weight
 
-   if (fPostNeuron == NULL) 
+   if (fPostNeuron == NULL)
       Log() << kFATAL << "<GetWeightedDelta> synapse not connected to neuron" << Endl;
 
    return fWeight * fPostNeuron->GetDelta();
@@ -108,3 +105,14 @@ void TMVA::TSynapse::CalculateDelta()
    fDelta += fPostNeuron->GetDelta() * fPreNeuron->GetActivationValue();
    fCount++;
 }
+
+//______________________________________________________________________________
+TMVA::MsgLogger& TMVA::TSynapse::Log() const
+{
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
+#else
+  static MsgLogger logger("TSynapse");               //! message logger, static to save resources
+#endif
+  return logger;
+}
diff --git a/tmva/src/Tools.cxx b/tmva/src/Tools.cxx
index d968043eb668e..f00bfa3447f94 100644
--- a/tmva/src/Tools.cxx
+++ b/tmva/src/Tools.cxx
@@ -70,10 +70,37 @@
 
 using namespace std;
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Tools*> TMVA::Tools::fgTools{0};
+#else
 TMVA::Tools* TMVA::Tools::fgTools = 0;
+#endif
+
 TMVA::Tools& TMVA::gTools()                 { return TMVA::Tools::Instance(); }
-TMVA::Tools& TMVA::Tools::Instance()        { return fgTools?*(fgTools): *(fgTools = new Tools()); }
-void         TMVA::Tools::DestroyInstance() { if (fgTools != 0) { delete fgTools; fgTools=0; } }
+TMVA::Tools& TMVA::Tools::Instance()        {
+#if __cplusplus > 199711L
+  if(!fgTools) {
+    Tools* tmp = new Tools();
+    Tools* expected = 0;
+    if(! fgTools.compare_exchange_strong(expected,tmp)) {
+      //another thread beat us
+      delete tmp;
+    }
+  }
+  return *fgTools;
+#else
+  return fgTools?*(fgTools): *(fgTools = new Tools());
+#endif
+}
+void         TMVA::Tools::DestroyInstance() {
+  //NOTE: there is no thread safe way to do this so
+  // one must only call this method ones in an executable
+#if __cplusplus > 199711L
+  if (fgTools != 0) { delete fgTools.load(); fgTools=0; }
+#else
+  if (fgTools != 0) { delete fgTools; fgTools=0; }
+#endif
+}
 
 //_______________________________________________________________________
 TMVA::Tools::Tools() :
@@ -107,19 +134,19 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
    Double_t separation = 0;
 
    // sanity checks
-   // signal and background histograms must have same number of bins and 
+   // signal and background histograms must have same number of bins and
    // same limits
    if ((S->GetNbinsX() != B->GetNbinsX()) || (S->GetNbinsX() <= 0)) {
       Log() << kFATAL << "<GetSeparation> signal and background"
-            << " histograms have different number of bins: " 
+            << " histograms have different number of bins: "
             << S->GetNbinsX() << " : " << B->GetNbinsX() << Endl;
    }
 
-   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() || 
-       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() || 
+   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() ||
+       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() ||
        S->GetXaxis()->GetXmax() <= S->GetXaxis()->GetXmin()) {
-      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin() 
-            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax() 
+      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin()
+            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax()
             << " " << S->GetXaxis()->GetXmax() << " " << S->GetXaxis()->GetXmin() << Endl;
       Log() << kFATAL << "<GetSeparation> signal and background"
             << " histograms have different or invalid dimensions:" << Endl;
@@ -140,7 +167,7 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
       separation *= intBin;
    }
    else {
-      Log() << kWARNING << "<GetSeparation> histograms with zero entries: " 
+      Log() << kWARNING << "<GetSeparation> histograms with zero entries: "
             << nS << " : " << nB << " cannot compute separation"
             << Endl;
       separation = 0;
@@ -186,11 +213,11 @@ void TMVA::Tools::ComputeStat( const std::vector<TMVA::Event*>& events, std::vec
                                Int_t signalClass, Bool_t  norm )
 {
    // sanity check
-   if (0 == valVec) 
+   if (0 == valVec)
       Log() << kFATAL << "<Tools::ComputeStat> value vector is zero pointer" << Endl;
-   
-   if ( events.size() != valVec->size() ) 
-      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths " 
+
+   if ( events.size() != valVec->size() )
+      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths "
             << events.size() << "!=" << valVec->size() << Endl;
 
    Long64_t entries = valVec->size();
@@ -301,14 +328,14 @@ TMatrixD* TMVA::Tools::GetSQRootMatrix( TMatrixDSym* symMat )
 //_______________________________________________________________________
 const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
 {
-   // turns covariance into correlation matrix   
+   // turns covariance into correlation matrix
    if (covMat == 0) return 0;
 
    // sanity check
    Int_t nvar = covMat->GetNrows();
-   if (nvar != covMat->GetNcols()) 
+   if (nvar != covMat->GetNcols())
       Log() << kFATAL << "<GetCorrelationMatrix> input matrix not quadratic" << Endl;
-   
+
    TMatrixD* corrMat = new TMatrixD( nvar, nvar );
 
    for (Int_t ivar=0; ivar<nvar; ivar++) {
@@ -323,12 +350,12 @@ const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
             }
             if (TMath::Abs( (*corrMat)(ivar,jvar))  > 1){
                Log() << kWARNING
-                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)  
+                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)
                      << " sigma2="<<d
                      << " cov("<<ivar<<","<<ivar<<")=" <<(*covMat)(ivar, ivar)
                      << " cov("<<jvar<<","<<jvar<<")=" <<(*covMat)(jvar, jvar)
-                     << Endl; 
-               
+                     << Endl;
+
             }
          }
          else (*corrMat)(ivar, ivar) = 1.0;
@@ -344,10 +371,10 @@ TH1* TMVA::Tools::projNormTH1F( TTree* theTree, const TString& theVarName,
                                 Double_t xmin, Double_t xmax, const TString& cut )
 {
    // projects variable from tree into normalised histogram
- 
+
    // needed because of ROOT bug (feature) that excludes events that have value == xmax
-   xmax += 0.00001; 
-   
+   xmax += 0.00001;
+
    TH1* hist = new TH1F( name, name, nbins, xmin, xmax );
    hist->Sumw2(); // enable quadratic errors
    theTree->Project( name, theVarName, cut );
@@ -390,11 +417,11 @@ TList* TMVA::Tools::ParseFormatLine( TString formatString, const char* sep )
       Ssiz_t posSep = formatString.First(sep);
       labelList->Add(new TObjString(TString(formatString(0,posSep)).Data()));
       formatString.Remove(0,posSep+1);
-      
+
       while (formatString.First(sep)==0) formatString.Remove(0,1); // remove additional separators
-      
+
    }
-   return labelList;                                                 
+   return labelList;
 }
 
 //_______________________________________________________________________
@@ -500,9 +527,9 @@ void TMVA::Tools::Scale( std::vector<Float_t>& v, Float_t f )
 
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::vector<TString>* vs ){
-   // sort 2D vector (AND in parallel a TString vector) in such a way 
+   // sort 2D vector (AND in parallel a TString vector) in such a way
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted. 
+   // in the same way as necessary to have the first vector sorted.
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -526,9 +553,9 @@ void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::v
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortDescending( std::vector<std::vector<Double_t> >& v, std::vector<TString>* vs )
 {
-   // sort 2D vector (AND in parallel a TString vector) in such a way 
+   // sort 2D vector (AND in parallel a TString vector) in such a way
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted. 
+   // in the same way as necessary to have the first vector sorted.
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -556,13 +583,13 @@ Double_t TMVA::Tools::GetMutualInformation( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0) return -1; 
+   if (hi == 0) return -1;
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
-   
+
    Double_t mutualInfo = 0.;
    Int_t maxBinX = h.GetNbinsX();
    Int_t maxBinY = h.GetNbinsY();
@@ -587,14 +614,14 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0.) return -1; 
+   if (hi == 0.) return -1;
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
 
-   Double_t corrRatio = 0.;    
+   Double_t corrRatio = 0.;
    Double_t y_mean = h.ProjectionY()->GetMean();
    for (Int_t ix=1; ix<=h.GetNbinsX(); ix++) {
       corrRatio += (h.Integral(ix,ix,1,h.GetNbinsY())/hi)*pow((GetYMean_binX(h,ix)-y_mean),2);
@@ -607,7 +634,7 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
 Double_t TMVA::Tools::GetYMean_binX( const TH2& h, Int_t bin_x )
 {
    // Compute the mean in Y for a given bin X of a 2D histogram
- 
+
    if (h.Integral(bin_x,bin_x,1,h.GetNbinsY()) == 0.) {return 0;}
    Double_t y_bin_mean = 0.;
    TH1* py = h.ProjectionY();
@@ -627,8 +654,8 @@ TH2F* TMVA::Tools::TransposeHist( const TH2F& h )
    if (h.GetNbinsX() != h.GetNbinsY()) {
       Log() << kFATAL << "<TransposeHist> cannot transpose non-quadratic histogram" << Endl;
    }
-   
-   TH2F *transposedHisto = new TH2F( h ); 
+
+   TH2F *transposedHisto = new TH2F( h );
    for (Int_t ix=1; ix <= h.GetNbinsX(); ix++){
       for (Int_t iy=1; iy <= h.GetNbinsY(); iy++){
          transposedHisto->SetBinContent(iy,ix,h.GetBinContent(ix,iy));
@@ -658,8 +685,8 @@ Bool_t TMVA::Tools::CheckForSilentOption( const TString& cs ) const
    // check for "silence" option in configuration option string
    Bool_t isSilent = kFALSE;
 
-   TString s( cs ); 
-   s.ToLower(); 
+   TString s( cs );
+   s.ToLower();
    s.ReplaceAll(" ","");
    if (s.Contains("silent") && !s.Contains("silent=f")) {
       if (!s.Contains("!silent") || s.Contains("silent=t")) isSilent = kTRUE;
@@ -674,8 +701,8 @@ Bool_t TMVA::Tools::CheckForVerboseOption( const TString& cs ) const
    // check if verbosity "V" set in option
    Bool_t isVerbose = kFALSE;
 
-   TString s( cs ); 
-   s.ToLower(); 
+   TString s( cs );
+   s.ToLower();
    s.ReplaceAll(" ","");
    std::vector<TString> v = SplitString( s, ':' );
    for (std::vector<TString>::iterator it = v.begin(); it != v.end(); it++) {
@@ -739,27 +766,27 @@ Int_t TMVA::Tools::GetIndexMinElement( std::vector<Double_t>& v )
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )  
+Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )
 {
    // check if regular expression
    // helper function to search for "$!%^&()'<>?= " in a string
 
    Bool_t  regular = kFALSE;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
       if (s.Contains( Tools::fRegexp[i] )) { regular = kTRUE; break; }
 
    return regular;
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )  
+TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )
 {
    // replace regular expressions
    // helper function to remove all occurences "$!%^&()'<>?= " from a string
    // and replace all ::,$,*,/,+,- with _M_,_S_,_T_,_D_,_P_,_M_ respectively
 
    TString snew = s;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
       snew.ReplaceAll( Tools::fRegexp[i], r );
 
    snew.ReplaceAll( "::", r );
@@ -784,56 +811,56 @@ TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString&
 }
 
 //_______________________________________________________________________
-const TString& TMVA::Tools::Color( const TString& c ) 
+const TString& TMVA::Tools::Color( const TString& c )
 {
    // human readable color strings
-   static TString gClr_none         = "" ;
-   static TString gClr_white        = "\033[1;37m";  // white
-   static TString gClr_black        = "\033[30m";    // black
-   static TString gClr_blue         = "\033[34m";    // blue
-   static TString gClr_red          = "\033[1;31m" ; // red
-   static TString gClr_yellow       = "\033[1;33m";  // yellow
-   static TString gClr_darkred      = "\033[31m";    // dark red
-   static TString gClr_darkgreen    = "\033[32m";    // dark green
-   static TString gClr_darkyellow   = "\033[33m";    // dark yellow
-                                    
-   static TString gClr_bold         = "\033[1m"    ; // bold 
-   static TString gClr_black_b      = "\033[30m"   ; // bold black
-   static TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
-   static TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
-   static TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
-                                    
-   static TString gClr_blue_bg      = "\033[44m";    // blue background
-   static TString gClr_red_bg       = "\033[1;41m";  // white on red background
-   static TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
-   static TString gClr_whiteongreen = "\033[1;42m";  // white on green background
-   static TString gClr_grey_bg      = "\033[47m";    // grey background
-
-   static TString gClr_reset  = "\033[0m";     // reset
+   static const TString gClr_none         = "" ;
+   static const TString gClr_white        = "\033[1;37m";  // white
+   static const TString gClr_black        = "\033[30m";    // black
+   static const TString gClr_blue         = "\033[34m";    // blue
+   static const TString gClr_red          = "\033[1;31m" ; // red
+   static const TString gClr_yellow       = "\033[1;33m";  // yellow
+   static const TString gClr_darkred      = "\033[31m";    // dark red
+   static const TString gClr_darkgreen    = "\033[32m";    // dark green
+   static const TString gClr_darkyellow   = "\033[33m";    // dark yellow
+
+   static const TString gClr_bold         = "\033[1m"    ; // bold
+   static const TString gClr_black_b      = "\033[30m"   ; // bold black
+   static const TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
+   static const TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
+   static const TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
+
+   static const TString gClr_blue_bg      = "\033[44m";    // blue background
+   static const TString gClr_red_bg       = "\033[1;41m";  // white on red background
+   static const TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
+   static const TString gClr_whiteongreen = "\033[1;42m";  // white on green background
+   static const TString gClr_grey_bg      = "\033[47m";    // grey background
+
+   static const TString gClr_reset  = "\033[0m";     // reset
 
    if (!gConfig().UseColor()) return gClr_none;
 
-   if (c == "white" )         return gClr_white; 
-   if (c == "blue"  )         return gClr_blue; 
-   if (c == "black"  )        return gClr_black; 
+   if (c == "white" )         return gClr_white;
+   if (c == "blue"  )         return gClr_blue;
+   if (c == "black"  )        return gClr_black;
    if (c == "lightblue")      return gClr_cyan_b;
-   if (c == "yellow")         return gClr_yellow; 
-   if (c == "red"   )         return gClr_red; 
-   if (c == "dred"  )         return gClr_darkred; 
-   if (c == "dgreen")         return gClr_darkgreen; 
+   if (c == "yellow")         return gClr_yellow;
+   if (c == "red"   )         return gClr_red;
+   if (c == "dred"  )         return gClr_darkred;
+   if (c == "dgreen")         return gClr_darkgreen;
    if (c == "lgreenb")        return gClr_lgreen_b;
-   if (c == "dyellow")        return gClr_darkyellow; 
+   if (c == "dyellow")        return gClr_darkyellow;
+
+   if (c == "bold")           return gClr_bold;
+   if (c == "bblack")         return gClr_black_b;
 
-   if (c == "bold")           return gClr_bold; 
-   if (c == "bblack")         return gClr_black_b; 
+   if (c == "blue_bgd")       return gClr_blue_bg;
+   if (c == "red_bgd" )       return gClr_red_bg;
 
-   if (c == "blue_bgd")       return gClr_blue_bg; 
-   if (c == "red_bgd" )       return gClr_red_bg; 
- 
-   if (c == "white_on_blue" ) return gClr_whiteonblue; 
-   if (c == "white_on_green") return gClr_whiteongreen; 
+   if (c == "white_on_blue" ) return gClr_whiteonblue;
+   if (c == "white_on_green") return gClr_whiteongreen;
 
-   if (c == "reset") return gClr_reset; 
+   if (c == "reset") return gClr_reset;
 
    std::cout << "Unknown color " << c << std::endl;
    exit(1);
@@ -842,7 +869,7 @@ const TString& TMVA::Tools::Color( const TString& c )
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V, 
+void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V,
                                    const TString titleVars, const TString titleValues, MsgLogger& logger,
                                    TString format )
 {
@@ -851,7 +878,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    // sanity check
    UInt_t nvar = V.size();
    if ((UInt_t)values.size() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
              << values.size() << " OR " << " != " << nvar << Endl;
    }
 
@@ -872,7 +899,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL) << titleVars << ":";
    logger << setw(maxV+1) << titleValues << ":";
    logger << Endl;
@@ -899,11 +926,11 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    // sanity check: matrix must be quadratic
    UInt_t nvar = V.size();
    if ((UInt_t)M.GetNcols() != nvar || (UInt_t)M.GetNrows() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
              << M.GetNcols() << " OR " << M.GetNrows() << " != " << nvar << " ==> abort" << Endl;
    }
 
-   // get length of each variable, and maximum length  
+   // get length of each variable, and maximum length
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -911,7 +938,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       vLengths.push_back(TMath::Max( (UInt_t)V[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-   
+
    // count column length
    UInt_t clen = maxL+1;
    for (UInt_t icol=0; icol<nvar; icol++) clen += vLengths[icol]+1;
@@ -920,7 +947,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nvar; icol++) logger << setw(vLengths[icol]+1) << V[icol];
    logger << Endl;
@@ -930,7 +957,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       logger << setw(maxL) << V[irow] << ":";
       for (UInt_t icol=0; icol<nvar; icol++) {
          logger << setw(vLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }      
+      }
       logger << Endl;
    }
 
@@ -940,17 +967,17 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const TMatrixD& M, 
-                                   const std::vector<TString>& vert, const std::vector<TString>& horiz, 
+void TMVA::Tools::FormattedOutput( const TMatrixD& M,
+                                   const std::vector<TString>& vert, const std::vector<TString>& horiz,
                                    MsgLogger& logger )
 {
    // formatted output of matrix (with labels)
 
    // sanity check: matrix must be quadratic
-   UInt_t nvvar = vert.size();   
+   UInt_t nvvar = vert.size();
    UInt_t nhvar = horiz.size();
 
-   // get length of each variable, and maximum length  
+   // get length of each variable, and maximum length
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -958,7 +985,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       vLengths.push_back(TMath::Max( (UInt_t)vert[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-   
+
    // count column length
    UInt_t minLh = 7;
    UInt_t maxLh = minLh;
@@ -975,7 +1002,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nhvar; icol++) logger << setw(hLengths[icol]+1) << horiz[icol];
    logger << Endl;
@@ -985,7 +1012,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       logger << setw(maxL) << vert[irow] << ":";
       for (UInt_t icol=0; icol<nhvar; icol++) {
          logger << setw(hLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }      
+      }
       logger << Endl;
    }
 
@@ -1073,7 +1100,7 @@ void TMVA::Tools::AddAttr( void* node, const char* attrname, const char* value )
 }
 
 //_______________________________________________________________________
-void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode ) 
+void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode )
 {
    // add child node
    if( !isRootNode && parent == 0 ) return 0;
@@ -1090,7 +1117,7 @@ void* TMVA::Tools::GetParent( void* child)
 {
    // get parent node
    void* par = xmlengine().GetParent(child);
-   
+
    return par;
 }
 //_______________________________________________________________________
@@ -1161,7 +1188,7 @@ std::vector<TString> TMVA::Tools::SplitString(const TString& theOpt, const char
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromInt( Long_t i ) 
+TString TMVA::Tools::StringFromInt( Long_t i )
 {
    // string tools
    std::stringstream s;
@@ -1170,7 +1197,7 @@ TString TMVA::Tools::StringFromInt( Long_t i )
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromDouble( Double_t d ) 
+TString TMVA::Tools::StringFromDouble( Double_t d )
 {
    // string tools
    std::stringstream s;
@@ -1250,7 +1277,7 @@ void TMVA::Tools::TMVAWelcomeMessage()
 void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 {
    // prints the TMVA release number and date
-   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE 
+   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE
           << "" << Endl;
 }
 
@@ -1258,10 +1285,10 @@ void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 void TMVA::Tools::ROOTVersionMessage( MsgLogger& logger )
 {
    // prints the ROOT release number and date
-   static const char *months[] = { "Jan","Feb","Mar","Apr","May",
+   static const char * const months[] = { "Jan","Feb","Mar","Apr","May",
                                    "Jun","Jul","Aug","Sep","Oct",
                                    "Nov","Dec" };
-   Int_t   idatqq = gROOT->GetVersionDate();   
+   Int_t   idatqq = gROOT->GetVersionDate();
    Int_t   iday   = idatqq%100;
    Int_t   imonth = (idatqq/100)%100;
    Int_t   iyear  = (idatqq/10000);
@@ -1342,27 +1369,27 @@ void TMVA::Tools::TMVAWelcomeMessage( MsgLogger& logger, EWelcomeMessage msgType
       break;
 
    case kOriginalWelcomeMsgColor:
-      logger << kINFO << "" << Color("red") 
+      logger << kINFO << "" << Color("red")
              << "_______________________________________" << Color("reset") << Endl;
       logger << kINFO << "" << Color("blue")
              << Color("red_bgd") << Color("bwhite") << " // " << Color("reset")
-             << Color("white") << Color("blue_bgd") 
+             << Color("white") << Color("blue_bgd")
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Color("reset") << Endl;
       logger << kINFO << ""<< Color("blue")
              << Color("red_bgd") << Color("white") << "//  " << Color("reset")
-             << Color("white") << Color("blue_bgd") 
+             << Color("white") << Color("blue_bgd")
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Color("reset") << Endl;
       break;
-      
+
    case kOriginalWelcomeMsgBW:
-      logger << kINFO << "" 
+      logger << kINFO << ""
              << "_______________________________________" << Endl;
       logger << kINFO << " // "
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Endl;
-      logger << kINFO << "//  " 
+      logger << kINFO << "//  "
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Endl;
       break;
-      
+
    default:
       logger << kFATAL << "unknown message type: " << msgType << Endl;
    }
@@ -1407,11 +1434,11 @@ void TMVA::Tools::TMVACitation( MsgLogger& logger, ECitation citType )
 
    case kHtmlLink:
       logger << kINFO << "  " << Endl;
-      logger << kINFO << gTools().Color("bold") 
+      logger << kINFO << gTools().Color("bold")
              << "Thank you for using TMVA!" << gTools().Color("reset") << Endl;
-      logger << kINFO << gTools().Color("bold") 
+      logger << kINFO << gTools().Color("bold")
              << "For citation information, please visit: http://tmva.sf.net/citeTMVA.html"
-             << gTools().Color("reset") << Endl; 
+             << gTools().Color("reset") << Endl;
    }
 }
 
@@ -1450,7 +1477,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
    }
 
    UInt_t nvars=0, ntgts=0, nspcts=0;
-   if (transformBase) 
+   if (transformBase)
       transformBase->CountVariableTypes( nvars, ntgts, nspcts );
    else {
       nvars =events.at(0)->GetNVariables ();
@@ -1504,7 +1531,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
             input.push_back (ev->GetValue(ivar));
          }
       }
-       
+
       if (maxCls > 1) {
          v = vec->at(matNum-1);
          m = mat2->at(matNum-1);
@@ -1576,7 +1603,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    int i = 0;
    if (w==NULL)
    {
-      while ( first != last ) 
+      while ( first != last )
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1594,7 +1621,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    }
    else
    {
-      while ( first != last ) 
+      while ( first != last )
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1642,7 +1669,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble; 
+         sum  += adouble;
          sum2 += adouble*adouble;
          sumw += 1.0;
          ++first;
@@ -1652,7 +1679,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble * (*w); 
+         sum  += adouble * (*w);
          sum2 += adouble*adouble * (*w);
          sumw += (*w);
          ++first;
@@ -1688,7 +1715,7 @@ TH1* TMVA::Tools::GetCumulativeDist( TH1* h)
 
    Float_t partialSum = 0;
    Float_t inverseSum = 0.;
-   
+
    Float_t val;
    for (Int_t ibinEnd=1, ibin=cumulativeDist->GetNbinsX(); ibin >=ibinEnd ; ibin--){
       val = cumulativeDist->GetBinContent(ibin);
diff --git a/tmva/src/Types.cxx b/tmva/src/Types.cxx
index 6d8d060b38bde..88701c8f410f5 100644
--- a/tmva/src/Types.cxx
+++ b/tmva/src/Types.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$   
+// @(#)root/tmva $Id$
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      U. of Victoria, Canada                                                    * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      U. of Victoria, Canada                                                    *
+ *      MPI-K Heidelberg, Germany                                                 *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -27,11 +27,19 @@
 
 #include <map>
 #include <iostream>
+#if __cplusplus > 199711L
+#include <mutex>
+#endif
 
 #include "TMVA/Types.h"
 #include "TMVA/MsgLogger.h"
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Types*> TMVA::Types::fgTypesPtr{0};
+static std::mutex gTypesMutex;
+#else
 TMVA::Types* TMVA::Types::fgTypesPtr = 0;
+#endif
 
 //_______________________________________________________________________
 TMVA::Types::Types()
@@ -40,33 +48,52 @@ TMVA::Types::Types()
    // constructor
 }
 
-TMVA::Types::~Types() 
+TMVA::Types::~Types()
 {
    // destructor
    delete fLogger;
 }
 
 //_______________________________________________________________________
-TMVA::Types& TMVA::Types::Instance() 
-{ 
-   // the the single instance of "Types" if existin already, or create it  (Signleton) 
-   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types()); 
+TMVA::Types& TMVA::Types::Instance()
+{
+   // the the single instance of "Types" if existin already, or create it  (Signleton)
+#if __cplusplus > 199711L
+  if(!fgTypesPtr) {
+    Types* tmp = new Types();
+    Types* expected = 0;
+    if(!fgTypesPtr.compare_exchange_strong(expected,tmp)) {
+      //Another thread already did it
+      delete tmp;
+    }
+  }
+  return *fgTypesPtr;
+#else
+   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types());
+#endif
 }
 //_______________________________________________________________________
-void   TMVA::Types::DestroyInstance() 
-{ 
+void   TMVA::Types::DestroyInstance()
+{
    // "destructor" of the single instance
-   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; } 
+#if __cplusplus > 199711L
+   if (fgTypesPtr != 0) { delete fgTypesPtr.load(); fgTypesPtr = 0; }
+#else
+   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; }
+#endif
 }
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname ) 
+Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname )
 {
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( methodname );
    if (it != fStr2type.end()) {
-      Log() << kFATAL 
-            << "Cannot add method " << methodname 
+      Log() << kFATAL
+            << "Cannot add method " << methodname
             << " to the name->type map because it exists already" << Endl;
       return kFALSE;
    }
@@ -76,8 +103,11 @@ Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodnam
 }
 
 //_______________________________________________________________________
-TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const 
-{ 
+TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
+{
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    // returns the method type (enum) for a given method (string)
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( method );
    if (it == fStr2type.end()) {
@@ -88,8 +118,11 @@ TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
 }
 
 //_______________________________________________________________________
-TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const 
+TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const
 {
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.begin();
    for (; it!=fStr2type.end(); it++) if (it->second == method) return it->first;
    Log() << kFATAL << "Unknown method index in map: " << method << Endl;

From 6273c14202edeffc8492954e6318312899775882 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 14:54:51 +0100
Subject: [PATCH 151/200] Stress the MT features of the Reader class with a new
 unit test

called utReaderMT. This test runs the code which is in utReader
but for 5 times in a row in different threads. Five times in a row
because intrinsic non reproducibility is present in multithreaded
programs and this makes the test more restrictive as it increases
the probability of collisions.
---
 test/stressTMVA.cxx | 132 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 3 deletions(-)

diff --git a/test/stressTMVA.cxx b/test/stressTMVA.cxx
index cdb7e397f6ba4..ea488b6f2fcbc 100644
--- a/test/stressTMVA.cxx
+++ b/test/stressTMVA.cxx
@@ -60,6 +60,7 @@ Regression_BDTG2 [4/4]...........................................OK
 *  CPUTIME   =  90.2   *  Root5.27/07   20100929/1318
 ******************************************************************
 */
+#include "TThread.h"
 // including file tmvaut/UnitTest.h
 #ifndef UNITTEST_H
 #define UNITTEST_H
@@ -70,6 +71,7 @@ Regression_BDTG2 [4/4]...........................................OK
 #include <string>
 #include <iostream>
 #include <cassert>
+#include <atomic>
 
 // The following have underscores because
 // they are macros. For consistency,
@@ -104,8 +106,8 @@ namespace UnitTesting
       bool floatCompare(float x1, float x2);
    private:
       std::ostream* osptr;
-      long nPass;
-      long nFail;
+      std::atomic<long> nPass;
+      std::atomic<long> nFail;
       mutable std::string fName;
       std::string fFileName;
       // Disallowed:
@@ -207,7 +209,7 @@ long UnitTest::report() const
 {
    if (osptr)
       {
-         std::string counts(Form(" [%li/%li]", nPass, nPass+nFail));
+         std::string counts(Form(" [%li/%li]", nPass.load(), nPass+nFail));
 
          *osptr << name() << counts;
 
@@ -1292,6 +1294,128 @@ void utReader::run()
    reader[2]->EvaluateMVA( "LD method");
    test_(1>0);
 }
+#ifndef UTREADERMT_H
+#define UTREADERMT_H
+
+// Author: D. Piparo, 2015
+// TMVA unit tests
+//
+// this class acts as interface to several reader applications in MT mode
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <vector>
+#include <thread>
+
+#include "TTree.h"
+#include "TString.h"
+
+#include "TMVA/Reader.h"
+#include "TMVA/Types.h"
+
+
+
+namespace UnitTesting
+{
+  class utReaderMT : public UnitTest
+  {
+  public:
+    utReaderMT(const char* theOption="");
+    virtual ~utReaderMT();
+
+    virtual void run();
+
+  protected:
+
+  private:
+     // disallow copy constructor and assignment
+     utReaderMT(const utReaderMT&);
+     utReaderMT& operator=(const utReaderMT&);
+  };
+} // namespace UnitTesting
+#endif //
+
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+#include "TTree.h"
+#include "TString.h"
+
+#include "TMVA/Reader.h"
+#include "TMVA/Types.h"
+
+
+
+using namespace std;
+using namespace UnitTesting;
+using namespace TMVA;
+
+utReaderMT::utReaderMT(const char* /*theOption*/)
+   : UnitTest(string("Reader"))
+{
+
+}
+utReaderMT::~utReaderMT(){ }
+
+void utReaderMT::run()
+{
+   auto runSingleReader = [&] () {
+      float xtest,xtest2;
+      Reader* reader2 = new Reader();
+      Reader* reader3 = new Reader();
+      reader2->AddVariable("test", &xtest);
+      reader2->AddVariable("test2", &xtest2);
+      reader3->AddVariable("test", &xtest);
+
+      delete reader2;
+      delete reader3;
+      test_(1>0);
+      const int nTest=3;
+      int ievt;
+      vector<float> testvar(10);
+      std::vector< TMVA::Reader* > reader(nTest);
+      for (int iTest=0;iTest<nTest;iTest++){
+         reader[iTest] = new TMVA::Reader( "!Color:Silent" );
+         if (iTest==0){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest_LD.weights.xml") ;
+         }
+         if (iTest==1){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3Var_LD.weights.xml") ;
+         }
+         if (iTest==2){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
+            reader[iTest]->AddVariable( "ivar0" ,&testvar[3]);
+            reader[iTest]->AddVariable( "ivar1" ,&testvar[4]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3VarF2VarI_LD.weights.xml") ;
+         }
+      }
+      reader[0]->EvaluateMVA( "LD method");
+      reader[1]->EvaluateMVA( "LD method");
+      reader[2]->EvaluateMVA( "LD method");
+      test_(1>0);
+   };
+   for (int j=0;j<5;++j){ // challenge non reproducibility repeating the loop
+      vector<thread> threads;
+      for (int i=0;i<10;++i) threads.emplace_back(runSingleReader);
+      for (auto&& t : threads) t.join();
+   }
+
+}
+
 // including file tmvaut/utFactory.h
 #ifndef UTFACTORY_H
 #define UTFACTORY_H
@@ -2883,6 +3007,7 @@ int main(int argc, char **argv)
    TMVA_test.addTest(new utDataSet);
    TMVA_test.addTest(new utFactory);
    TMVA_test.addTest(new utReader);
+   TMVA_test.addTest(new utReaderMT);
 
    addClassificationTests(TMVA_test, full);
    addRegressionTests(TMVA_test, full);
@@ -2890,6 +3015,7 @@ int main(int argc, char **argv)
    addComplexClassificationTests(TMVA_test, full);
 
    // run all
+   TThread::Initialize();
    TMVA_test.run();
 
 #ifdef COUTDEBUG

From 4a9a21e685868f6f6f238beb1c806fa1b08c0333 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 15:37:03 +0100
Subject: [PATCH 152/200] Add Windows counterparts of gitinfo.sh and
 githeader.sh

---
 build/win/githeader.bat | 13 +++++++++++++
 build/win/gitinfo.bat   | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 build/win/githeader.bat
 create mode 100644 build/win/gitinfo.bat

diff --git a/build/win/githeader.bat b/build/win/githeader.bat
new file mode 100644
index 0000000000000..ec20ad2726c35
--- /dev/null
+++ b/build/win/githeader.bat
@@ -0,0 +1,13 @@
+@echo off
+
+rem Generate the header file from the Store info about in which git branch,
+rem what SHA1 and at what date/time we executed make.
+
+for /f "delims=" %%a in ('powershell.exe -command "& {Get-Content .\etc\gitinfo.txt | select -First 1}"') do set GIT_BRANCH=%%a
+for /f "delims=" %%a in ('powershell.exe -command "& {Get-Content .\etc\gitinfo.txt | select -First 2 | select -Last 1}"') do set GIT_COMMIT=%%a
+
+echo '#ifndef ROOT_RGITCOMMIT_H' > $1
+echo '#define ROOT_RGITCOMMIT_H' >> $1
+echo '#define ROOT_GIT_BRANCH "%GIT_BRANCH%"' >> $1
+echo '#define ROOT_GIT_COMMIT "%GIT_COMMIT%"' >> $1
+echo '#endif' >> $1
diff --git a/build/win/gitinfo.bat b/build/win/gitinfo.bat
new file mode 100644
index 0000000000000..0db5462033d53
--- /dev/null
+++ b/build/win/gitinfo.bat
@@ -0,0 +1,20 @@
+@echo off
+
+rem Store info about in which git branch, what SHA1 and at what date/time we executed make.
+
+set dir=""
+set dotgit=".git"
+if not "%1"=="" set dotgit="%1\.git"
+
+rem if we don't see the .git directory, just return
+if not exist %dotgit% exit /b 0
+
+set OUT=".\etc\gitinfo.txt"
+
+call git.exe --git-dir=%dotgit% describe --all > %OUT%
+call git.exe --git-dir=%dotgit% describe --always >> %OUT%
+
+for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
+set ldt=%ldt:~6,2% %ldt:~4,2% %ldt:~0,4%, %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2%
+echo %ldt%>> %OUT%
+

From 21a1293d84ced49f30783b87afd9a8cc98b9631d Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 15:51:16 +0100
Subject: [PATCH 153/200] Use proper batch script syntax

---
 build/win/githeader.bat | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/build/win/githeader.bat b/build/win/githeader.bat
index ec20ad2726c35..e68d0c707326b 100644
--- a/build/win/githeader.bat
+++ b/build/win/githeader.bat
@@ -6,8 +6,8 @@ rem what SHA1 and at what date/time we executed make.
 for /f "delims=" %%a in ('powershell.exe -command "& {Get-Content .\etc\gitinfo.txt | select -First 1}"') do set GIT_BRANCH=%%a
 for /f "delims=" %%a in ('powershell.exe -command "& {Get-Content .\etc\gitinfo.txt | select -First 2 | select -Last 1}"') do set GIT_COMMIT=%%a
 
-echo '#ifndef ROOT_RGITCOMMIT_H' > $1
-echo '#define ROOT_RGITCOMMIT_H' >> $1
-echo '#define ROOT_GIT_BRANCH "%GIT_BRANCH%"' >> $1
-echo '#define ROOT_GIT_COMMIT "%GIT_COMMIT%"' >> $1
-echo '#endif' >> $1
+echo #ifndef ROOT_RGITCOMMIT_H > %1
+echo #define ROOT_RGITCOMMIT_H >> %1
+echo #define ROOT_GIT_BRANCH "%GIT_BRANCH%" >> %1
+echo #define ROOT_GIT_COMMIT "%GIT_COMMIT%" >> %1
+echo #endif >> %1

From abd7f6b1927ab134ab14394f4cf408096a8acde3 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 16:09:54 +0100
Subject: [PATCH 154/200] On Windows, use the batch scripts instead of the
 shell scripts

---
 core/CMakeLists.txt | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 8066bb6cab0fe..37d8ed31000f0 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -73,12 +73,21 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/include/RGitCommit.h
                    COMMENT ""
                    DEPENDS ${CMAKE_BINARY_DIR}/RGitCommit.h.tmp
                    WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
-add_custom_command(OUTPUT  ${CMAKE_BINARY_DIR}/RGitCommit.h.tmp
-                   COMMAND ${CMAKE_SOURCE_DIR}/build/unix/gitinfo.sh ${CMAKE_SOURCE_DIR}
-                   COMMAND ${CMAKE_SOURCE_DIR}/build/unix/githeader.sh RGitCommit.h.tmp
-                   COMMENT "Recording the git revision now"
-                   DEPENDS ${dep_objects}
-                   WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+if(WIN32)
+  add_custom_command(OUTPUT  ${CMAKE_BINARY_DIR}/RGitCommit.h.tmp
+                     COMMAND ${CMAKE_SOURCE_DIR}/build/win/gitinfo.bat ${CMAKE_SOURCE_DIR}
+                     COMMAND ${CMAKE_SOURCE_DIR}/build/win/githeader.bat RGitCommit.h.tmp
+                     COMMENT "Recording the git revision now"
+                     DEPENDS ${dep_objects}
+                     WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+else()
+  add_custom_command(OUTPUT  ${CMAKE_BINARY_DIR}/RGitCommit.h.tmp
+                     COMMAND ${CMAKE_SOURCE_DIR}/build/unix/gitinfo.sh ${CMAKE_SOURCE_DIR}
+                     COMMAND ${CMAKE_SOURCE_DIR}/build/unix/githeader.sh RGitCommit.h.tmp
+                     COMMENT "Recording the git revision now"
+                     DEPENDS ${dep_objects}
+                     WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+endif()
 add_custom_target(gitcommit ALL DEPENDS ${CMAKE_BINARY_DIR}/RGitCommit.h.tmp)
 set_source_files_properties(${CMAKE_BINARY_DIR}/RGitCommit.h.tmp PROPERTIES GENERATED TRUE)
 add_dependencies(gitcommit ${dep_targets})

From 5758705f205c197d0929ad0e4aeaf798f09f7fd8 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 16:12:30 +0100
Subject: [PATCH 155/200] Fix usage of thread_local on OSx 10.9 using the ROOT
 macro TTHREAD_TLS

---
 tmva/inc/TMVA/BDTEventWrapper.h |  29 ++---
 tmva/inc/TMVA/MethodBase.h      |  25 +++--
 tmva/inc/TMVA/MethodPDERS.h     |  17 +--
 tmva/inc/TMVA/ModulekNN.h       |  16 +--
 tmva/inc/TMVA/PDF.h             |  45 ++++----
 tmva/src/BDTEventWrapper.cxx    |  14 +--
 tmva/src/BinaryTree.cxx         |  12 +-
 tmva/src/DecisionTreeNode.cxx   |   4 +-
 tmva/src/Interval.cxx           |  37 +++---
 tmva/src/LogInterval.cxx        |   3 +-
 tmva/src/MethodBase.cxx         | 192 ++++++++++++++++----------------
 tmva/src/MethodMLP.cxx          |  46 ++++----
 tmva/src/MethodPDERS.cxx        |  64 +++++------
 tmva/src/MethodTMlpANN.cxx      |  26 ++---
 tmva/src/ModulekNN.cxx          | 147 ++++++++++++------------
 tmva/src/Option.cxx             |  23 ++--
 tmva/src/PDF.cxx                |  10 +-
 tmva/src/TNeuron.cxx            |  10 +-
 tmva/src/TSynapse.cxx           |   4 +-
 19 files changed, 371 insertions(+), 353 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index cc3d0ae17814e..f272ea30b275b 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -5,9 +5,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *  
- *                                                                                *  
- *                                                                                *  
+ * Description:                                                                   *
+ *                                                                                *
+ *                                                                                *
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
@@ -25,64 +25,65 @@
 #ifndef ROOT_Event
 #include "Event.h"
 #endif
+#include "ThreadLocalStorage.h"
 
 namespace TMVA {
-  
+
    class BDTEventWrapper{
 
    public:
 
       BDTEventWrapper( const Event* );
       ~BDTEventWrapper();
-    
+
       // Require '<' operator to use std::sort algorithms on collection of Events
       Bool_t operator <( const BDTEventWrapper& other ) const;
-    
+
       // Set the accumulated weight, for sorted signal/background events
       /**
        * @param fType - true for signal, false for background
        * @param weight - the total weight
        */
       void SetCumulativeWeight( Bool_t type, Double_t weight );
-    
+
       // Get the accumulated weight
       /**
        * @param fType - true for signal, false for background
        * @return the cumulative weight for sorted signal/background events
        */
       Double_t GetCumulativeWeight( Bool_t type ) const;
-    
+
       // Set the index of the variable to compare on
       /**
        * @param iVar - index of the variable in fEvent to use
        */
       inline static void SetVarIndex( Int_t iVar ) { if (iVar >= 0) fVarIndex = iVar; }
-    
+
       // Return the value of variable fVarIndex for this event
       /**
        * @return value of variable fVarIndex for this event
        */
       inline Double_t GetVal() const { return fEvent->GetValue(fVarIndex); }
       const Event* operator*() const { return fEvent; }
-    
+
    private:
 
 #if __cplusplus > 199711L
-      static thread_local Int_t fVarIndex;  // index of the variable to sort on
+      static TTHREAD_TLS(Int_t) fVarIndex;  // index of the variable to sort on
 #else
       static Int_t fVarIndex;  // index of the variable to sort on
 #endif
       const Event* fEvent;     // pointer to the event
-    
+
       Double_t     fBkgWeight; // cumulative background weight for splitting
       Double_t     fSigWeight; // same for the signal weights
    };
 }
 
-inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const 
+inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const
 {
    return GetVal() < other.GetVal();
 }
 
-#endif 
+#endif
 
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 8a1c2d28610b9..6f699e7f7934b 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -71,6 +71,7 @@
 #ifndef ROOT_TMVA_OptimizeConfigParameters
 #include "TMVA/OptimizeConfigParameters.h"
 #endif
+#include "ThreadLocalStorage.h"
 
 class TGraph;
 class TTree;
@@ -202,7 +203,7 @@ namespace TMVA {
       }
 
       // probability of classifier response (mvaval) to be signal (requires "CreateMvaPdf" option set)
-      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different) 
+      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different)
       virtual Double_t GetProba( Double_t mvaVal, Double_t ap_sig );
 
       // Rarity of classifier response (signal or background (default) is uniform in [0,1])
@@ -274,7 +275,7 @@ namespace TMVA {
 
       // variables (and private menber functions) for the Evaluation:
       // get the effiency. It fills a histogram for efficiency/vs/bkg
-      // and returns the one value fo the efficiency demanded for 
+      // and returns the one value fo the efficiency demanded for
       // in the TString argument. (Watch the string format)
       virtual Double_t GetEfficiency( const TString&, Types::ETreeType, Double_t& err );
       virtual Double_t GetTrainingEfficiency(const TString& );
@@ -283,7 +284,7 @@ namespace TMVA {
       virtual Double_t GetSignificance() const;
       virtual Double_t GetROCIntegral(TH1D *histS, TH1D *histB) const;
       virtual Double_t GetROCIntegral(PDF *pdfS=0, PDF *pdfB=0) const;
-      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents, 
+      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents,
                                                Double_t& optimal_significance_value  ) const;
       virtual Double_t GetSeparation( TH1*, TH1* ) const;
       virtual Double_t GetSeparation( PDF* pdfS = 0, PDF* pdfB = 0 ) const;
@@ -366,7 +367,7 @@ namespace TMVA {
       mutable const Event*   fTmpEvent; //! temporary event when testing on a different DataSet than the own one
 
       // event reference and update
-      // NOTE: these Event accessors make sure that you get the events transformed according to the 
+      // NOTE: these Event accessors make sure that you get the events transformed according to the
       //        particular clasifiers transformation chosen
       UInt_t           GetNEvents      () const { return Data()->GetNEvents(); }
       const Event*     GetEvent        () const;
@@ -630,7 +631,7 @@ namespace TMVA {
 
       // this carrier
 #if __cplusplus > 199711L
-      static thread_local MethodBase* fgThisBase;         // this pointer
+      static TTHREAD_TLS(MethodBase*) fgThisBase;         // this pointer
 #else
       static MethodBase* fgThisBase;         // this pointer
 #endif
@@ -641,7 +642,7 @@ namespace TMVA {
       Bool_t           fNormalise;                   // normalise input variables
       Bool_t           fUseDecorr;                   // synonymous for decorrelation
       TString          fVariableTransformTypeString; // labels variable transform type
-      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files 
+      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files
       Int_t            fNbinsMVAPdf;                 // number of bins used in histogram that creates PDF
       Int_t            fNsmoothMVAPdf;               // number of times a histogram is smoothed before creating the PDF
 
@@ -662,12 +663,12 @@ namespace TMVA {
 
 
 //_______________________________________________________________________
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const
 {
    return GetTransformationHandler().Transform(ev);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent() const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
 {
    if(fTmpEvent)
       return GetTransformationHandler().Transform(fTmpEvent);
@@ -675,25 +676,25 @@ inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
       return GetTransformationHandler().Transform(Data()->GetEvent());
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt, type));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTraining);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTesting);
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index 9d1a4f7bd1e61..ecc3398b3af54 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -58,6 +58,7 @@
 #include "TVector.h"
 #endif
 #endif
+#include "ThreadLocalStorage.h"
 
 namespace TMVA {
 
@@ -69,7 +70,7 @@ namespace TMVA {
    public:
 
       MethodPDERS( const TString& jobName,
-                   const TString& methodTitle, 
+                   const TString& methodTitle,
                    DataSetInfo& theData,
                    const TString& theOption,
                    TDirectory* theTargetDir = 0 );
@@ -128,8 +129,8 @@ namespace TMVA {
 
       Double_t ApplyKernelFunction( Double_t normalized_distance );
       Double_t KernelNormalization( Double_t pdf );
-      Double_t GetNormalizedDistance( const TMVA::Event &base_event, 
-                                      const BinarySearchTreeNode &sample_event, 
+      Double_t GetNormalizedDistance( const TMVA::Event &base_event,
+                                      const BinarySearchTreeNode &sample_event,
                                       Double_t *dim_normalization);
       Double_t NormSinc( Double_t x );
       Double_t LanczosFilter( Int_t level, Double_t x );
@@ -148,7 +149,7 @@ namespace TMVA {
 
       // create binary search trees for signal and background
       void CreateBinarySearchTree( Types::ETreeType type );
-      
+
       // get sample of training events
       void GetSample( const Event &e, std::vector<const BinarySearchTreeNode*>& events, Volume *volume);
 
@@ -191,7 +192,7 @@ namespace TMVA {
       Float_t            fScaleS;        // weight for signal events
       Float_t            fScaleB;        // weight for background events
       Float_t            fDeltaFrac;     // fraction of RMS
-      Double_t           fGaussSigma;    // size of Gauss in adaptive volume 
+      Double_t           fGaussSigma;    // size of Gauss in adaptive volume
       Double_t           fGaussSigmaNorm;// size of Gauss in adaptive volume (normalised to dimensions)
 
       Double_t           fNRegOut;       // number of output dimensions for regression
@@ -203,10 +204,10 @@ namespace TMVA {
       Float_t            fInitialScale;  // initial scale for adaptive volume
 
       Bool_t             fInitializedVolumeEle; // is volume element initialized ?
-      
+
       Int_t              fkNNMin;        // min number of events in kNN tree
       Int_t              fkNNMax;        // max number of events in kNN tree
-      
+
       Double_t           fMax_distance;  // maximum distance
       Bool_t             fPrinted;       // print
       Bool_t             fNormTree;      // binary-search tree is normalised
@@ -221,7 +222,7 @@ namespace TMVA {
 
       // this carrier
 #if __cplusplus > 199711L
-      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+      static TTHREAD_TLS(MethodPDERS*) fgThisPDERS; // this pointer (required by root finder)
 #else
       static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
 #endif
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index 569ee5e80b46c..ddc4ff574bcee 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -48,20 +48,22 @@
 #ifndef ROOT_TRandom
 #include "TRandom3.h"
 #endif
+#include "ThreadLocalStorage.h"
 
 #ifndef ROOT_TMVA_NodekNN
 #include "TMVA/NodekNN.h"
 #endif
+#include "ThreadLocalStorage.h"
 
 namespace TMVA {
 
    class MsgLogger;
 
    namespace kNN {
-      
+
       typedef Float_t VarType;
       typedef std::vector<VarType> VarVec;
-      
+
       class Event {
       public:
 
@@ -97,7 +99,7 @@ namespace TMVA {
          VarVec fTgt; // targets for regression analysis
 
          Double_t fWeight; // event weight
-         Short_t fType; // event type ==0 or == 1, expand it to arbitrary class types? 
+         Short_t fType; // event type ==0 or == 1, expand it to arbitrary class types?
       };
 
       typedef std::vector<TMVA::kNN::Event> EventVec;
@@ -125,7 +127,7 @@ namespace TMVA {
 
          Bool_t Find(Event event, UInt_t nfind = 100, const std::string &option = "count") const;
          Bool_t Find(UInt_t nfind, const std::string &option) const;
-      
+
          const EventVec& GetEventVec() const;
 
          const List& GetkNNList() const;
@@ -134,7 +136,7 @@ namespace TMVA {
          const VarMap& GetVarMap() const;
 
          const std::map<Int_t, Double_t>& GetMetric() const;
-      
+
          void Print() const;
          void Print(std::ostream &os) const;
 
@@ -149,7 +151,7 @@ namespace TMVA {
       private:
 
 #if __cplusplus > 199711L
-         static thread_local TRandom3 fgRndm;
+         static TTHREAD_TLS(TRandom3) fgRndm;
 #else
          static TRandom3 fgRndm;
 #endif
@@ -161,7 +163,7 @@ namespace TMVA {
 
          mutable List  fkNNList;     // latest result from kNN search
          mutable Event fkNNEvent;    // latest event used for kNN search
-         
+
          std::map<Short_t, UInt_t> fCount; // count number of events of each type
 
          EventVec fEvent; // vector of all events used to build tree and analysis
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index e6387c99b496d..0dad2e2bbb1bf 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -19,10 +19,10 @@
  *      Jan Therhaag       <Jan.Therhaag@cern.ch>     - U of Bonn, Germany        *
  *                                                                                *
  * Copyright (c) 2005-2011:                                                       *
- *      CERN, Switzerland                                                         * 
- *      U. of Victoria, Canada                                                    * 
- *      MPI-K Heidelberg, Germany                                                 * 
- *      Freiburg U., Germany                                                      * 
+ *      CERN, Switzerland                                                         *
+ *      U. of Victoria, Canada                                                    *
+ *      MPI-K Heidelberg, Germany                                                 *
+ *      Freiburg U., Germany                                                      *
  *      U. of Bonn, Germany                                                       *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -52,6 +52,7 @@
 #ifndef ROOT_TMVA_Configurable
 #include "TMVA/Configurable.h"
 #endif
+#include "ThreadLocalStorage.h"
 
 class TSpline;
 class TGraph;
@@ -69,20 +70,20 @@ namespace TMVA {
 
       friend std::ostream& operator<< ( std::ostream& os, const PDF& tree );
       friend std::istream& operator>> ( std::istream& istr, PDF& tree);
-      
+
    public:
 
       enum EInterpolateMethod { kSpline0, kSpline1, kSpline2, kSpline3, kSpline5, kKDE };
 
       explicit PDF( const TString& name, Bool_t norm=kTRUE );
-      explicit PDF( const TString& name, const TH1* theHist, EInterpolateMethod method = kSpline2, 
+      explicit PDF( const TString& name, const TH1* theHist, EInterpolateMethod method = kSpline2,
                     Int_t minnsmooth = 0, Int_t maxnsmooth = 0, Bool_t checkHist = kFALSE, Bool_t norm=kTRUE );
-      explicit PDF( const TString& name, const TH1* theHist, 
-                    KDEKernel::EKernelType ktype, KDEKernel::EKernelIter kiter, KDEKernel::EKernelBorder 
+      explicit PDF( const TString& name, const TH1* theHist,
+                    KDEKernel::EKernelType ktype, KDEKernel::EKernelIter kiter, KDEKernel::EKernelBorder
                     kborder, Float_t FineFactor, Bool_t norm=kTRUE );
       explicit PDF( const TString& name, const TString& options, const TString& suffix = "", PDF* defaultPDF = 0, Bool_t norm=kTRUE);
       virtual ~PDF();
-      
+
       //creates the pdf after the definitions have been stored in
       void BuildPDF (const TH1* theHist);
 
@@ -121,7 +122,7 @@ namespace TMVA {
       const char* GetName() const { return fPDFName; }
 
       // TMVA version control (for weight files)
-      void   SetReadingVersion( UInt_t rv ) { fReadingVersion = rv; }      
+      void   SetReadingVersion( UInt_t rv ) { fReadingVersion = rv; }
       UInt_t GetReadingVersion() const { return fReadingVersion; }
 
       //void WriteOptionsToStream ( std::ostream& o, const TString& prefix ) const;
@@ -132,7 +133,7 @@ namespace TMVA {
 
    private:
 
-      // sanity check of PDF quality (after smoothing): comparison with 
+      // sanity check of PDF quality (after smoothing): comparison with
       // original histogram
       void     CheckHist() const;
       void     FillSplineToHist();
@@ -140,7 +141,7 @@ namespace TMVA {
       void     SmoothHistogram();
       void     FillHistToGraph();
       Double_t GetIntegral() const;
-      Double_t GetPdfHistBinWidth() const { 
+      Double_t GetPdfHistBinWidth() const {
          TH1* h = GetPDFHist();
          return (fPDFHist) ? (h->GetXaxis()->GetXmax() - h->GetXaxis()->GetXmin())/h->GetNbinsX() : 1;
       }
@@ -148,7 +149,7 @@ namespace TMVA {
       // do we use the original histogram as reference ?
       Bool_t   UseHistogram() const { return fUseHistogram; }
 
-      void FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue, 
+      void FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue,
 			   Double_t y, Bool_t isMonotonouslyIncreasingFunction=kFALSE ) const;
 
 
@@ -156,11 +157,11 @@ namespace TMVA {
 
       // flag that indicates that no splines are produced and no smoothing
       // is applied, i.e., the original histogram is used as reference
-      // this is useful for discrete variables      
+      // this is useful for discrete variables
       Bool_t                   fUseHistogram;  // spline0 uses histogram as reference
-  
+
       // static configuration variables ----------------------------
-      // to increase computation speed, the final PDF is filled in 
+      // to increase computation speed, the final PDF is filled in
       // a high-binned histogram; "GetValue" then returns the histogram
       // entry, linearized between adjacent bins
       static const Int_t       fgNbin_PdfHist;        // number of bins in high-binned reference histogram
@@ -202,17 +203,17 @@ namespace TMVA {
 
       TString                  fSuffix;               //! the suffix for options
       mutable MsgLogger*       fLogger;               //! message logger
-      MsgLogger&               Log() const { return *fLogger; }    
+      MsgLogger&               Log() const { return *fLogger; }
 
       // static pointer to this object
 #if __cplusplus > 199711L
-      static thread_local PDF* fgThisPDF;             // this PDF pointer 
+      static TTHREAD_TLS(PDF*) fgThisPDF;             // this PDF pointer
 #else
-      static PDF*              fgThisPDF;             // this PDF pointer 
+      static PDF*              fgThisPDF;             // this PDF pointer
 #endif
-      static PDF*              ThisPDF( void ); 
+      static PDF*              ThisPDF( void );
 
-      // external auxiliary functions 
+      // external auxiliary functions
       static Double_t          IGetVal( Double_t*, Double_t* );
 
       ClassDef(PDF,1)  // PDF wrapper for histograms
@@ -220,4 +221,4 @@ namespace TMVA {
 
 } // namespace TMVA
 
-#endif 
+#endif
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index 0820339c01c41..dc0f5ac6e7b2f 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -4,9 +4,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *  
- *                                                                                *  
- *                                                                                *  
+ * Description:                                                                   *
+ *                                                                                *
+ *                                                                                *
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  *                                                                                *
@@ -27,7 +27,7 @@
 using namespace TMVA;
 
 #if __cplusplus > 199711L
-thread_local Int_t BDTEventWrapper::fVarIndex = 0;
+TTHREAD_TLS(Int_t) BDTEventWrapper::fVarIndex = 0;
 #else
 Int_t BDTEventWrapper::fVarIndex = 0;
 #endif
@@ -39,7 +39,7 @@ BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
   fSigWeight = 0.0;
 }
 
-BDTEventWrapper::~BDTEventWrapper() { 
+BDTEventWrapper::~BDTEventWrapper() {
    // destructor
 }
 
@@ -49,14 +49,14 @@ void BDTEventWrapper::SetCumulativeWeight(Bool_t type, Double_t weight) {
     * @param fType - true for signal, false for background
     * @param weight - the total weight
     */
-   
+
    if(type) fSigWeight = weight;
    else fBkgWeight = weight;
 }
 
 Double_t BDTEventWrapper::GetCumulativeWeight(Bool_t type) const {
    // Get the accumulated weight
-   
+
    if(type) return fSigWeight;
    return fBkgWeight;
 }
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index dca177c92dbd2..d671bf3968fa2 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -44,6 +44,8 @@
 #include "TMVA/Event.h"
 #include "TMVA/Tools.h"
 
+#include "ThreadLocalStorage.h"
+
 ClassImp(TMVA::BinaryTree)
 
 //_______________________________________________________________________
@@ -175,7 +177,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
       // find parent node
       while( parent!=0 && parent->GetDepth() != currentNode->GetDepth()-1) parent=parent->GetParent();
-      
+
       if (parent!=0) { // link new node to parent
          currentNode->SetParent(parent);
          if (currentNode->GetPos()=='l') parent->SetLeft(currentNode);
@@ -190,7 +192,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
 //_______________________________________________________________________
 std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
-{ 
+{
    // read the tree from an std::istream
    tree.Read(istr);
    return istr;
@@ -199,7 +201,7 @@ std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
 void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 {
    // descend a tree to find all its leaf nodes, fill max depth reached in the
-   // tree at the same time. 
+   // tree at the same time.
 
    if (n == NULL){ //default, start at the tree top, then descend recursively
       n = (Node*) this->GetRoot();
@@ -207,7 +209,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
          Log() << kFATAL << "SetTotalTreeDepth: started with undefined ROOT node" <<Endl;
          return ;
       }
-   } 
+   }
    if (this->GetLeftDaughter(n) != NULL){
       this->SetTotalTreeDepth( this->GetLeftDaughter(n) );
    }
@@ -222,7 +224,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("BinaryTree");
+  static TTHREAD_TLS(MsgLogger) logger("BinaryTree");
 #else
   static MsgLogger logger("BinaryTree");
 #endif
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index 37425a83b94f7..f6102b4066cce 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -46,6 +46,8 @@
 #include "TMVA/Tools.h"
 #include "TMVA/Event.h"
 
+#include "ThreadLocalStorage.h"
+
 using std::string;
 
 ClassImp(TMVA::DecisionTreeNode)
@@ -509,7 +511,7 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+  static TTHREAD_TLS(MsgLogger) logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #else
   static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #endif
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index d89b023679f49..fcfb0b7193e9c 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -54,14 +54,14 @@
 </ul>
 <pre>
 
-    Example:   Interval(.5,1.,6) 
+    Example:   Interval(.5,1.,6)
 
-             [ min                           max ]                       
+             [ min                           max ]
          ------------------------------------------------------------
                 |     |     |     |     |     |
-               .5    .6    .7    .8    .9    1.0            
- 
-         bin    0     1     2     3     4     5  
+               .5    .6    .7    .8    .9    1.0
+
+         bin    0     1     2     3     4     5
 
 
 </pre>
@@ -69,6 +69,7 @@ End_Html */
 
 #include "TMath.h"
 #include "TRandom3.h"
+#include "ThreadLocalStorage.h"
 
 #include "TMVA/Interval.h"
 #include "TMVA/MsgLogger.h"
@@ -76,7 +77,7 @@ End_Html */
 ClassImp(TMVA::Interval)
 
 //_______________________________________________________________________
-TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
+TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) :
    fMin(min),
    fMax(max),
    fNbins(nbins)
@@ -112,9 +113,9 @@ TMVA::Interval::~Interval()
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval. 
+   // calculates the value of the "number" bin in a discrete interval.
    // Parameters:
-   //        Double_t position 
+   //        Double_t position
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
@@ -130,7 +131,7 @@ Double_t TMVA::Interval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete Interval" 
+   // retuns the step size between the numbers of a "discrete Interval"
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
    }
@@ -148,25 +149,25 @@ Double_t TMVA::Interval::GetRndm( TRandom3& rnd )  const
    return rnd.Rndm()*(fMax - fMin) + fMin;
 }
 
-Double_t TMVA::Interval::GetWidth() const 
-{ 
-   return fMax - fMin; 
+Double_t TMVA::Interval::GetWidth() const
+{
+   return fMax - fMin;
 }
-Double_t TMVA::Interval::GetMean()  const 
-{ 
-   return (fMax + fMin)/2; 
+Double_t TMVA::Interval::GetMean()  const
+{
+   return (fMax + fMin)/2;
 }
 
-void TMVA::Interval::Print(std::ostream &os) const 
+void TMVA::Interval::Print(std::ostream &os) const
 {
    for (Int_t i=0; i<GetNbins(); i++){
       os << "| " << GetElement(i)<<" |" ;
-   }  
+   }
 }
 
 TMVA::MsgLogger& TMVA::Interval::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Interval");   // message logger
+  static TTHREAD_TLS(MsgLogger) logger("Interval");   // message logger
 #else
   static MsgLogger logger("Interval");   // message logger
 #endif
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 922ae5ace5991..39514a03fc7d4 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -75,6 +75,7 @@ End_Html */
 
 #include "TMath.h"
 #include "TRandom3.h"
+#include "ThreadLocalStorage.h"
 
 #include "TMVA/LogInterval.h"
 #include "TMVA/MsgLogger.h"
@@ -149,7 +150,7 @@ Double_t TMVA::LogInterval::GetMean()  const
 
 TMVA::MsgLogger& TMVA::LogInterval::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("LogInterval");   // message logger
+  static TTHREAD_TLS(MsgLogger) logger("LogInterval");   // message logger
 #else
   static MsgLogger logger("LogInterval");   // message logger
 #endif
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index 71b7af726cd1a..ab7bae9138a93 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -440,7 +440,7 @@ void TMVA::MethodBase::ProcessBaseOptions()
       SetOptions( fMVAPdfS->GetOptions() );
    }
 
-   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString, 
+   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString,
                                                DataInfo(),
                                                GetTransformationHandler(),
                                                Log() );
@@ -469,8 +469,8 @@ void TMVA::MethodBase::ProcessBaseOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn, 
-                                                 TMVA::DataSetInfo& dataInfo, 
+void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn,
+                                                 TMVA::DataSetInfo& dataInfo,
                                                  TMVA::TransformationHandler& transformationHandler,
                                                  TMVA::MsgLogger& log )
 {
@@ -572,7 +572,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
       if (transformation) {
          ClassInfo* clsInfo = dataInfo.GetClassInfo(idxCls);
          if (clsInfo )
-            log << kINFO << "Create Transformation \"" << trName << "\" with reference class " 
+            log << kINFO << "Create Transformation \"" << trName << "\" with reference class "
                 << clsInfo->GetName() << "=("<< idxCls <<")"<<Endl;
          else
             log << kINFO << "Create Transformation \"" << trName << "\" with events from all classes." << Endl;
@@ -588,7 +588,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
 void TMVA::MethodBase::DeclareCompatibilityOptions()
 {
    // options that are used ONLY for the READER to ensure backward compatibility
-   //   they are hence without any effect (the reader is only reading the training 
+   //   they are hence without any effect (the reader is only reading the training
    //   options that HAD been used at the training of the .xml weightfile at hand
 
    DeclareOptionRef( fNormalise=kFALSE, "Normalise", "Normalise input variables" ); // don't change the default !!!
@@ -622,8 +622,8 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
    // individually (as long as we don't have it automatized via the
    // configuraion string
 
-   Log() << kWARNING << "Parameter optimization is not yet implemented for method " 
-         << GetName() << Endl; 
+   Log() << kWARNING << "Parameter optimization is not yet implemented for method "
+         << GetName() << Endl;
    Log() << kWARNING << "Currently we need to set hardcoded which parameter is tuned in which ranges"<<Endl;
 
    std::map<TString,Double_t> tunedParameters;
@@ -636,7 +636,7 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
 void TMVA::MethodBase::SetTuneParameters(std::map<TString,Double_t> /* tuneParameters */)
 {
    // set the tuning parameters accoding to the argument
-   // This is just a dummy .. have a look at the MethodBDT how you could 
+   // This is just a dummy .. have a look at the MethodBDT how you could
    // perhaps implment the same thing for the other Classifiers..
 }
 
@@ -653,7 +653,7 @@ void TMVA::MethodBase::TrainMethod()
    BaseDir()->cd();
 
    // once calculate all the transformation (e.g. the sequence of Decorr:Gauss:Decorr)
-   //    needed for this classifier 
+   //    needed for this classifier
    GetTransformationHandler().CalcTransformations(Data()->GetEventCollection());
 
    // call training of derived MVA
@@ -681,9 +681,9 @@ void TMVA::MethodBase::TrainMethod()
          CreateMVAPdfs();
          AddClassifierOutputProb(Types::kTraining);
       }
-      
+
    } else {
-      
+
       Log() << "regression on training sample" << Endl;
       AddRegressionOutput( Types::kTraining );
 
@@ -707,7 +707,7 @@ void TMVA::MethodBase::TrainMethod()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const 
+void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const
 {
    if (!DoRegression()) Log() << kFATAL << "Trying to use GetRegressionDeviation() with a classification job" << Endl;
    Log() << kINFO << "Create results for " << (type==Types::kTraining?"training":"testing") << Endl;
@@ -820,16 +820,16 @@ Double_t TMVA::MethodBase::GetMvaValue( const Event* const ev, Double_t* err, Do
 }
 
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike() { 
+Bool_t TMVA::MethodBase::IsSignalLike() {
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event would be selected as signal or background
-   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
+   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
 }
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) { 
+Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) {
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event with this mva output value would tbe selected as signal or background
-   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
+   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
 }
 
 //_______________________________________________________________________
@@ -854,7 +854,7 @@ void TMVA::MethodBase::AddClassifierOutput( Types::ETreeType type )
    for (Int_t ievt=0; ievt<nEvents; ievt++) {
       Data()->SetCurrentEvent(ievt);
       clRes->SetValue( GetMvaValue(), ievt );
-      
+
       // print progress
       Int_t modulo = Int_t(nEvents/100);
       if (modulo <= 0 ) modulo = 1;
@@ -877,7 +877,7 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 
    Data()->SetCurrentType(type);
 
-   ResultsClassification* mvaProb = 
+   ResultsClassification* mvaProb =
       (ResultsClassification*)Data()->GetResults(TString("prob_")+GetMethodName(), type, Types::kClassification );
 
    Long64_t nEvents = Data()->GetNEvents();
@@ -907,15 +907,15 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT, 
-                                       Double_t& dev,  Double_t& devT, 
-                                       Double_t& rms,  Double_t& rmsT, 
+void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
+                                       Double_t& dev,  Double_t& devT,
+                                       Double_t& rms,  Double_t& rmsT,
                                        Double_t& mInf, Double_t& mInfT,
-                                       Double_t& corr, 
+                                       Double_t& corr,
                                        Types::ETreeType type )
 {
-   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample 
-   //                    
+   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample
+   //
    //   bias = average deviation
    //   dev  = average absolute deviation
    //   rms  = rms of deviation
@@ -933,7 +933,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    Float_t* wV = new Float_t[nevt];
    Float_t  xmin = 1e30, xmax = -1e30;
    for (Long64_t ievt=0; ievt<nevt; ievt++) {
-      
+
       const Event* ev = Data()->GetEvent(ievt); // NOTE: need untransformed event here !
       Float_t t = ev->GetTarget(0);
       Float_t w = ev->GetWeight();
@@ -948,7 +948,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
       rV[ievt] = r;
       tV[ievt] = t;
       wV[ievt] = w;
-      
+
       // compute deviation-squared
       sumw += w;
       bias += w * d;
@@ -968,8 +968,8 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    rms  = TMath::Sqrt(rms - bias*bias);
 
    // correlation
-   m1   /= sumw; 
-   m2   /= sumw; 
+   m1   /= sumw;
+   m2   /= sumw;
    corr  = s12/sumw - m1*m2;
    corr /= TMath::Sqrt( (s1/sumw - m1*m1) * (s2/sumw - m2*m2) );
 
@@ -989,11 +989,11 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
          sumw  += wV[ievt];
          biasT += wV[ievt] * d;
          devT  += wV[ievt] * TMath::Abs(d);
-         rmsT  += wV[ievt] * d * d;       
+         rmsT  += wV[ievt] * d * d;
          histT->Fill( rV[ievt], tV[ievt], wV[ievt] );
          ic++;
       }
-   }   
+   }
    biasT /= sumw;
    devT  /= sumw;
    rmsT  /= sumw;
@@ -1008,14 +1008,14 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    delete [] tV;
    delete [] wV;
 
-   Data()->SetCurrentType(savedType);   
+   Data()->SetCurrentType(savedType);
 }
 
 
 //_______________________________________________________________________
 void TMVA::MethodBase::TestMulticlass()
 {
-   // test multiclass classification 
+   // test multiclass classification
 
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in TestMulticlass, exiting."<<Endl;
@@ -1034,7 +1034,7 @@ void TMVA::MethodBase::TestClassification()
 
    ResultsClassification* mvaRes = dynamic_cast<ResultsClassification*>
       ( Data()->GetResults(GetMethodName(),Types::kTesting, Types::kClassification) );
-   
+
    // sanity checks: tree must exist, and theVar must be in tree
    if (0==mvaRes && !(GetMethodTypeName().Contains("Cuts"))) {
       Log() << "mvaRes " << mvaRes << " GetMethodTypeName " << GetMethodTypeName()
@@ -1042,24 +1042,24 @@ void TMVA::MethodBase::TestClassification()
       Log() << kFATAL << "<TestInit> Test variable " << GetTestvarName()
             << " not found in tree" << Endl;
    }
-   
+
    // basic statistics operations are made in base class
    gTools().ComputeStat( GetEventCollection(Types::kTesting), mvaRes->GetValueVector(),
                          fMeanS, fMeanB, fRmsS, fRmsB, fXmin, fXmax, fSignalClass );
-   
+
    // choose reasonable histogram ranges, by removing outliers
    Double_t nrms = 10;
    fXmin = TMath::Max( TMath::Min( fMeanS - nrms*fRmsS, fMeanB - nrms*fRmsB ), fXmin );
    fXmax = TMath::Min( TMath::Max( fMeanS + nrms*fRmsS, fMeanB + nrms*fRmsB ), fXmax );
-   
+
    // determine cut orientation
    fCutOrientation = (fMeanS > fMeanB) ? kPositive : kNegative;
 
    // fill 2 types of histograms for the various analyses
    // this one is for actual plotting
-   
+
    Double_t sxmax = fXmax+0.00001;
-   
+
    // classifier response distributions for training sample
    // MVA plots used for graphics representation (signal)
    TH1* mva_s = new TH1D( GetTestvarName() + "_S",GetTestvarName() + "_S", fNbinsMVAoutput, fXmin, sxmax );
@@ -1090,7 +1090,7 @@ void TMVA::MethodBase::TestClassification()
       rarity_s->Sumw2();
       rarity_b->Sumw2();
    }
-   
+
    // MVA plots used for efficiency calculations (large number of bins)
    TH1* mva_eff_s = new TH1D( GetTestvarName() + "_S_high", GetTestvarName() + "_S_high", fNbinsH, fXmin, sxmax );
    TH1* mva_eff_b = new TH1D( GetTestvarName() + "_B_high", GetTestvarName() + "_B_high", fNbinsH, fXmin, sxmax );
@@ -1098,26 +1098,26 @@ void TMVA::MethodBase::TestClassification()
    mvaRes->Store(mva_eff_b, "MVA_HIGHBIN_B");
    mva_eff_s->Sumw2();
    mva_eff_b->Sumw2();
-   
+
    // fill the histograms
    ResultsClassification* mvaProb = dynamic_cast<ResultsClassification*>
       (Data()->GetResults( TString("prob_")+GetMethodName(), Types::kTesting, Types::kMaxAnalysisType ) );
-   
+
    Log() << kINFO << "Loop over test events and fill histograms with classifier response..." << Endl;
    if (mvaProb) Log() << kINFO << "Also filling probability and rarity histograms (on request)..." << Endl;
    for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
-      
+
       const Event* ev = GetEvent(ievt);
       Float_t v = (*mvaRes)[ievt][0];
       Float_t w = ev->GetWeight();
-      
+
       if (DataInfo().IsSignal(ev)) {
          mva_s ->Fill( v, w );
          if (mvaProb) {
             proba_s->Fill( (*mvaProb)[ievt][0], w );
             rarity_s->Fill( GetRarity( v ), w );
          }
-         
+
          mva_eff_s ->Fill( v, w );
       }
       else {
@@ -1129,7 +1129,7 @@ void TMVA::MethodBase::TestClassification()
          mva_eff_b ->Fill( v, w );
       }
    }
-   
+
    // uncomment those (and several others if you want unnormalized output
    gTools().NormHist( mva_s  );
    gTools().NormHist( mva_b  );
@@ -1139,7 +1139,7 @@ void TMVA::MethodBase::TestClassification()
    gTools().NormHist( rarity_b );
    gTools().NormHist( mva_eff_s  );
    gTools().NormHist( mva_eff_b  );
-   
+
    // create PDFs from histograms, using default splines, and no additional smoothing
    if (fSplS) { delete fSplS; fSplS = 0; }
    if (fSplB) { delete fSplB; fSplB = 0; }
@@ -1188,7 +1188,7 @@ void TMVA::MethodBase::WriteStateToStream( std::ostream& tf ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const 
+void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const
 {
    // xml writing
    void* it = gTools().AddChild(gi,"Info");
@@ -1247,7 +1247,7 @@ void TMVA::MethodBase::WriteStateToXML( void* parent ) const
 
    // write class info if in multiclass mode
    AddClassesXMLTo(parent);
-   
+
    // write target info if in regression mode
    if (DoRegression()) AddTargetsXMLTo(parent);
 
@@ -1357,7 +1357,7 @@ void TMVA::MethodBase::ReadStateFromXMLString( const char* xmlstr ) {
    ReadStateFromXML(rootnode);
    gTools().xmlengine().FreeDoc(doc);
 #else
-   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = " 
+   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = "
          << xmlstr << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
 #endif
 
@@ -1638,9 +1638,9 @@ void TMVA::MethodBase::ReadVarsFromStream( std::istream& istr )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
 {
-   // write variable info to XML 
+   // write variable info to XML
    void* vars = gTools().AddChild(parent, "Variables");
    gTools().AddAttr( vars, "NVar", gTools().StringFromInt(DataInfo().GetNVariables()) );
 
@@ -1653,9 +1653,9 @@ void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
 {
-   // write spectator info to XML 
+   // write spectator info to XML
    void* specs = gTools().AddChild(parent, "Spectators");
 
    UInt_t writeIdx=0;
@@ -1675,14 +1675,14 @@ void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
 {
-   // write class info to XML 
+   // write class info to XML
    UInt_t nClasses=DataInfo().GetNClasses();
-   
+
    void* classes = gTools().AddChild(parent, "Classes");
    gTools().AddAttr( classes, "NClass", nClasses );
-   
+
    for (UInt_t iCls=0; iCls<nClasses; ++iCls) {
       ClassInfo *classInfo=DataInfo().GetClassInfo (iCls);
       TString  className  =classInfo->GetName();
@@ -1694,9 +1694,9 @@ void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
    }
 }
 //_______________________________________________________________________
-void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
 {
-   // write target info to XML 
+   // write target info to XML
    void* targets = gTools().AddChild(parent, "Targets");
    gTools().AddAttr( targets, "NTrgt", gTools().StringFromInt(DataInfo().GetNTargets()) );
 
@@ -1709,7 +1709,7 @@ void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadVariablesFromXML( void* varnode ) 
+void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
 {
    // read variable info from XML
    UInt_t readNVar;
@@ -1729,11 +1729,11 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
       gTools().ReadAttr( ch, "VarIndex", varIdx);
       existingVarInfo = DataInfo().GetVariableInfos()[varIdx];
       readVarInfo.ReadFromXML(ch);
-      
+
       if (existingVarInfo.GetExpression() == readVarInfo.GetExpression()) {
          readVarInfo.SetExternalLink(existingVarInfo.GetExternalLink());
          existingVarInfo = readVarInfo;
-      } 
+      }
       else {
          Log() << kINFO << "ERROR in <ReadVariablesFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the variables found in the input file is"  << Endl;
@@ -1748,7 +1748,7 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode ) 
+void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
 {
    // read spectator info from XML
    UInt_t readNSpec;
@@ -1768,11 +1768,11 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
       gTools().ReadAttr( ch, "SpecIndex", specIdx);
       existingSpecInfo = DataInfo().GetSpectatorInfos()[specIdx];
       readSpecInfo.ReadFromXML(ch);
-      
+
       if (existingSpecInfo.GetExpression() == readSpecInfo.GetExpression()) {
          readSpecInfo.SetExternalLink(existingSpecInfo.GetExternalLink());
          existingSpecInfo = readSpecInfo;
-      } 
+      }
       else {
          Log() << kINFO << "ERROR in <ReadSpectatorsFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the spectators found in the input file is"  << Endl;
@@ -1787,7 +1787,7 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadClassesFromXML( void* clsnode ) 
+void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
 {
    // read number of classes from XML
    UInt_t readNCls;
@@ -1828,7 +1828,7 @@ void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode ) 
+void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode )
 {
    // read target info from XML
    UInt_t readNTar;
@@ -1935,7 +1935,7 @@ TString TMVA::MethodBase::GetWeightFileName() const
    // directory/jobname_methodname_suffix.extension.{root/txt}
    TString suffix = "";
    TString wFileDir(GetWeightFileDir());
-   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/") 
+   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/")
             + GetJobName() + "_" + GetMethodName() +
             suffix + "." + gConfig().GetIONames().fWeightFileExtension + ".xml" );
 }
@@ -1962,7 +1962,7 @@ void TMVA::MethodBase::WriteEvaluationHistosToFile(Types::ETreeType treetype)
    Results* results = Data()->GetResults( GetMethodName(), treetype, Types::kMaxAnalysisType );
    if (!results)
       Log() << kFATAL << "<WriteEvaluationHistosToFile> Unknown result: "
-            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting") 
+            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting")
             << "/kMaxAnalysisType" << Endl;
    results->GetStorage()->Write();
    if (treetype==Types::kTesting) {
@@ -2013,8 +2013,8 @@ Bool_t TMVA::MethodBase::GetLine(std::istream& fin, char* buf )
       else if (analysisType == "multiclass"     || analysisType == "Multiclass")     SetAnalysisType( Types::kMulticlass );
       else Log() << kFATAL << "Analysis type " << analysisType << " from weight-file not known!" << std::endl;
 
-      Log() << kINFO << "Method was trained for " 
-            << (GetAnalysisType() == Types::kRegression ? "Regression" : 
+      Log() << kINFO << "Method was trained for "
+            << (GetAnalysisType() == Types::kRegression ? "Regression" :
                 (GetAnalysisType() == Types::kMulticlass ? "Multiclass" : "Classification")) << Endl;
    }
 
@@ -2094,7 +2094,7 @@ Double_t TMVA::MethodBase::GetProba(const Event *ev){
    }
    Double_t sigFraction = DataInfo().GetTrainingSumSignalWeights() / (DataInfo().GetTrainingSumSignalWeights() + DataInfo().GetTrainingSumBackgrWeights() );
    Double_t mvaVal = GetMvaValue(ev);
-   
+
    return GetProba(mvaVal,sigFraction);
 
 }
@@ -2172,7 +2172,7 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
 #if __cplusplus > 199711L
-   static thread_local Double_t nevtS;
+   static TTHREAD_TLS(Double_t) nevtS;
 #else
    static Double_t nevtS;
 #endif
@@ -2479,7 +2479,7 @@ Double_t TMVA::MethodBase::GetTrainingEfficiency(const TString& theString)
       // note that there is a bin shift when going from a TH1D object to a TGraph :-(
       if (Use_Splines_for_Eff_) {
          if (fSplTrainRefS) delete fSplTrainRefS;
-         if (fSplTrainRefB) delete fSplTrainRefB;         
+         if (fSplTrainRefB) delete fSplTrainRefB;
          fSplTrainRefS  = new TSpline1( "spline2_signal",     new TGraph( mva_eff_tr_s ) );
          fSplTrainRefB  = new TSpline1( "spline2_background", new TGraph( mva_eff_tr_b ) );
 
@@ -2548,8 +2548,8 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassEfficiency(std::vector<std::
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassEfficiency, exiting."<<Endl;
 
-   purity.push_back(resMulticlass->GetAchievablePur()); 
-   return resMulticlass->GetAchievableEff(); 
+   purity.push_back(resMulticlass->GetAchievablePur());
+   return resMulticlass->GetAchievableEff();
 }
 
 //_______________________________________________________________________
@@ -2559,14 +2559,14 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassTrainingEfficiency(std::vect
    Data()->SetCurrentType(Types::kTraining);
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTraining, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassTrainingEfficiency, exiting."<<Endl;
-   
+
    Log() << kINFO << "Determine optimal multiclass cuts for training data..." << Endl;
    for (UInt_t icls = 0; icls<DataInfo().GetNClasses(); ++icls) {
       resMulticlass->GetBestMultiClassCuts(icls);
    }
-    
-   purity.push_back(resMulticlass->GetAchievablePur()); 
-   return resMulticlass->GetAchievableEff(); 
+
+   purity.push_back(resMulticlass->GetAchievablePur());
+   return resMulticlass->GetAchievableEff();
 }
 
 
@@ -2637,10 +2637,10 @@ Double_t TMVA::MethodBase::GetROCIntegral(TH1D *histS, TH1D *histB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   } 
+   }
    return integral*step;
 }
-   
+
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
@@ -2667,7 +2667,7 @@ Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   } 
+   }
    return integral*step;
 }
 
@@ -2996,7 +2996,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "                 varIt != inputValues.end(); varIt++, ivar++) {" << std::endl;
    fout << "               iV.push_back(NormVariable( *varIt, fVmin[ivar], fVmax[ivar] ));" << std::endl;
    fout << "            }" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            Transform( iV, -1 );" << std::endl;
@@ -3004,7 +3004,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "            retval = GetMvaValue__( iV );" << std::endl;
    fout << "         }" << std::endl;
    fout << "         else {" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            std::vector<double> iV;" << std::endl;
@@ -3090,7 +3090,7 @@ void TMVA::MethodBase::PrintHelpMessage() const
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
 #if __cplusplus > 199711L
-thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
+TTHREAD_TLS(TMVA::MethodBase*) TMVA::MethodBase::fgThisBase = 0;
 #else
 TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
 #endif
@@ -3128,18 +3128,18 @@ Double_t TMVA::MethodBase::GetEffForRoot( Double_t theCut )
 }
 
 //_______________________________________________________________________
-const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type) 
+const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type)
 {
    // returns the event collection (i.e. the dataset) TRANSFORMED using the
    //   classifiers specific Variable Transformation (e.g. Decorr or Decorr:Gauss:Decorr)
 
-   // if there's no variable transformation for this classifier, just hand back the 
+   // if there's no variable transformation for this classifier, just hand back the
    //  event collection of the data set
    if (GetTransformationHandler().GetTransformationList().GetEntries() <= 0) {
       return (Data()->GetEventCollection(type));
-   } 
+   }
 
-   // otherwise, transform ALL the events and hand back the vector of the pointers to the 
+   // otherwise, transform ALL the events and hand back the vector of the pointers to the
    // transformed events. If the pointer is already != 0, i.e. the whole thing has been
    // done before, I don't need to do it again, but just "hand over" the pointer to those events.
    Int_t idx = Data()->TreeIndex(type);  //index indicating Training,Testing,...  events/datasets
@@ -3171,19 +3171,19 @@ TString TMVA::MethodBase::GetTrainingROOTVersionString() const
 
    return TString(Form("%i.%02i/%02i",a,b,c));
 }
- 
+
 //_______________________________________________________________________
 TMVA::MethodBase* TMVA::MethodBase::GetThisBase()
 {
    // return a pointer the base class of this method
-   return fgThisBase; 
+   return fgThisBase;
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ResetThisBase() 
-{ 
+void TMVA::MethodBase::ResetThisBase()
+{
    // reset required for RootFinder
-   fgThisBase = this; 
+   fgThisBase = this;
 }
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
@@ -3198,7 +3198,7 @@ Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
      TH1D *mva_b_tr = dynamic_cast<TH1D*> (mvaRes->GetHist("MVA_TRAIN_B"));
 
      if ( !mva_s || !mva_b || !mva_s_tr || !mva_b_tr) return -1;
- 
+
      if (SorB == 's' || SorB == 'S')
        return mva_s->KolmogorovTest( mva_s_tr, opt.Data() );
      else
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 9e4f58143e1b5..91e33c05d7674 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -85,10 +85,10 @@ TMVA::MethodMLP::MethodMLP( const TString& jobName,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -107,10 +107,10 @@ TMVA::MethodMLP::MethodMLP( DataSetInfo& theData,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -221,13 +221,13 @@ void TMVA::MethodMLP::ProcessOptions()
    // process user options
    MethodANNBase::ProcessOptions();
 
-   
+
    if (IgnoreEventsWithNegWeightsInTraining()) {
-      Log() << kINFO 
+      Log() << kINFO
             << "Will ignore negative events in training!"
             << Endl;
    }
-   
+
 
    if      (fTrainMethodS == "BP"  ) fTrainingMethod = kBP;
    else if (fTrainMethodS == "BFGS") fTrainingMethod = kBFGS;
@@ -301,8 +301,8 @@ Double_t TMVA::MethodMLP::CalculateEstimator( Types::ETreeType treeType, Int_t i
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event* ev = GetEvent(i);
-      
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (saveType == Types::kTraining)){
          continue;
       }
@@ -419,7 +419,7 @@ void TMVA::MethodMLP::Train(Int_t nEpochs)
 
    Int_t nEvents=GetNEvents();
    Int_t nSynapses=fSynapses->GetEntriesFast();
-   if (nSynapses>nEvents) 
+   if (nSynapses>nEvents)
       Log()<<kWARNING<<"ANN too complicated: #events="<<nEvents<<"\t#synapses="<<nSynapses<<Endl;
 
 #ifdef MethodMLP_UseMinuit__
@@ -661,7 +661,7 @@ void TMVA::MethodMLP::ComputeDEDw()
    for (Int_t i=0;i<nEvents;i++) {
 
       const Event* ev = GetEvent(i);
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          --nPosEvents;
          continue;
@@ -810,7 +810,7 @@ Bool_t TMVA::MethodMLP::LineSearch(TMatrixD &Dir, std::vector<Double_t> &buffer,
 
    SetDirWeights( Origin, Dir, alpha2 );
    Double_t err2 = GetError();
-   //Double_t err2 = err1; 
+   //Double_t err2 = err1;
    Double_t err3 = err2;
    Bool_t bingo = kFALSE;
 
@@ -918,7 +918,7 @@ Double_t TMVA::MethodMLP::GetError()
    for (Int_t i=0;i<nEvents;i++) {
       const Event* ev = GetEvent(i);
 
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
@@ -1089,11 +1089,11 @@ void TMVA::MethodMLP::TrainOneEpoch()
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event * ev = GetEvent(index[i]);
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
-      
+
       TrainOneEvent(index[i]);
 
       // do adjustments if in batch mode
@@ -1146,7 +1146,7 @@ void TMVA::MethodMLP::DecaySynapseWeights(Bool_t lateEpoch)
    TSynapse* synapse;
    Int_t numSynapses = fSynapses->GetEntriesFast();
    for (Int_t i = 0; i < numSynapses; i++) {
-      synapse = (TSynapse*)fSynapses->At(i);      
+      synapse = (TSynapse*)fSynapses->At(i);
       if (lateEpoch) synapse->DecayLearningRate(TMath::Sqrt(fDecayRate)); // In order to lower the learning rate even more, we need to apply sqrt instead of square.
       else           synapse->DecayLearningRate(fDecayRate);
    }
@@ -1160,13 +1160,13 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    GetEvent(ievt);
 
    // as soon as we know how to get event weights, get that here
-   
+
    // note: the normalization of event weights will affect the choice
    // of learning rate, one will have to experiment to get the right value.
    // in general, if the "average" event weight is 1, the learning rate
    // should be good if set around 0.02 (a good value if all event weights are 1)
    Double_t eventWeight = 1.0;
-   
+
    // get the desired output of this event
    Double_t desired;
    if (type == 0) desired = fOutput->GetMin();  // background //zjh
@@ -1175,7 +1175,7 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    // force the value for each input neuron
    Double_t x;
    TNeuron* neuron;
-   
+
    for (UInt_t j = 0; j < GetNvar(); j++) {
       x = branchVar[j];
       if (IsNormalised()) x = gTools().NormVariable( x, GetXmin( j ), GetXmax( j ) );
@@ -1260,7 +1260,7 @@ void TMVA::MethodMLP::CalculateNeuronDeltas()
    for (Int_t i = numLayers-1; i >= 0; i--) {
       curLayer = (TObjArray*)fNetwork->At(i);
       numNeurons = curLayer->GetEntriesFast();
-  
+
       for (Int_t j = 0; j < numNeurons; j++) {
          neuron = (TNeuron*) curLayer->At(j);
          neuron->CalculateDelta();
@@ -1498,7 +1498,7 @@ Double_t TMVA::MethodMLP::GetMvaValue( Double_t* errLower, Double_t* errUpper )
      variance=0;
    }
    variance=sqrt(variance);
- 
+
    //upper
    MvaUpper=fOutput->Eval(median+variance);
    if(errUpper)
@@ -1584,8 +1584,8 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
 }
 
 #if __cplusplus > 199711L
-static thread_local Int_t  nc   = 0;
-static thread_local double minf = 1000000;
+static TTHREAD_TLS(Int_t)  nc   = 0;
+static TTHREAD_TLS(Double_t) minf = 1000000;
 #else
 static Int_t  nc   = 0;
 static double minf = 1000000;
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 96d03cc58b61f..9281f2b414014 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -88,7 +88,7 @@ namespace TMVA {
 };
 
 #if __cplusplus > 199711L
-thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
+TTHREAD_TLS(TMVA::MethodPDERS*) TMVA::MethodPDERS::fgThisPDERS = NULL;
 #else
 TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
 #endif
@@ -189,7 +189,7 @@ void TMVA::MethodPDERS::Init( void )
    fInitialScale    = 0.99;
    fGaussSigma      = 0.1;
    fNormTree        = kFALSE;
-    
+
    fkNNMin      = Int_t(fNEventsMin);
    fkNNMax      = Int_t(fNEventsMax);
 
@@ -211,12 +211,12 @@ TMVA::MethodPDERS::~MethodPDERS( void )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::DeclareOptions() 
+void TMVA::MethodPDERS::DeclareOptions()
 {
-   // define the options (their key words) that can be set in the option string 
+   // define the options (their key words) that can be set in the option string
    // know options:
    // VolumeRangeMode   <string>  Method to determine volume range
-   //    available values are:        MinMax 
+   //    available values are:        MinMax
    //                                 Unscaled
    //                                 RMS
    //                                 kNN
@@ -239,10 +239,10 @@ void TMVA::MethodPDERS::DeclareOptions()
    //                                 Trim
    //
    // DeltaFrac         <float>   Ratio of #EventsMin/#EventsMax for MinMax and RMS volume range
-   // NEventsMin        <int>     Minimum number of events for adaptive volume range             
+   // NEventsMin        <int>     Minimum number of events for adaptive volume range
    // NEventsMax        <int>     Maximum number of events for adaptive volume range
    // MaxVIterations    <int>     Maximum number of iterations for adaptive volume range
-   // InitialScale      <float>   Initial scale for adaptive volume range           
+   // InitialScale      <float>   Initial scale for adaptive volume range
    // GaussSigma        <float>   Width with respect to the volume size of Gaussian kernel estimator
    DeclareOptionRef(fVolumeRange="Adaptive", "VolumeRangeMode", "Method to determine volume size");
    AddPreDefVal(TString("Unscaled"));
@@ -277,13 +277,13 @@ void TMVA::MethodPDERS::DeclareOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::ProcessOptions() 
+void TMVA::MethodPDERS::ProcessOptions()
 {
    // process the options specified by the user
-   
+
    if (IgnoreEventsWithNegWeightsInTraining()) {
       Log() << kFATAL << "Mechanism to ignore events with negative weights in training not yet available for method: "
-            << GetMethodTypeName() 
+            << GetMethodTypeName()
             << " --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
             << Endl;
    }
@@ -342,13 +342,13 @@ void TMVA::MethodPDERS::Train( void )
    // trainingTree in the weight file, and to rebuild the binary tree in the
    // test phase from scratch
 
-   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; " 
+   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; "
                                << "please remove the option from the configuration string, or "
                                << "use \"!Normalise\""
                                << Endl;
 
    CreateBinarySearchTree( Types::kTraining );
-    
+
    CalcAverages();
    SetVolumeElement();
 
@@ -425,7 +425,7 @@ void TMVA::MethodPDERS::CalcAverages()
       fAverageRMS.clear();
       fBinaryTree->CalcStatistics();
 
-      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) { 
+      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
          if (!DoRegression()){ //why there are separate rms for signal and background?
             Float_t rmsS = fBinaryTree->RMS(Types::kSignal, ivar);
             Float_t rmsB = fBinaryTree->RMS(Types::kBackground, ivar);
@@ -436,7 +436,7 @@ void TMVA::MethodPDERS::CalcAverages()
          }
       }
    }
-}   
+}
 
 //_______________________________________________________________________
 void TMVA::MethodPDERS::CreateBinarySearchTree( Types::ETreeType type )
@@ -474,7 +474,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    // init relative scales
    fkNNMin      = Int_t(fNEventsMin);
-   fkNNMax      = Int_t(fNEventsMax);   
+   fkNNMax      = Int_t(fNEventsMax);
 
    if (fDelta) delete fDelta;
    if (fShift) delete fShift;
@@ -483,7 +483,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       switch (fVRangeMode) {
-         
+
       case kRMS:
       case kkNN:
       case kAdaptive:
@@ -778,7 +778,7 @@ Double_t TMVA::MethodPDERS::CRScalc( const Event& e )
    }
 
    Volume *volume = new Volume( lb, ub );
-   
+
    GetSample( e, events, volume );
    Double_t count = CKernelEstimate( e, events, *volume );
    delete volume;
@@ -948,22 +948,22 @@ Double_t TMVA::MethodPDERS::ApplyKernelFunction (Double_t normalized_distance)
 
    return 0;
 }
-      
+
 //_______________________________________________________________________
-Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf) 
+Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 {
-   // Calculating the normalization factor only once (might need a reset at some point. 
+   // Calculating the normalization factor only once (might need a reset at some point.
    // Can the method be restarted with different params?)
 
-   // Caching jammed to disable function. 
+   // Caching jammed to disable function.
    // It's not really useful afterall, badly implemented and untested :-)
 #if __cplusplus > 199711L
-   static thread_local Double_t ret = 1.0; 
+   static TTHREAD_TLS(Double_t) ret = 1.0;
 #else
-   static Double_t ret = 1.0; 
+   static Double_t ret = 1.0;
 #endif
-   
-   if (ret != 0.0) return ret*pdf; 
+
+   if (ret != 0.0) return ret*pdf;
 
    // We first normalize by the volume of the hypersphere.
    switch (fKernelEstimator) {
@@ -1005,7 +1005,7 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 //_______________________________________________________________________
 Double_t TMVA::MethodPDERS::GetNormalizedDistance ( const Event &base_event,
                                                     const BinarySearchTreeNode &sample_event,
-                                                    Double_t *dim_normalization) 
+                                                    Double_t *dim_normalization)
 {
    // We use Euclidian metric here. Might not be best or most efficient.
    Double_t ret=0;
@@ -1155,16 +1155,16 @@ void TMVA::MethodPDERS::ReadWeightsFromStream( TFile& /*rf*/ )
 }
 
 //_______________________________________________________________________
-TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void ) 
-{ 
+TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void )
+{
    // static pointer to this object
-   return fgThisPDERS; 
+   return fgThisPDERS;
 }
 //_______________________________________________________________________
-void TMVA::MethodPDERS::UpdateThis( void ) 
+void TMVA::MethodPDERS::UpdateThis( void )
 {
    // update static this pointer
-   fgThisPDERS = this; 
+   fgThisPDERS = this;
 }
 
 //_______________________________________________________________________
@@ -1180,7 +1180,7 @@ void TMVA::MethodPDERS::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line: 
+   // typical length of text line:
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index e6ee4baca6918..8925db79de4e3 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -129,7 +129,7 @@ void TMVA::MethodTMlpANN::Init( void )
 //_______________________________________________________________________
 TMVA::MethodTMlpANN::~MethodTMlpANN( void )
 {
-   // destructor 
+   // destructor
    if (fMLP) delete fMLP;
 }
 
@@ -224,7 +224,7 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
 #if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
+   static TTHREAD_TLS(Double_t*) d = new Double_t[Data()->GetNVariables()];
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
 #endif
@@ -258,17 +258,17 @@ void TMVA::MethodTMlpANN::Train( void )
    Int_t type;
    Float_t weight;
    const Long_t basketsize = 128000;
-   Float_t* vArr = new Float_t[GetNvar()]; 
+   Float_t* vArr = new Float_t[GetNvar()];
 
    TTree *localTrainingTree = new TTree( "TMLPtrain", "Local training tree for TMlpANN" );
    localTrainingTree->Branch( "type",       &type,        "type/I",        basketsize );
    localTrainingTree->Branch( "weight",     &weight,      "weight/F",      basketsize );
-   
+
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       const char* myVar = GetInternalVarName(ivar).Data();
       localTrainingTree->Branch( myVar, &vArr[ivar], Form("Var%02i/F", ivar), basketsize );
    }
-   
+
    for (UInt_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
       const Event *ev = GetEvent(ievt);
       for (UInt_t i=0; i<GetNvar(); i++) {
@@ -399,15 +399,15 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
          }
       }
       if (strcmp(gTools().GetName(ch),"neurons")==0) {
-         fout << "#neurons weights" << std::endl;         
+         fout << "#neurons weights" << std::endl;
          while (content >> temp1) {
             fout << temp1 << std::endl;
          }
       }
       if (strcmp(gTools().GetName(ch),"synapses")==0) {
-         fout << "#synapses weights" ;         
+         fout << "#synapses weights" ;
          while (content >> temp1) {
-            fout << std::endl << temp1 ;                
+            fout << std::endl << temp1 ;
          }
       }
       ch = gTools().GetNextChild(ch);
@@ -417,8 +417,8 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
 #if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
-   static thread_local Int_t type;
+   static TTHREAD_TLS(Double_t*) d = new Double_t[Data()->GetNVariables()] ;
+   static TTHREAD_TLS(Int_t) type;
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
@@ -436,7 +436,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    fMLP = new TMultiLayerPerceptron( fMLPBuildOptions.Data(), dummyTree );
    fMLP->LoadWeights( fname );
 }
- 
+
 //_______________________________________________________________________
 void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
 {
@@ -450,7 +450,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    // the MLP is already build
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
-   Double_t* d = new Double_t[Data()->GetNVariables()] ; 
+   Double_t* d = new Double_t[Data()->GetNVariables()] ;
    Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -499,7 +499,7 @@ void TMVA::MethodTMlpANN::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line: 
+   // typical length of text line:
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index 2160b5dfee708..e803c16c36076 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Rustem Ospanov 
+// Author: Rustem Ospanov
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -14,8 +14,8 @@
  *      Rustem Ospanov <rustem@fnal.gov> - U. of Texas at Austin, USA             *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
- *      CERN, Switzerland                                                         * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      MPI-K Heidelberg, Germany                                                 *
  *      U. of Texas at Austin, USA                                                *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -33,12 +33,13 @@
 #include <algorithm>
 
 #include "TMath.h"
+#include "ThreadLocalStorage.h"
 
 // TMVA
 #include "TMVA/MsgLogger.h"
- 
+
 //-------------------------------------------------------------------------------------------
-TMVA::kNN::Event::Event() 
+TMVA::kNN::Event::Event()
    :fVar(),
     fWeight(-1.0),
     fType(-1)
@@ -81,12 +82,12 @@ TMVA::kNN::VarType TMVA::kNN::Event::GetDist(const Event &other) const
       std::cerr << "Distance: two events have different dimensions" << std::endl;
       return -1.0;
    }
-   
+
    VarType sum = 0.0;
    for (UInt_t ivar = 0; ivar < nvar; ++ivar) {
       sum += GetDist(other.GetVar(ivar), ivar);
    }
-   
+
    return sum;
 }
 
@@ -154,7 +155,7 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
 
 
 #if __cplusplus > 199711L
-thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
+TTHREAD_TLS(TRandom3) TMVA::kNN::ModulekNN::fgRndm(1);
 #else
 TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
 #endif
@@ -197,11 +198,11 @@ void TMVA::kNN::ModulekNN::Clear()
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::Add(const Event &event)
-{   
+{
    // add an event to tree
    if (fTree) {
       Log() << kFATAL << "<Add> Cannot add event: tree is already built" << Endl;
-      return;      
+      return;
    }
 
    if (fDimn < 1) {
@@ -234,7 +235,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    if (fTree) {
       Log() << kFATAL << "ModulekNN::Fill - tree has already been created" << Endl;
       return kFALSE;
-   }   
+   }
 
    // If trim option is set then find class with lowest number of events
    // and set that as maximum number of events for all other classes.
@@ -245,14 +246,14 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
             min = it->second;
          }
       }
-      
+
       Log() << kINFO << "<Fill> Will trim all event types to " << min << " events" << Endl;
-      
+
       fCount.clear();
       fVar.clear();
-      
+
       EventVec evec;
-      
+
       for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
          std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
          if (cit == fCount.end()) {
@@ -273,7 +274,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
       }
 
       Log() << kINFO << "<Fill> Erased " << fEvent.size() - evec.size() << " events" << Endl;
-      
+
       fEvent = evec;
    }
 
@@ -287,7 +288,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
 
    if (option.find("metric") != std::string::npos && ifrac > 0) {
       ComputeMetric(ifrac);
-      
+
       // sort again each variable for all events - needs this before Optimize()
       // rescaling has changed variable values
       for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
@@ -300,15 +301,15 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    // all child nodes. If odepth = 0 then split variable 0
    // at the median (in half) and return it as root node
    fTree = Optimize(odepth);
-   
+
    if (!fTree) {
       Log() << kFATAL << "ModulekNN::Fill() - failed to create tree" << Endl;
-      return kFALSE;      
-   }      
-   
+      return kFALSE;
+   }
+
    for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
       fTree->Add(*event, 0);
-      
+
       std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
       if (cit == fCount.end()) {
          fCount[event->GetType()] = 1;
@@ -317,20 +318,20 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
          ++(cit->second);
       }
    }
-   
+
    for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
-      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8) 
+      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8)
               << it->second << " events" << Endl;
    }
-   
+
    return kTRUE;
 }
 
 //-------------------------------------------------------------------------------------------
 Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::string &option) const
-{  
+{
    // find in tree
-   // if tree has been filled then search for nfind closest events 
+   // if tree has been filled then search for nfind closest events
    // if metic (fVarScale map) is computed then rescale event variables
    // using previsouly computed width of variable distribution
 
@@ -356,7 +357,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    // latest event for k-nearest neighbor search
    fkNNEvent = event;
    fkNNList.clear();
-   
+
    if(option.find("weight") != std::string::npos)
    {
       // recursive kd-tree search for nfind-nearest neighbors
@@ -368,7 +369,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    {
       // recursive kd-tree search for nfind-nearest neighbors
       // count nodes and do not use event weight
-      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);      
+      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);
    }
 
    return kTRUE;
@@ -381,9 +382,11 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
    if (fCount.empty() || !fTree) {
       return kFALSE;
    }
-   
+
 #if __cplusplus > 199711L
-   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+   //this to be able to use the macro
+   using stdMapShorttUinnttconstIterator = std::map<Short_t, UInt_t>::const_iterator;
+   static TTHREAD_TLS(stdMapShorttUinnttconstIterator) cit = fCount.end();
 #else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
 #endif
@@ -401,9 +404,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          if (vit == fVar.end()) {
             return kFALSE;
          }
-         
+
          const std::vector<Double_t> &vvec = vit->second;
-         
+
          if (vvec.empty()) {
             return kFALSE;
          }
@@ -412,7 +415,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          const VarType min = vvec.front();
          const VarType max = vvec.back();
          const VarType width = max - min;
-         
+
          if (width < 0.0 || width > 0.0) {
             dvec.push_back(min + width*fgRndm.Rndm());
          }
@@ -422,9 +425,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       }
 
       const Event event(dvec, 1.0, etype);
-      
+
       Find(event, nfind);
-      
+
       return kTRUE;
    }
 
@@ -459,8 +462,8 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
 
    if (double(fDimn*size) < TMath::Power(2.0, double(odepth))) {
       Log() << kWARNING << "<Optimize> Optimization depth exceeds number of events" << Endl;
-      return 0;      
-   }   
+      return 0;
+   }
 
    Log() << kINFO << "Optimizing tree for " << fDimn << " variables with " << size << " values" << Endl;
 
@@ -473,14 +476,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
    }
 
    const Event pevent(VarVec(fDimn, (it->second)[size/2]), -1.0, -1);
-   
+
    Node<Event> *tree = new Node<Event>(0, pevent, 0);
-   
+
    pvec.push_back(tree);
 
-   for (UInt_t depth = 1; depth < odepth; ++depth) {            
+   for (UInt_t depth = 1; depth < odepth; ++depth) {
       const UInt_t mod = depth % fDimn;
-      
+
       VarMap::const_iterator vit = fVar.find(mod);
       if (vit == fVar.end()) {
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
@@ -492,26 +495,26 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
          return 0;
       }
-      
+
       UInt_t ichild = 1;
       for (std::vector<Node<Event> *>::iterator pit = pvec.begin(); pit != pvec.end(); ++pit) {
          Node<Event> *parent = *pit;
-         
+
          const VarType lmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
 
          const VarType rmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
-      
+
          const Event levent(VarVec(fDimn, lmedian), -1.0, -1);
          const Event revent(VarVec(fDimn, rmedian), -1.0, -1);
-         
+
          Node<Event> *lchild = new Node<Event>(parent, levent, mod);
          Node<Event> *rchild = new Node<Event>(parent, revent, mod);
-         
+
          parent->SetNodeL(lchild);
          parent->SetNodeR(rchild);
-         
+
          cvec.push_back(lchild);
          cvec.push_back(rchild);
       }
@@ -519,14 +522,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
       pvec = cvec;
       cvec.clear();
    }
-   
+
    return tree;
 }
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
 {
-   // compute scale factor for each variable (dimension) so that 
+   // compute scale factor for each variable (dimension) so that
    // distance is computed uniformely along each dimension
    // compute width of interval that includes (100 - 2*ifrac)% of events
    // below, assume that in fVar each vector of values is sorted
@@ -537,37 +540,37 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
    if (ifrac > 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - fraction can not exceed 100%" << Endl;
       return;
-   }   
+   }
    if (!fVarScale.empty()) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - metric is already computed" << Endl;
       return;
    }
    if (fEvent.size() < 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - number of events is too small" << Endl;
-      return;      
+      return;
    }
 
    const UInt_t lfrac = (100 - ifrac)/2;
    const UInt_t rfrac = 100 - (100 - ifrac)/2;
 
-   Log() << kINFO << "Computing scale factor for 1d distributions: " 
-           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;   
+   Log() << kINFO << "Computing scale factor for 1d distributions: "
+           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;
 
    fVarScale.clear();
-   
+
    for (VarMap::const_iterator vit = fVar.begin(); vit != fVar.end(); ++vit) {
       const std::vector<Double_t> &dvec = vit->second;
-      
+
       std::vector<Double_t>::const_iterator beg_it = dvec.end();
       std::vector<Double_t>::const_iterator end_it = dvec.end();
-      
+
       Int_t dist = 0;
       for (std::vector<Double_t>::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit, ++dist) {
-         
+
          if ((100*dist)/dvec.size() == lfrac && beg_it == dvec.end()) {
             beg_it = dit;
          }
-         
+
          if ((100*dist)/dvec.size() == rfrac && end_it == dvec.end()) {
             end_it = dit;
          }
@@ -576,35 +579,35 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
       if (beg_it == dvec.end() || end_it == dvec.end()) {
          beg_it = dvec.begin();
          end_it = dvec.end();
-         
+
          assert(beg_it != end_it && "Empty vector");
-         
+
          --end_it;
       }
 
       const Double_t lpos = *beg_it;
       const Double_t rpos = *end_it;
-      
+
       if (!(lpos < rpos)) {
          Log() << kFATAL << "ModulekNN::ComputeMetric() - min value is greater than max value" << Endl;
          continue;
       }
-      
+
       // Rustem: please find a solution that does not use distance (it does not exist on solaris)
-      //       Log() << kINFO << "Variable " << vit->first 
+      //       Log() << kINFO << "Variable " << vit->first
       //               << " included " << distance(beg_it, end_it) + 1
       //               << " events: width = " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos - lpos
-      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos 
+      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos
       //               << ", " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos << ")" << Endl;
-      
+
       fVarScale[vit->first] = rpos - lpos;
    }
 
    fVar.clear();
 
-   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {      
+   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {
       fEvent[ievent] = Scale(fEvent[ievent]);
-      
+
       for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
          fVar[ivar].push_back(fEvent[ievent].GetVar(ivar));
       }
@@ -616,7 +619,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
 {
    // scale each event variable so that rms of variables is approximately 1.0
    // this allows comparisons of variables with distinct scales and units
-   
+
    if (fVarScale.empty()) {
       return event;
    }
@@ -634,7 +637,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
          Log() << kFATAL << "ModulekNN::Scale() - failed to find scale for " << ivar << Endl;
          continue;
       }
-      
+
       if (fit->second > 0.0) {
          vvec[ivar] = event.GetVar(ivar)/fit->second;
       }
@@ -668,7 +671,7 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
    os << "Printing " << fkNNList.size() << " nearest neighbors" << std::endl;
    for (List::const_iterator it = fkNNList.begin(); it != fkNNList.end(); ++it) {
       os << ++count << ": " << it->second << ": " << it->first->GetEvent() << std::endl;
-      
+
       const Event &event = it->first->GetEvent();
       for (UShort_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
          if (min.find(ivar) == min.end()) {
@@ -693,6 +696,6 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
          Log() << kINFO << "(var, min, max) = (" << i << "," << min[i] << ", " << max[i] << ")" << Endl;
       }
    }
-   
+
    os << "----------------------------------------------------------------------" << std::endl;
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index 8f6bbf3d68e40..405f117ec21c6 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$   
+// @(#)root/tmva $Id$
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      U. of Victoria, Canada                                                    * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      U. of Victoria, Canada                                                    *
+ *      MPI-K Heidelberg, Germany                                                 *
  *      LAPP, Annecy, France                                                      *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -27,13 +27,14 @@
  **********************************************************************************/
 
 #include "TMVA/Option.h"
+#include "ThreadLocalStorage.h"
 
 //______________________________________________________________________
-TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
-   : TObject(), 
-     fName        ( name ), 
-     fNameAllLower( name ), 
-     fDescription ( desc ), 
+TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
+   : TObject(),
+     fName        ( name ),
+     fNameAllLower( name ),
+     fDescription ( desc ),
      fIsSet       ( kFALSE )
 {
    // constructor
@@ -41,7 +42,7 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
 }
 
 //______________________________________________________________________
-Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t ) 
+Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
 {
    // set value for option
    fIsSet = kTRUE;
@@ -52,7 +53,7 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
 TMVA::MsgLogger& TMVA::OptionBase::Log()
 {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
+  static TTHREAD_TLS(MsgLogger) logger("Option",kDEBUG);  // message logger
 #else
   static MsgLogger logger("Option",kDEBUG);  // message logger
 #endif
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 875ca43f4b04b..2519d300daea5 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -50,7 +50,7 @@ const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
 #if __cplusplus > 199711L
-thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
+TTHREAD_TLS(TMVA::PDF*) TMVA::PDF::fgThisPDF  = 0;
 #else
 TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
 #endif
@@ -597,7 +597,7 @@ void TMVA::PDF::ValidatePDF( TH1* originalHist ) const
       if (y > 0) {
          ndof++;
          Double_t d = TMath::Abs( (y - yref*rref)/ey );
-         //         std::cout << "bin: " << bin << "  val: " << x << "  data(err): " << y << "(" << ey << ")   pdf: " 
+         //         std::cout << "bin: " << bin << "  val: " << x << "  data(err): " << y << "(" << ey << ")   pdf: "
          //              << yref << "  dev(chi2): " << d << "(" << chi2 << ")  rref: " << rref << std::endl;
          chi2 += d*d;
          if (d > 1) { nc1++; if (d > 2) { nc2++; if (d > 3) { nc3++; if (d > 6) nc6++; } } }
@@ -723,7 +723,7 @@ Double_t TMVA::PDF::GetValInverse( Double_t y, Bool_t isMonotonouslyIncreasingFu
    Int_t    lowerBin=0,      higherBin=0;
    Double_t lowerBinValue=0, higherBinValue=0;
    FindBinInverse(fPDFHist,lowerBin,higherBin,lowerBinValue,higherBinValue,y,isMonotonouslyIncreasingFunction);
-   
+
    Double_t xValueLowerBin =fPDFHist->GetBinCenter (lowerBin);
    Double_t xValueHigherBin=fPDFHist->GetBinCenter (higherBin);
 
@@ -743,7 +743,7 @@ Double_t TMVA::PDF::GetValInverse( Double_t y, Bool_t isMonotonouslyIncreasingFu
 }
 
 //_____________________________________________________________________
-void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue, 
+void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue,
 				Double_t y, Bool_t isMonotonouslyIncreasingFunction ) const
 {
    // find bin from value on ordinate
@@ -752,7 +752,7 @@ void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& hi
       lowerBin =0;
 
       Int_t bin=higherBin/2;
-      
+
       while (bin>lowerBin && bin<higherBin) {
 	 Double_t binContent=histogram->GetBinContent(bin);
 
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index 1099a9caa3ff1..7e776158d142e 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -151,7 +151,7 @@ void TMVA::TNeuron::CalculateDelta()
 void TMVA::TNeuron::SetInputCalculator(TNeuronInput* calculator)
 {
    // set input calculator
-   if (fInputCalculator != NULL) delete fInputCalculator; 
+   if (fInputCalculator != NULL) delete fInputCalculator;
    fInputCalculator = calculator;
 }
 
@@ -294,7 +294,7 @@ void TMVA::TNeuron::InitSynapseDeltas()
 }
 
 //______________________________________________________________________________
-void TMVA::TNeuron::PrintLinks(TObjArray* links) const 
+void TMVA::TNeuron::PrintLinks(TObjArray* links) const
 {
    // print an array of TSynapses, for debugging
 
@@ -308,7 +308,7 @@ void TMVA::TNeuron::PrintLinks(TObjArray* links) const
    Int_t numLinks = links->GetEntriesFast();
    for  (Int_t i = 0; i < numLinks; i++) {
       synapse = (TSynapse*)links->At(i);
-      Log() << kDEBUG <<  
+      Log() << kDEBUG <<
          "\t\t\tweighta: " << synapse->GetWeight()
            << "\t\tw-value: " << synapse->GetWeightedValue()
            << "\t\tw-delta: " << synapse->GetWeightedDelta()
@@ -333,10 +333,10 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
 }
 
 //______________________________________________________________________________
-TMVA::MsgLogger& TMVA::TNeuron::Log() const 
+TMVA::MsgLogger& TMVA::TNeuron::Log() const
 {
   #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
+  static TTHREAD_TLS(MsgLogger) logger("TNeuron",kDEBUG);    //! message logger, static to save resources
 #else
   static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
 #endif
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index ab03d79f8b173..c38a9f6726fe9 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -36,6 +36,8 @@
 #include "TMVA/MsgLogger.h"
 #endif
 
+#include "ThreadLocalStorage.h"
+
 static const Int_t fgUNINITIALIZED = -1;
 
 ClassImp(TMVA::TSynapse);
@@ -110,7 +112,7 @@ void TMVA::TSynapse::CalculateDelta()
 TMVA::MsgLogger& TMVA::TSynapse::Log() const
 {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
+  static TTHREAD_TLS(MsgLogger) logger("TSynapse");  //! message logger, static to save resources
 #else
   static MsgLogger logger("TSynapse");               //! message logger, static to save resources
 #endif

From 9e519306d8514c3c77d95064b4eed0a674f68d1a Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Thu, 5 Mar 2015 16:38:18 +0100
Subject: [PATCH 156/200] Add forgotten executable extensions

---
 core/utils/CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/utils/CMakeLists.txt b/core/utils/CMakeLists.txt
index 9f3fa9bb97468..5eb09c38923fc 100644
--- a/core/utils/CMakeLists.txt
+++ b/core/utils/CMakeLists.txt
@@ -38,8 +38,8 @@ add_dependencies(rootcling CLING LLVMRES)
 
 if(WIN32)
   add_custom_command(TARGET rootcling POST_BUILD
-                     COMMAND copy /y rootcling rootcint
-                     COMMAND copy /y rootcling genreflex
+                     COMMAND copy /y rootcling.exe rootcint.exe
+                     COMMAND copy /y rootcling.exe genreflex.exe
                      WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
 else()
   add_custom_command(TARGET rootcling POST_BUILD

From 42314afce127b1ffbd4db93b28dcacfcd2895b37 Mon Sep 17 00:00:00 2001
From: Lorenzo Moneta <Lorenzo.Moneta@cern.ch>
Date: Thu, 5 Mar 2015 17:22:50 +0100
Subject: [PATCH 157/200] Fix backward compatible constructors (ROOT-7150)

---
 hist/hist/inc/TF1.h | 40 ++++++++++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 6 deletions(-)

diff --git a/hist/hist/inc/TF1.h b/hist/hist/inc/TF1.h
index 9024924e8ed8e..b484e4c10933b 100644
--- a/hist/hist/inc/TF1.h
+++ b/hist/hist/inc/TF1.h
@@ -225,9 +225,23 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    }
    // backward compatible interface
    template <typename Func>
-   TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar, const char *   ) {
-      TF1 tmp(name,f,xmin,xmax,npar,1);
-      *this = tmp;
+   TF1(const char *name, Func f, Double_t xmin, Double_t xmax, Int_t npar, const char *   ) :
+      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
+      fXmin(xmin), fXmax(xmax),
+      fNpar(npar), fNdim(1),
+      fNpx(100), fType(1),
+      fNpfits(0), fNDF(0), fChisquare(0),
+      fMinimum(-1111), fMaximum(-1111),
+      fParErrors(std::vector<Double_t>(npar)),
+      fParMin(std::vector<Double_t>(npar)),
+      fParMax(std::vector<Double_t>(npar)),
+      fParent(0), fHistogram(0),
+      fMethodCall(0),
+      fFunctor(ROOT::Math::ParamFunctor(f)),
+      fFormula(0),
+      fParams(new TF1Parameters(npar) )
+   {
+      DoInitialize();
    }
 
 
@@ -260,9 +274,23 @@ class TF1 : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
    }
    // backward compatible interface
    template <class PtrObj, typename MemFn>
-   TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,const char * , const char * ) {
-      TF1 tmp(name,p, memFn,xmin,xmax,npar,1);
-      *this = tmp;
+   TF1(const char *name, const  PtrObj& p, MemFn memFn, Double_t xmin, Double_t xmax, Int_t npar,const char * , const char * ) :
+      TNamed(name,name), TAttLine(), TAttFill(), TAttMarker(),
+      fXmin(xmin), fXmax(xmax),
+      fNpar(npar), fNdim(1),
+      fNpx(100), fType(1),
+      fNpfits(0), fNDF(0), fChisquare(0),
+      fMinimum(-1111), fMaximum(-1111),
+      fParErrors(std::vector<Double_t>(npar)),
+      fParMin(std::vector<Double_t>(npar)),
+      fParMax(std::vector<Double_t>(npar)),
+      fParent(0), fHistogram(0),
+      fMethodCall(0),
+      fFunctor   ( ROOT::Math::ParamFunctor(p,memFn) ),
+      fFormula(0),
+      fParams(new TF1Parameters(npar) )
+   {
+      DoInitialize();
    }
 
    TF1(const TF1 &f1);

From d5669469ad3a492755ecded43128c62a58c1b479 Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Thu, 5 Mar 2015 19:01:05 +0100
Subject: [PATCH 158/200] Partially fix ROOT-7144 - CMake warnings with CMake
 3.2-rc2

---
 math/minuit2/test/CMakeLists.txt | 8 ++++----
 test/CMakeLists.txt              | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/math/minuit2/test/CMakeLists.txt b/math/minuit2/test/CMakeLists.txt
index e478ce1225025..6f99dbf421c99 100644
--- a/math/minuit2/test/CMakeLists.txt
+++ b/math/minuit2/test/CMakeLists.txt
@@ -40,10 +40,10 @@ endforeach()
 ROOT_LINKER_LIBRARY(Minuit2TestMnSim MnSim/GaussDataGen.cxx MnSim/GaussFcn.cxx MnSim/GaussFcn2.cxx LIBRARIES Minuit2)
 
 #input text files
-configure_file(MnSim/paul.txt paul.txt @COPY_ONLY)
-configure_file(MnSim/paul2.txt paul2.txt @COPY_ONLY)
-configure_file(MnSim/paul3.txt paul3.txt @COPY_ONLY)
-configure_file(MnSim/paul4.txt paul4.txt @COPY_ONLY)
+configure_file(MnSim/paul.txt paul.txt COPYONLY)
+configure_file(MnSim/paul2.txt paul2.txt COPYONLY)
+configure_file(MnSim/paul3.txt paul3.txt COPYONLY)
+configure_file(MnSim/paul4.txt paul4.txt COPYONLY)
 
 foreach(file ${TestSourceMnSim})
   get_filename_component(testname ${file} NAME_WE)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a8666a7d27f92..ae0e6134f41e1 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -49,7 +49,7 @@ ROOT_ADD_TEST(test-minexam COMMAND minexam)
 
 #--tstring-------------------------------------------------------------------------------------
 ROOT_EXECUTABLE(tstring tstring.cxx LIBRARIES Core)
-configure_file(tstring.cxx tstring.cxx @COPY_ONLY)
+configure_file(tstring.cxx tstring.cxx COPYONLY)
 ROOT_ADD_TEST(test-tstring COMMAND tstring)
 
 #--tcollex-------------------------------------------------------------------------------------
@@ -112,8 +112,8 @@ ROOT_ADD_TEST(test-stresslinear-interpreted COMMAND ${ROOT_root_CMD} -b -q -l ${
 
 #--stressGraphics------------------------------------------------------------------------------------
 ROOT_EXECUTABLE(stressGraphics stressGraphics.cxx LIBRARIES Graf Gpad Postscript)
-configure_file(stressGraphics.ref stressGraphics.ref @COPY_ONLY)
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../tutorials/graphics/earth.dat earth.dat @COPY_ONLY)
+configure_file(stressGraphics.ref stressGraphics.ref COPYONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../tutorials/graphics/earth.dat earth.dat COPYONLY)
 ROOT_ADD_TEST(test-stressgraphics ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:$ENV{LD_LIBRARY_PATH} COMMAND stressGraphics -b -k FAILREGEX "FAILED|Error in")
 ROOT_ADD_TEST(test-stressgraphics-interpreted COMMAND ${ROOT_root_CMD} -b -q -l ${CMAKE_CURRENT_SOURCE_DIR}/stressGraphics.cxx
               FAILREGEX "FAILED|Error in" DEPENDS test-stressgraphics)
@@ -127,7 +127,7 @@ ROOT_ADD_TEST(test-stresshistogram-interpreted COMMAND ${ROOT_root_CMD} -b -q -l
 #--stressGUI---------------------------------------------------------------------------------------
 ROOT_EXECUTABLE(stressGUI stressGUI.cxx LIBRARIES Gui Recorder GuiHtml ASImageGui)
 #---Cannot run GUI test in batch mode--------------------
-#configure_file(stressGUI.ref stressGUI.ref @COPY_ONLY)
+#configure_file(stressGUI.ref stressGUI.ref COPYONLY)
 #ROOT_ADD_TEST(test-stressgui COMMAND stressGUI -ref FAILREGEX "FAILED|Error in")
 
 #--stressSpectrum----------------------------------------------------------------------------------

From e94f8f74830852de561c75985a1d9e5dd489082d Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 20:53:46 +0100
Subject: [PATCH 159/200] Revert "Fix usage of thread_local on OSx 10.9 using
 the ROOT macro TTHREAD_TLS"

The macros in the ThreadLocalStorage.h are not the panacea.
For example, the standard C++ keyword "thread_local" is not equivalent to the
TTHREAD_TLS(xyz) syntax. Indeed, the presence of a static storage, it leads
to static static __thread constructs not digested on many platforms.

They work on kubuntu14 and SLC6, but they fail on osx10.9 and other platforms.
They should be used differently.

This reverts commit 5758705f205c197d0929ad0e4aeaf798f09f7fd8.
---
 tmva/inc/TMVA/BDTEventWrapper.h |  29 +++--
 tmva/inc/TMVA/MethodBase.h      |  25 ++---
 tmva/inc/TMVA/MethodPDERS.h     |  17 ++-
 tmva/inc/TMVA/ModulekNN.h       |  16 ++-
 tmva/inc/TMVA/PDF.h             |  45 ++++----
 tmva/src/BDTEventWrapper.cxx    |  14 +--
 tmva/src/BinaryTree.cxx         |  12 +-
 tmva/src/DecisionTreeNode.cxx   |   4 +-
 tmva/src/Interval.cxx           |  37 +++---
 tmva/src/LogInterval.cxx        |   3 +-
 tmva/src/MethodBase.cxx         | 192 ++++++++++++++++----------------
 tmva/src/MethodMLP.cxx          |  46 ++++----
 tmva/src/MethodPDERS.cxx        |  64 +++++------
 tmva/src/MethodTMlpANN.cxx      |  26 ++---
 tmva/src/ModulekNN.cxx          | 147 ++++++++++++------------
 tmva/src/Option.cxx             |  23 ++--
 tmva/src/PDF.cxx                |  10 +-
 tmva/src/TNeuron.cxx            |  10 +-
 tmva/src/TSynapse.cxx           |   4 +-
 19 files changed, 353 insertions(+), 371 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index f272ea30b275b..cc3d0ae17814e 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -5,9 +5,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *
- *                                                                                *
- *                                                                                *
+ * Description:                                                                   *  
+ *                                                                                *  
+ *                                                                                *  
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
@@ -25,65 +25,64 @@
 #ifndef ROOT_Event
 #include "Event.h"
 #endif
-#include "ThreadLocalStorage.h"
 
 namespace TMVA {
-
+  
    class BDTEventWrapper{
 
    public:
 
       BDTEventWrapper( const Event* );
       ~BDTEventWrapper();
-
+    
       // Require '<' operator to use std::sort algorithms on collection of Events
       Bool_t operator <( const BDTEventWrapper& other ) const;
-
+    
       // Set the accumulated weight, for sorted signal/background events
       /**
        * @param fType - true for signal, false for background
        * @param weight - the total weight
        */
       void SetCumulativeWeight( Bool_t type, Double_t weight );
-
+    
       // Get the accumulated weight
       /**
        * @param fType - true for signal, false for background
        * @return the cumulative weight for sorted signal/background events
        */
       Double_t GetCumulativeWeight( Bool_t type ) const;
-
+    
       // Set the index of the variable to compare on
       /**
        * @param iVar - index of the variable in fEvent to use
        */
       inline static void SetVarIndex( Int_t iVar ) { if (iVar >= 0) fVarIndex = iVar; }
-
+    
       // Return the value of variable fVarIndex for this event
       /**
        * @return value of variable fVarIndex for this event
        */
       inline Double_t GetVal() const { return fEvent->GetValue(fVarIndex); }
       const Event* operator*() const { return fEvent; }
-
+    
    private:
 
 #if __cplusplus > 199711L
-      static TTHREAD_TLS(Int_t) fVarIndex;  // index of the variable to sort on
+      static thread_local Int_t fVarIndex;  // index of the variable to sort on
 #else
       static Int_t fVarIndex;  // index of the variable to sort on
 #endif
       const Event* fEvent;     // pointer to the event
-
+    
       Double_t     fBkgWeight; // cumulative background weight for splitting
       Double_t     fSigWeight; // same for the signal weights
    };
 }
 
-inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const
+inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const 
 {
    return GetVal() < other.GetVal();
 }
 
-#endif
+#endif 
 
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 6f699e7f7934b..8a1c2d28610b9 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -71,7 +71,6 @@
 #ifndef ROOT_TMVA_OptimizeConfigParameters
 #include "TMVA/OptimizeConfigParameters.h"
 #endif
-#include "ThreadLocalStorage.h"
 
 class TGraph;
 class TTree;
@@ -203,7 +202,7 @@ namespace TMVA {
       }
 
       // probability of classifier response (mvaval) to be signal (requires "CreateMvaPdf" option set)
-      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different)
+      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different) 
       virtual Double_t GetProba( Double_t mvaVal, Double_t ap_sig );
 
       // Rarity of classifier response (signal or background (default) is uniform in [0,1])
@@ -275,7 +274,7 @@ namespace TMVA {
 
       // variables (and private menber functions) for the Evaluation:
       // get the effiency. It fills a histogram for efficiency/vs/bkg
-      // and returns the one value fo the efficiency demanded for
+      // and returns the one value fo the efficiency demanded for 
       // in the TString argument. (Watch the string format)
       virtual Double_t GetEfficiency( const TString&, Types::ETreeType, Double_t& err );
       virtual Double_t GetTrainingEfficiency(const TString& );
@@ -284,7 +283,7 @@ namespace TMVA {
       virtual Double_t GetSignificance() const;
       virtual Double_t GetROCIntegral(TH1D *histS, TH1D *histB) const;
       virtual Double_t GetROCIntegral(PDF *pdfS=0, PDF *pdfB=0) const;
-      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents,
+      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents, 
                                                Double_t& optimal_significance_value  ) const;
       virtual Double_t GetSeparation( TH1*, TH1* ) const;
       virtual Double_t GetSeparation( PDF* pdfS = 0, PDF* pdfB = 0 ) const;
@@ -367,7 +366,7 @@ namespace TMVA {
       mutable const Event*   fTmpEvent; //! temporary event when testing on a different DataSet than the own one
 
       // event reference and update
-      // NOTE: these Event accessors make sure that you get the events transformed according to the
+      // NOTE: these Event accessors make sure that you get the events transformed according to the 
       //        particular clasifiers transformation chosen
       UInt_t           GetNEvents      () const { return Data()->GetNEvents(); }
       const Event*     GetEvent        () const;
@@ -631,7 +630,7 @@ namespace TMVA {
 
       // this carrier
 #if __cplusplus > 199711L
-      static TTHREAD_TLS(MethodBase*) fgThisBase;         // this pointer
+      static thread_local MethodBase* fgThisBase;         // this pointer
 #else
       static MethodBase* fgThisBase;         // this pointer
 #endif
@@ -642,7 +641,7 @@ namespace TMVA {
       Bool_t           fNormalise;                   // normalise input variables
       Bool_t           fUseDecorr;                   // synonymous for decorrelation
       TString          fVariableTransformTypeString; // labels variable transform type
-      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files
+      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files 
       Int_t            fNbinsMVAPdf;                 // number of bins used in histogram that creates PDF
       Int_t            fNsmoothMVAPdf;               // number of times a histogram is smoothed before creating the PDF
 
@@ -663,12 +662,12 @@ namespace TMVA {
 
 
 //_______________________________________________________________________
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const 
 {
    return GetTransformationHandler().Transform(ev);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
+inline const TMVA::Event* TMVA::MethodBase::GetEvent() const 
 {
    if(fTmpEvent)
       return GetTransformationHandler().Transform(fTmpEvent);
@@ -676,25 +675,25 @@ inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
       return GetTransformationHandler().Transform(Data()->GetEvent());
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const 
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const 
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt, type));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const
+inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const 
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTraining);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const
+inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const 
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTesting);
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index ecc3398b3af54..9d1a4f7bd1e61 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -58,7 +58,6 @@
 #include "TVector.h"
 #endif
 #endif
-#include "ThreadLocalStorage.h"
 
 namespace TMVA {
 
@@ -70,7 +69,7 @@ namespace TMVA {
    public:
 
       MethodPDERS( const TString& jobName,
-                   const TString& methodTitle,
+                   const TString& methodTitle, 
                    DataSetInfo& theData,
                    const TString& theOption,
                    TDirectory* theTargetDir = 0 );
@@ -129,8 +128,8 @@ namespace TMVA {
 
       Double_t ApplyKernelFunction( Double_t normalized_distance );
       Double_t KernelNormalization( Double_t pdf );
-      Double_t GetNormalizedDistance( const TMVA::Event &base_event,
-                                      const BinarySearchTreeNode &sample_event,
+      Double_t GetNormalizedDistance( const TMVA::Event &base_event, 
+                                      const BinarySearchTreeNode &sample_event, 
                                       Double_t *dim_normalization);
       Double_t NormSinc( Double_t x );
       Double_t LanczosFilter( Int_t level, Double_t x );
@@ -149,7 +148,7 @@ namespace TMVA {
 
       // create binary search trees for signal and background
       void CreateBinarySearchTree( Types::ETreeType type );
-
+      
       // get sample of training events
       void GetSample( const Event &e, std::vector<const BinarySearchTreeNode*>& events, Volume *volume);
 
@@ -192,7 +191,7 @@ namespace TMVA {
       Float_t            fScaleS;        // weight for signal events
       Float_t            fScaleB;        // weight for background events
       Float_t            fDeltaFrac;     // fraction of RMS
-      Double_t           fGaussSigma;    // size of Gauss in adaptive volume
+      Double_t           fGaussSigma;    // size of Gauss in adaptive volume 
       Double_t           fGaussSigmaNorm;// size of Gauss in adaptive volume (normalised to dimensions)
 
       Double_t           fNRegOut;       // number of output dimensions for regression
@@ -204,10 +203,10 @@ namespace TMVA {
       Float_t            fInitialScale;  // initial scale for adaptive volume
 
       Bool_t             fInitializedVolumeEle; // is volume element initialized ?
-
+      
       Int_t              fkNNMin;        // min number of events in kNN tree
       Int_t              fkNNMax;        // max number of events in kNN tree
-
+      
       Double_t           fMax_distance;  // maximum distance
       Bool_t             fPrinted;       // print
       Bool_t             fNormTree;      // binary-search tree is normalised
@@ -222,7 +221,7 @@ namespace TMVA {
 
       // this carrier
 #if __cplusplus > 199711L
-      static TTHREAD_TLS(MethodPDERS*) fgThisPDERS; // this pointer (required by root finder)
+      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
 #else
       static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
 #endif
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index ddc4ff574bcee..569ee5e80b46c 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -48,22 +48,20 @@
 #ifndef ROOT_TRandom
 #include "TRandom3.h"
 #endif
-#include "ThreadLocalStorage.h"
 
 #ifndef ROOT_TMVA_NodekNN
 #include "TMVA/NodekNN.h"
 #endif
-#include "ThreadLocalStorage.h"
 
 namespace TMVA {
 
    class MsgLogger;
 
    namespace kNN {
-
+      
       typedef Float_t VarType;
       typedef std::vector<VarType> VarVec;
-
+      
       class Event {
       public:
 
@@ -99,7 +97,7 @@ namespace TMVA {
          VarVec fTgt; // targets for regression analysis
 
          Double_t fWeight; // event weight
-         Short_t fType; // event type ==0 or == 1, expand it to arbitrary class types?
+         Short_t fType; // event type ==0 or == 1, expand it to arbitrary class types? 
       };
 
       typedef std::vector<TMVA::kNN::Event> EventVec;
@@ -127,7 +125,7 @@ namespace TMVA {
 
          Bool_t Find(Event event, UInt_t nfind = 100, const std::string &option = "count") const;
          Bool_t Find(UInt_t nfind, const std::string &option) const;
-
+      
          const EventVec& GetEventVec() const;
 
          const List& GetkNNList() const;
@@ -136,7 +134,7 @@ namespace TMVA {
          const VarMap& GetVarMap() const;
 
          const std::map<Int_t, Double_t>& GetMetric() const;
-
+      
          void Print() const;
          void Print(std::ostream &os) const;
 
@@ -151,7 +149,7 @@ namespace TMVA {
       private:
 
 #if __cplusplus > 199711L
-         static TTHREAD_TLS(TRandom3) fgRndm;
+         static thread_local TRandom3 fgRndm;
 #else
          static TRandom3 fgRndm;
 #endif
@@ -163,7 +161,7 @@ namespace TMVA {
 
          mutable List  fkNNList;     // latest result from kNN search
          mutable Event fkNNEvent;    // latest event used for kNN search
-
+         
          std::map<Short_t, UInt_t> fCount; // count number of events of each type
 
          EventVec fEvent; // vector of all events used to build tree and analysis
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index 0dad2e2bbb1bf..e6387c99b496d 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -19,10 +19,10 @@
  *      Jan Therhaag       <Jan.Therhaag@cern.ch>     - U of Bonn, Germany        *
  *                                                                                *
  * Copyright (c) 2005-2011:                                                       *
- *      CERN, Switzerland                                                         *
- *      U. of Victoria, Canada                                                    *
- *      MPI-K Heidelberg, Germany                                                 *
- *      Freiburg U., Germany                                                      *
+ *      CERN, Switzerland                                                         * 
+ *      U. of Victoria, Canada                                                    * 
+ *      MPI-K Heidelberg, Germany                                                 * 
+ *      Freiburg U., Germany                                                      * 
  *      U. of Bonn, Germany                                                       *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -52,7 +52,6 @@
 #ifndef ROOT_TMVA_Configurable
 #include "TMVA/Configurable.h"
 #endif
-#include "ThreadLocalStorage.h"
 
 class TSpline;
 class TGraph;
@@ -70,20 +69,20 @@ namespace TMVA {
 
       friend std::ostream& operator<< ( std::ostream& os, const PDF& tree );
       friend std::istream& operator>> ( std::istream& istr, PDF& tree);
-
+      
    public:
 
       enum EInterpolateMethod { kSpline0, kSpline1, kSpline2, kSpline3, kSpline5, kKDE };
 
       explicit PDF( const TString& name, Bool_t norm=kTRUE );
-      explicit PDF( const TString& name, const TH1* theHist, EInterpolateMethod method = kSpline2,
+      explicit PDF( const TString& name, const TH1* theHist, EInterpolateMethod method = kSpline2, 
                     Int_t minnsmooth = 0, Int_t maxnsmooth = 0, Bool_t checkHist = kFALSE, Bool_t norm=kTRUE );
-      explicit PDF( const TString& name, const TH1* theHist,
-                    KDEKernel::EKernelType ktype, KDEKernel::EKernelIter kiter, KDEKernel::EKernelBorder
+      explicit PDF( const TString& name, const TH1* theHist, 
+                    KDEKernel::EKernelType ktype, KDEKernel::EKernelIter kiter, KDEKernel::EKernelBorder 
                     kborder, Float_t FineFactor, Bool_t norm=kTRUE );
       explicit PDF( const TString& name, const TString& options, const TString& suffix = "", PDF* defaultPDF = 0, Bool_t norm=kTRUE);
       virtual ~PDF();
-
+      
       //creates the pdf after the definitions have been stored in
       void BuildPDF (const TH1* theHist);
 
@@ -122,7 +121,7 @@ namespace TMVA {
       const char* GetName() const { return fPDFName; }
 
       // TMVA version control (for weight files)
-      void   SetReadingVersion( UInt_t rv ) { fReadingVersion = rv; }
+      void   SetReadingVersion( UInt_t rv ) { fReadingVersion = rv; }      
       UInt_t GetReadingVersion() const { return fReadingVersion; }
 
       //void WriteOptionsToStream ( std::ostream& o, const TString& prefix ) const;
@@ -133,7 +132,7 @@ namespace TMVA {
 
    private:
 
-      // sanity check of PDF quality (after smoothing): comparison with
+      // sanity check of PDF quality (after smoothing): comparison with 
       // original histogram
       void     CheckHist() const;
       void     FillSplineToHist();
@@ -141,7 +140,7 @@ namespace TMVA {
       void     SmoothHistogram();
       void     FillHistToGraph();
       Double_t GetIntegral() const;
-      Double_t GetPdfHistBinWidth() const {
+      Double_t GetPdfHistBinWidth() const { 
          TH1* h = GetPDFHist();
          return (fPDFHist) ? (h->GetXaxis()->GetXmax() - h->GetXaxis()->GetXmin())/h->GetNbinsX() : 1;
       }
@@ -149,7 +148,7 @@ namespace TMVA {
       // do we use the original histogram as reference ?
       Bool_t   UseHistogram() const { return fUseHistogram; }
 
-      void FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue,
+      void FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue, 
 			   Double_t y, Bool_t isMonotonouslyIncreasingFunction=kFALSE ) const;
 
 
@@ -157,11 +156,11 @@ namespace TMVA {
 
       // flag that indicates that no splines are produced and no smoothing
       // is applied, i.e., the original histogram is used as reference
-      // this is useful for discrete variables
+      // this is useful for discrete variables      
       Bool_t                   fUseHistogram;  // spline0 uses histogram as reference
-
+  
       // static configuration variables ----------------------------
-      // to increase computation speed, the final PDF is filled in
+      // to increase computation speed, the final PDF is filled in 
       // a high-binned histogram; "GetValue" then returns the histogram
       // entry, linearized between adjacent bins
       static const Int_t       fgNbin_PdfHist;        // number of bins in high-binned reference histogram
@@ -203,17 +202,17 @@ namespace TMVA {
 
       TString                  fSuffix;               //! the suffix for options
       mutable MsgLogger*       fLogger;               //! message logger
-      MsgLogger&               Log() const { return *fLogger; }
+      MsgLogger&               Log() const { return *fLogger; }    
 
       // static pointer to this object
 #if __cplusplus > 199711L
-      static TTHREAD_TLS(PDF*) fgThisPDF;             // this PDF pointer
+      static thread_local PDF* fgThisPDF;             // this PDF pointer 
 #else
-      static PDF*              fgThisPDF;             // this PDF pointer
+      static PDF*              fgThisPDF;             // this PDF pointer 
 #endif
-      static PDF*              ThisPDF( void );
+      static PDF*              ThisPDF( void ); 
 
-      // external auxiliary functions
+      // external auxiliary functions 
       static Double_t          IGetVal( Double_t*, Double_t* );
 
       ClassDef(PDF,1)  // PDF wrapper for histograms
@@ -221,4 +220,4 @@ namespace TMVA {
 
 } // namespace TMVA
 
-#endif
+#endif 
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index dc0f5ac6e7b2f..0820339c01c41 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -4,9 +4,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *
- *                                                                                *
- *                                                                                *
+ * Description:                                                                   *  
+ *                                                                                *  
+ *                                                                                *  
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  *                                                                                *
@@ -27,7 +27,7 @@
 using namespace TMVA;
 
 #if __cplusplus > 199711L
-TTHREAD_TLS(Int_t) BDTEventWrapper::fVarIndex = 0;
+thread_local Int_t BDTEventWrapper::fVarIndex = 0;
 #else
 Int_t BDTEventWrapper::fVarIndex = 0;
 #endif
@@ -39,7 +39,7 @@ BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
   fSigWeight = 0.0;
 }
 
-BDTEventWrapper::~BDTEventWrapper() {
+BDTEventWrapper::~BDTEventWrapper() { 
    // destructor
 }
 
@@ -49,14 +49,14 @@ void BDTEventWrapper::SetCumulativeWeight(Bool_t type, Double_t weight) {
     * @param fType - true for signal, false for background
     * @param weight - the total weight
     */
-
+   
    if(type) fSigWeight = weight;
    else fBkgWeight = weight;
 }
 
 Double_t BDTEventWrapper::GetCumulativeWeight(Bool_t type) const {
    // Get the accumulated weight
-
+   
    if(type) return fSigWeight;
    return fBkgWeight;
 }
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index d671bf3968fa2..dca177c92dbd2 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -44,8 +44,6 @@
 #include "TMVA/Event.h"
 #include "TMVA/Tools.h"
 
-#include "ThreadLocalStorage.h"
-
 ClassImp(TMVA::BinaryTree)
 
 //_______________________________________________________________________
@@ -177,7 +175,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
       // find parent node
       while( parent!=0 && parent->GetDepth() != currentNode->GetDepth()-1) parent=parent->GetParent();
-
+      
       if (parent!=0) { // link new node to parent
          currentNode->SetParent(parent);
          if (currentNode->GetPos()=='l') parent->SetLeft(currentNode);
@@ -192,7 +190,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
 //_______________________________________________________________________
 std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
-{
+{ 
    // read the tree from an std::istream
    tree.Read(istr);
    return istr;
@@ -201,7 +199,7 @@ std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
 void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 {
    // descend a tree to find all its leaf nodes, fill max depth reached in the
-   // tree at the same time.
+   // tree at the same time. 
 
    if (n == NULL){ //default, start at the tree top, then descend recursively
       n = (Node*) this->GetRoot();
@@ -209,7 +207,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
          Log() << kFATAL << "SetTotalTreeDepth: started with undefined ROOT node" <<Endl;
          return ;
       }
-   }
+   } 
    if (this->GetLeftDaughter(n) != NULL){
       this->SetTotalTreeDepth( this->GetLeftDaughter(n) );
    }
@@ -224,7 +222,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("BinaryTree");
+  static thread_local MsgLogger logger("BinaryTree");
 #else
   static MsgLogger logger("BinaryTree");
 #endif
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index f6102b4066cce..37425a83b94f7 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -46,8 +46,6 @@
 #include "TMVA/Tools.h"
 #include "TMVA/Event.h"
 
-#include "ThreadLocalStorage.h"
-
 using std::string;
 
 ClassImp(TMVA::DecisionTreeNode)
@@ -511,7 +509,7 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #else
   static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #endif
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index fcfb0b7193e9c..d89b023679f49 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -54,14 +54,14 @@
 </ul>
 <pre>
 
-    Example:   Interval(.5,1.,6)
+    Example:   Interval(.5,1.,6) 
 
-             [ min                           max ]
+             [ min                           max ]                       
          ------------------------------------------------------------
                 |     |     |     |     |     |
-               .5    .6    .7    .8    .9    1.0
-
-         bin    0     1     2     3     4     5
+               .5    .6    .7    .8    .9    1.0            
+ 
+         bin    0     1     2     3     4     5  
 
 
 </pre>
@@ -69,7 +69,6 @@ End_Html */
 
 #include "TMath.h"
 #include "TRandom3.h"
-#include "ThreadLocalStorage.h"
 
 #include "TMVA/Interval.h"
 #include "TMVA/MsgLogger.h"
@@ -77,7 +76,7 @@ End_Html */
 ClassImp(TMVA::Interval)
 
 //_______________________________________________________________________
-TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) :
+TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
    fMin(min),
    fMax(max),
    fNbins(nbins)
@@ -113,9 +112,9 @@ TMVA::Interval::~Interval()
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval.
+   // calculates the value of the "number" bin in a discrete interval. 
    // Parameters:
-   //        Double_t position
+   //        Double_t position 
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
@@ -131,7 +130,7 @@ Double_t TMVA::Interval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete Interval"
+   // retuns the step size between the numbers of a "discrete Interval" 
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
    }
@@ -149,25 +148,25 @@ Double_t TMVA::Interval::GetRndm( TRandom3& rnd )  const
    return rnd.Rndm()*(fMax - fMin) + fMin;
 }
 
-Double_t TMVA::Interval::GetWidth() const
-{
-   return fMax - fMin;
+Double_t TMVA::Interval::GetWidth() const 
+{ 
+   return fMax - fMin; 
 }
-Double_t TMVA::Interval::GetMean()  const
-{
-   return (fMax + fMin)/2;
+Double_t TMVA::Interval::GetMean()  const 
+{ 
+   return (fMax + fMin)/2; 
 }
 
-void TMVA::Interval::Print(std::ostream &os) const
+void TMVA::Interval::Print(std::ostream &os) const 
 {
    for (Int_t i=0; i<GetNbins(); i++){
       os << "| " << GetElement(i)<<" |" ;
-   }
+   }  
 }
 
 TMVA::MsgLogger& TMVA::Interval::Log() const {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("Interval");   // message logger
+  static thread_local MsgLogger logger("Interval");   // message logger
 #else
   static MsgLogger logger("Interval");   // message logger
 #endif
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 39514a03fc7d4..922ae5ace5991 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -75,7 +75,6 @@ End_Html */
 
 #include "TMath.h"
 #include "TRandom3.h"
-#include "ThreadLocalStorage.h"
 
 #include "TMVA/LogInterval.h"
 #include "TMVA/MsgLogger.h"
@@ -150,7 +149,7 @@ Double_t TMVA::LogInterval::GetMean()  const
 
 TMVA::MsgLogger& TMVA::LogInterval::Log() const {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("LogInterval");   // message logger
+  static thread_local MsgLogger logger("LogInterval");   // message logger
 #else
   static MsgLogger logger("LogInterval");   // message logger
 #endif
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index ab7bae9138a93..71b7af726cd1a 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -440,7 +440,7 @@ void TMVA::MethodBase::ProcessBaseOptions()
       SetOptions( fMVAPdfS->GetOptions() );
    }
 
-   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString,
+   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString, 
                                                DataInfo(),
                                                GetTransformationHandler(),
                                                Log() );
@@ -469,8 +469,8 @@ void TMVA::MethodBase::ProcessBaseOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn,
-                                                 TMVA::DataSetInfo& dataInfo,
+void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn, 
+                                                 TMVA::DataSetInfo& dataInfo, 
                                                  TMVA::TransformationHandler& transformationHandler,
                                                  TMVA::MsgLogger& log )
 {
@@ -572,7 +572,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
       if (transformation) {
          ClassInfo* clsInfo = dataInfo.GetClassInfo(idxCls);
          if (clsInfo )
-            log << kINFO << "Create Transformation \"" << trName << "\" with reference class "
+            log << kINFO << "Create Transformation \"" << trName << "\" with reference class " 
                 << clsInfo->GetName() << "=("<< idxCls <<")"<<Endl;
          else
             log << kINFO << "Create Transformation \"" << trName << "\" with events from all classes." << Endl;
@@ -588,7 +588,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
 void TMVA::MethodBase::DeclareCompatibilityOptions()
 {
    // options that are used ONLY for the READER to ensure backward compatibility
-   //   they are hence without any effect (the reader is only reading the training
+   //   they are hence without any effect (the reader is only reading the training 
    //   options that HAD been used at the training of the .xml weightfile at hand
 
    DeclareOptionRef( fNormalise=kFALSE, "Normalise", "Normalise input variables" ); // don't change the default !!!
@@ -622,8 +622,8 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
    // individually (as long as we don't have it automatized via the
    // configuraion string
 
-   Log() << kWARNING << "Parameter optimization is not yet implemented for method "
-         << GetName() << Endl;
+   Log() << kWARNING << "Parameter optimization is not yet implemented for method " 
+         << GetName() << Endl; 
    Log() << kWARNING << "Currently we need to set hardcoded which parameter is tuned in which ranges"<<Endl;
 
    std::map<TString,Double_t> tunedParameters;
@@ -636,7 +636,7 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
 void TMVA::MethodBase::SetTuneParameters(std::map<TString,Double_t> /* tuneParameters */)
 {
    // set the tuning parameters accoding to the argument
-   // This is just a dummy .. have a look at the MethodBDT how you could
+   // This is just a dummy .. have a look at the MethodBDT how you could 
    // perhaps implment the same thing for the other Classifiers..
 }
 
@@ -653,7 +653,7 @@ void TMVA::MethodBase::TrainMethod()
    BaseDir()->cd();
 
    // once calculate all the transformation (e.g. the sequence of Decorr:Gauss:Decorr)
-   //    needed for this classifier
+   //    needed for this classifier 
    GetTransformationHandler().CalcTransformations(Data()->GetEventCollection());
 
    // call training of derived MVA
@@ -681,9 +681,9 @@ void TMVA::MethodBase::TrainMethod()
          CreateMVAPdfs();
          AddClassifierOutputProb(Types::kTraining);
       }
-
+      
    } else {
-
+      
       Log() << "regression on training sample" << Endl;
       AddRegressionOutput( Types::kTraining );
 
@@ -707,7 +707,7 @@ void TMVA::MethodBase::TrainMethod()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const
+void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const 
 {
    if (!DoRegression()) Log() << kFATAL << "Trying to use GetRegressionDeviation() with a classification job" << Endl;
    Log() << kINFO << "Create results for " << (type==Types::kTraining?"training":"testing") << Endl;
@@ -820,16 +820,16 @@ Double_t TMVA::MethodBase::GetMvaValue( const Event* const ev, Double_t* err, Do
 }
 
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike() {
+Bool_t TMVA::MethodBase::IsSignalLike() { 
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event would be selected as signal or background
-   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
+   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
 }
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) {
+Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) { 
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event with this mva output value would tbe selected as signal or background
-   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
+   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
 }
 
 //_______________________________________________________________________
@@ -854,7 +854,7 @@ void TMVA::MethodBase::AddClassifierOutput( Types::ETreeType type )
    for (Int_t ievt=0; ievt<nEvents; ievt++) {
       Data()->SetCurrentEvent(ievt);
       clRes->SetValue( GetMvaValue(), ievt );
-
+      
       // print progress
       Int_t modulo = Int_t(nEvents/100);
       if (modulo <= 0 ) modulo = 1;
@@ -877,7 +877,7 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 
    Data()->SetCurrentType(type);
 
-   ResultsClassification* mvaProb =
+   ResultsClassification* mvaProb = 
       (ResultsClassification*)Data()->GetResults(TString("prob_")+GetMethodName(), type, Types::kClassification );
 
    Long64_t nEvents = Data()->GetNEvents();
@@ -907,15 +907,15 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
-                                       Double_t& dev,  Double_t& devT,
-                                       Double_t& rms,  Double_t& rmsT,
+void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT, 
+                                       Double_t& dev,  Double_t& devT, 
+                                       Double_t& rms,  Double_t& rmsT, 
                                        Double_t& mInf, Double_t& mInfT,
-                                       Double_t& corr,
+                                       Double_t& corr, 
                                        Types::ETreeType type )
 {
-   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample
-   //
+   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample 
+   //                    
    //   bias = average deviation
    //   dev  = average absolute deviation
    //   rms  = rms of deviation
@@ -933,7 +933,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    Float_t* wV = new Float_t[nevt];
    Float_t  xmin = 1e30, xmax = -1e30;
    for (Long64_t ievt=0; ievt<nevt; ievt++) {
-
+      
       const Event* ev = Data()->GetEvent(ievt); // NOTE: need untransformed event here !
       Float_t t = ev->GetTarget(0);
       Float_t w = ev->GetWeight();
@@ -948,7 +948,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
       rV[ievt] = r;
       tV[ievt] = t;
       wV[ievt] = w;
-
+      
       // compute deviation-squared
       sumw += w;
       bias += w * d;
@@ -968,8 +968,8 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    rms  = TMath::Sqrt(rms - bias*bias);
 
    // correlation
-   m1   /= sumw;
-   m2   /= sumw;
+   m1   /= sumw; 
+   m2   /= sumw; 
    corr  = s12/sumw - m1*m2;
    corr /= TMath::Sqrt( (s1/sumw - m1*m1) * (s2/sumw - m2*m2) );
 
@@ -989,11 +989,11 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
          sumw  += wV[ievt];
          biasT += wV[ievt] * d;
          devT  += wV[ievt] * TMath::Abs(d);
-         rmsT  += wV[ievt] * d * d;
+         rmsT  += wV[ievt] * d * d;       
          histT->Fill( rV[ievt], tV[ievt], wV[ievt] );
          ic++;
       }
-   }
+   }   
    biasT /= sumw;
    devT  /= sumw;
    rmsT  /= sumw;
@@ -1008,14 +1008,14 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    delete [] tV;
    delete [] wV;
 
-   Data()->SetCurrentType(savedType);
+   Data()->SetCurrentType(savedType);   
 }
 
 
 //_______________________________________________________________________
 void TMVA::MethodBase::TestMulticlass()
 {
-   // test multiclass classification
+   // test multiclass classification 
 
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in TestMulticlass, exiting."<<Endl;
@@ -1034,7 +1034,7 @@ void TMVA::MethodBase::TestClassification()
 
    ResultsClassification* mvaRes = dynamic_cast<ResultsClassification*>
       ( Data()->GetResults(GetMethodName(),Types::kTesting, Types::kClassification) );
-
+   
    // sanity checks: tree must exist, and theVar must be in tree
    if (0==mvaRes && !(GetMethodTypeName().Contains("Cuts"))) {
       Log() << "mvaRes " << mvaRes << " GetMethodTypeName " << GetMethodTypeName()
@@ -1042,24 +1042,24 @@ void TMVA::MethodBase::TestClassification()
       Log() << kFATAL << "<TestInit> Test variable " << GetTestvarName()
             << " not found in tree" << Endl;
    }
-
+   
    // basic statistics operations are made in base class
    gTools().ComputeStat( GetEventCollection(Types::kTesting), mvaRes->GetValueVector(),
                          fMeanS, fMeanB, fRmsS, fRmsB, fXmin, fXmax, fSignalClass );
-
+   
    // choose reasonable histogram ranges, by removing outliers
    Double_t nrms = 10;
    fXmin = TMath::Max( TMath::Min( fMeanS - nrms*fRmsS, fMeanB - nrms*fRmsB ), fXmin );
    fXmax = TMath::Min( TMath::Max( fMeanS + nrms*fRmsS, fMeanB + nrms*fRmsB ), fXmax );
-
+   
    // determine cut orientation
    fCutOrientation = (fMeanS > fMeanB) ? kPositive : kNegative;
 
    // fill 2 types of histograms for the various analyses
    // this one is for actual plotting
-
+   
    Double_t sxmax = fXmax+0.00001;
-
+   
    // classifier response distributions for training sample
    // MVA plots used for graphics representation (signal)
    TH1* mva_s = new TH1D( GetTestvarName() + "_S",GetTestvarName() + "_S", fNbinsMVAoutput, fXmin, sxmax );
@@ -1090,7 +1090,7 @@ void TMVA::MethodBase::TestClassification()
       rarity_s->Sumw2();
       rarity_b->Sumw2();
    }
-
+   
    // MVA plots used for efficiency calculations (large number of bins)
    TH1* mva_eff_s = new TH1D( GetTestvarName() + "_S_high", GetTestvarName() + "_S_high", fNbinsH, fXmin, sxmax );
    TH1* mva_eff_b = new TH1D( GetTestvarName() + "_B_high", GetTestvarName() + "_B_high", fNbinsH, fXmin, sxmax );
@@ -1098,26 +1098,26 @@ void TMVA::MethodBase::TestClassification()
    mvaRes->Store(mva_eff_b, "MVA_HIGHBIN_B");
    mva_eff_s->Sumw2();
    mva_eff_b->Sumw2();
-
+   
    // fill the histograms
    ResultsClassification* mvaProb = dynamic_cast<ResultsClassification*>
       (Data()->GetResults( TString("prob_")+GetMethodName(), Types::kTesting, Types::kMaxAnalysisType ) );
-
+   
    Log() << kINFO << "Loop over test events and fill histograms with classifier response..." << Endl;
    if (mvaProb) Log() << kINFO << "Also filling probability and rarity histograms (on request)..." << Endl;
    for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
-
+      
       const Event* ev = GetEvent(ievt);
       Float_t v = (*mvaRes)[ievt][0];
       Float_t w = ev->GetWeight();
-
+      
       if (DataInfo().IsSignal(ev)) {
          mva_s ->Fill( v, w );
          if (mvaProb) {
             proba_s->Fill( (*mvaProb)[ievt][0], w );
             rarity_s->Fill( GetRarity( v ), w );
          }
-
+         
          mva_eff_s ->Fill( v, w );
       }
       else {
@@ -1129,7 +1129,7 @@ void TMVA::MethodBase::TestClassification()
          mva_eff_b ->Fill( v, w );
       }
    }
-
+   
    // uncomment those (and several others if you want unnormalized output
    gTools().NormHist( mva_s  );
    gTools().NormHist( mva_b  );
@@ -1139,7 +1139,7 @@ void TMVA::MethodBase::TestClassification()
    gTools().NormHist( rarity_b );
    gTools().NormHist( mva_eff_s  );
    gTools().NormHist( mva_eff_b  );
-
+   
    // create PDFs from histograms, using default splines, and no additional smoothing
    if (fSplS) { delete fSplS; fSplS = 0; }
    if (fSplB) { delete fSplB; fSplB = 0; }
@@ -1188,7 +1188,7 @@ void TMVA::MethodBase::WriteStateToStream( std::ostream& tf ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const
+void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const 
 {
    // xml writing
    void* it = gTools().AddChild(gi,"Info");
@@ -1247,7 +1247,7 @@ void TMVA::MethodBase::WriteStateToXML( void* parent ) const
 
    // write class info if in multiclass mode
    AddClassesXMLTo(parent);
-
+   
    // write target info if in regression mode
    if (DoRegression()) AddTargetsXMLTo(parent);
 
@@ -1357,7 +1357,7 @@ void TMVA::MethodBase::ReadStateFromXMLString( const char* xmlstr ) {
    ReadStateFromXML(rootnode);
    gTools().xmlengine().FreeDoc(doc);
 #else
-   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = "
+   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = " 
          << xmlstr << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
 #endif
 
@@ -1638,9 +1638,9 @@ void TMVA::MethodBase::ReadVarsFromStream( std::istream& istr )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
+void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const 
 {
-   // write variable info to XML
+   // write variable info to XML 
    void* vars = gTools().AddChild(parent, "Variables");
    gTools().AddAttr( vars, "NVar", gTools().StringFromInt(DataInfo().GetNVariables()) );
 
@@ -1653,9 +1653,9 @@ void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
+void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const 
 {
-   // write spectator info to XML
+   // write spectator info to XML 
    void* specs = gTools().AddChild(parent, "Spectators");
 
    UInt_t writeIdx=0;
@@ -1675,14 +1675,14 @@ void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
+void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const 
 {
-   // write class info to XML
+   // write class info to XML 
    UInt_t nClasses=DataInfo().GetNClasses();
-
+   
    void* classes = gTools().AddChild(parent, "Classes");
    gTools().AddAttr( classes, "NClass", nClasses );
-
+   
    for (UInt_t iCls=0; iCls<nClasses; ++iCls) {
       ClassInfo *classInfo=DataInfo().GetClassInfo (iCls);
       TString  className  =classInfo->GetName();
@@ -1694,9 +1694,9 @@ void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
    }
 }
 //_______________________________________________________________________
-void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
+void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const 
 {
-   // write target info to XML
+   // write target info to XML 
    void* targets = gTools().AddChild(parent, "Targets");
    gTools().AddAttr( targets, "NTrgt", gTools().StringFromInt(DataInfo().GetNTargets()) );
 
@@ -1709,7 +1709,7 @@ void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
+void TMVA::MethodBase::ReadVariablesFromXML( void* varnode ) 
 {
    // read variable info from XML
    UInt_t readNVar;
@@ -1729,11 +1729,11 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
       gTools().ReadAttr( ch, "VarIndex", varIdx);
       existingVarInfo = DataInfo().GetVariableInfos()[varIdx];
       readVarInfo.ReadFromXML(ch);
-
+      
       if (existingVarInfo.GetExpression() == readVarInfo.GetExpression()) {
          readVarInfo.SetExternalLink(existingVarInfo.GetExternalLink());
          existingVarInfo = readVarInfo;
-      }
+      } 
       else {
          Log() << kINFO << "ERROR in <ReadVariablesFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the variables found in the input file is"  << Endl;
@@ -1748,7 +1748,7 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
+void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode ) 
 {
    // read spectator info from XML
    UInt_t readNSpec;
@@ -1768,11 +1768,11 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
       gTools().ReadAttr( ch, "SpecIndex", specIdx);
       existingSpecInfo = DataInfo().GetSpectatorInfos()[specIdx];
       readSpecInfo.ReadFromXML(ch);
-
+      
       if (existingSpecInfo.GetExpression() == readSpecInfo.GetExpression()) {
          readSpecInfo.SetExternalLink(existingSpecInfo.GetExternalLink());
          existingSpecInfo = readSpecInfo;
-      }
+      } 
       else {
          Log() << kINFO << "ERROR in <ReadSpectatorsFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the spectators found in the input file is"  << Endl;
@@ -1787,7 +1787,7 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
+void TMVA::MethodBase::ReadClassesFromXML( void* clsnode ) 
 {
    // read number of classes from XML
    UInt_t readNCls;
@@ -1828,7 +1828,7 @@ void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode )
+void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode ) 
 {
    // read target info from XML
    UInt_t readNTar;
@@ -1935,7 +1935,7 @@ TString TMVA::MethodBase::GetWeightFileName() const
    // directory/jobname_methodname_suffix.extension.{root/txt}
    TString suffix = "";
    TString wFileDir(GetWeightFileDir());
-   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/")
+   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/") 
             + GetJobName() + "_" + GetMethodName() +
             suffix + "." + gConfig().GetIONames().fWeightFileExtension + ".xml" );
 }
@@ -1962,7 +1962,7 @@ void TMVA::MethodBase::WriteEvaluationHistosToFile(Types::ETreeType treetype)
    Results* results = Data()->GetResults( GetMethodName(), treetype, Types::kMaxAnalysisType );
    if (!results)
       Log() << kFATAL << "<WriteEvaluationHistosToFile> Unknown result: "
-            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting")
+            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting") 
             << "/kMaxAnalysisType" << Endl;
    results->GetStorage()->Write();
    if (treetype==Types::kTesting) {
@@ -2013,8 +2013,8 @@ Bool_t TMVA::MethodBase::GetLine(std::istream& fin, char* buf )
       else if (analysisType == "multiclass"     || analysisType == "Multiclass")     SetAnalysisType( Types::kMulticlass );
       else Log() << kFATAL << "Analysis type " << analysisType << " from weight-file not known!" << std::endl;
 
-      Log() << kINFO << "Method was trained for "
-            << (GetAnalysisType() == Types::kRegression ? "Regression" :
+      Log() << kINFO << "Method was trained for " 
+            << (GetAnalysisType() == Types::kRegression ? "Regression" : 
                 (GetAnalysisType() == Types::kMulticlass ? "Multiclass" : "Classification")) << Endl;
    }
 
@@ -2094,7 +2094,7 @@ Double_t TMVA::MethodBase::GetProba(const Event *ev){
    }
    Double_t sigFraction = DataInfo().GetTrainingSumSignalWeights() / (DataInfo().GetTrainingSumSignalWeights() + DataInfo().GetTrainingSumBackgrWeights() );
    Double_t mvaVal = GetMvaValue(ev);
-
+   
    return GetProba(mvaVal,sigFraction);
 
 }
@@ -2172,7 +2172,7 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
 #if __cplusplus > 199711L
-   static TTHREAD_TLS(Double_t) nevtS;
+   static thread_local Double_t nevtS;
 #else
    static Double_t nevtS;
 #endif
@@ -2479,7 +2479,7 @@ Double_t TMVA::MethodBase::GetTrainingEfficiency(const TString& theString)
       // note that there is a bin shift when going from a TH1D object to a TGraph :-(
       if (Use_Splines_for_Eff_) {
          if (fSplTrainRefS) delete fSplTrainRefS;
-         if (fSplTrainRefB) delete fSplTrainRefB;
+         if (fSplTrainRefB) delete fSplTrainRefB;         
          fSplTrainRefS  = new TSpline1( "spline2_signal",     new TGraph( mva_eff_tr_s ) );
          fSplTrainRefB  = new TSpline1( "spline2_background", new TGraph( mva_eff_tr_b ) );
 
@@ -2548,8 +2548,8 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassEfficiency(std::vector<std::
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassEfficiency, exiting."<<Endl;
 
-   purity.push_back(resMulticlass->GetAchievablePur());
-   return resMulticlass->GetAchievableEff();
+   purity.push_back(resMulticlass->GetAchievablePur()); 
+   return resMulticlass->GetAchievableEff(); 
 }
 
 //_______________________________________________________________________
@@ -2559,14 +2559,14 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassTrainingEfficiency(std::vect
    Data()->SetCurrentType(Types::kTraining);
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTraining, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassTrainingEfficiency, exiting."<<Endl;
-
+   
    Log() << kINFO << "Determine optimal multiclass cuts for training data..." << Endl;
    for (UInt_t icls = 0; icls<DataInfo().GetNClasses(); ++icls) {
       resMulticlass->GetBestMultiClassCuts(icls);
    }
-
-   purity.push_back(resMulticlass->GetAchievablePur());
-   return resMulticlass->GetAchievableEff();
+    
+   purity.push_back(resMulticlass->GetAchievablePur()); 
+   return resMulticlass->GetAchievableEff(); 
 }
 
 
@@ -2637,10 +2637,10 @@ Double_t TMVA::MethodBase::GetROCIntegral(TH1D *histS, TH1D *histB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   }
+   } 
    return integral*step;
 }
-
+   
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
@@ -2667,7 +2667,7 @@ Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   }
+   } 
    return integral*step;
 }
 
@@ -2996,7 +2996,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "                 varIt != inputValues.end(); varIt++, ivar++) {" << std::endl;
    fout << "               iV.push_back(NormVariable( *varIt, fVmin[ivar], fVmax[ivar] ));" << std::endl;
    fout << "            }" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            Transform( iV, -1 );" << std::endl;
@@ -3004,7 +3004,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "            retval = GetMvaValue__( iV );" << std::endl;
    fout << "         }" << std::endl;
    fout << "         else {" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            std::vector<double> iV;" << std::endl;
@@ -3090,7 +3090,7 @@ void TMVA::MethodBase::PrintHelpMessage() const
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
 #if __cplusplus > 199711L
-TTHREAD_TLS(TMVA::MethodBase*) TMVA::MethodBase::fgThisBase = 0;
+thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
 #else
 TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
 #endif
@@ -3128,18 +3128,18 @@ Double_t TMVA::MethodBase::GetEffForRoot( Double_t theCut )
 }
 
 //_______________________________________________________________________
-const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type)
+const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type) 
 {
    // returns the event collection (i.e. the dataset) TRANSFORMED using the
    //   classifiers specific Variable Transformation (e.g. Decorr or Decorr:Gauss:Decorr)
 
-   // if there's no variable transformation for this classifier, just hand back the
+   // if there's no variable transformation for this classifier, just hand back the 
    //  event collection of the data set
    if (GetTransformationHandler().GetTransformationList().GetEntries() <= 0) {
       return (Data()->GetEventCollection(type));
-   }
+   } 
 
-   // otherwise, transform ALL the events and hand back the vector of the pointers to the
+   // otherwise, transform ALL the events and hand back the vector of the pointers to the 
    // transformed events. If the pointer is already != 0, i.e. the whole thing has been
    // done before, I don't need to do it again, but just "hand over" the pointer to those events.
    Int_t idx = Data()->TreeIndex(type);  //index indicating Training,Testing,...  events/datasets
@@ -3171,19 +3171,19 @@ TString TMVA::MethodBase::GetTrainingROOTVersionString() const
 
    return TString(Form("%i.%02i/%02i",a,b,c));
 }
-
+ 
 //_______________________________________________________________________
 TMVA::MethodBase* TMVA::MethodBase::GetThisBase()
 {
    // return a pointer the base class of this method
-   return fgThisBase;
+   return fgThisBase; 
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ResetThisBase()
-{
+void TMVA::MethodBase::ResetThisBase() 
+{ 
    // reset required for RootFinder
-   fgThisBase = this;
+   fgThisBase = this; 
 }
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
@@ -3198,7 +3198,7 @@ Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
      TH1D *mva_b_tr = dynamic_cast<TH1D*> (mvaRes->GetHist("MVA_TRAIN_B"));
 
      if ( !mva_s || !mva_b || !mva_s_tr || !mva_b_tr) return -1;
-
+ 
      if (SorB == 's' || SorB == 'S')
        return mva_s->KolmogorovTest( mva_s_tr, opt.Data() );
      else
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 91e33c05d7674..9e4f58143e1b5 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -85,10 +85,10 @@ TMVA::MethodMLP::MethodMLP( const TString& jobName,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -107,10 +107,10 @@ TMVA::MethodMLP::MethodMLP( DataSetInfo& theData,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -221,13 +221,13 @@ void TMVA::MethodMLP::ProcessOptions()
    // process user options
    MethodANNBase::ProcessOptions();
 
-
+   
    if (IgnoreEventsWithNegWeightsInTraining()) {
-      Log() << kINFO
+      Log() << kINFO 
             << "Will ignore negative events in training!"
             << Endl;
    }
-
+   
 
    if      (fTrainMethodS == "BP"  ) fTrainingMethod = kBP;
    else if (fTrainMethodS == "BFGS") fTrainingMethod = kBFGS;
@@ -301,8 +301,8 @@ Double_t TMVA::MethodMLP::CalculateEstimator( Types::ETreeType treeType, Int_t i
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event* ev = GetEvent(i);
-
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
+      
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
           &&  (saveType == Types::kTraining)){
          continue;
       }
@@ -419,7 +419,7 @@ void TMVA::MethodMLP::Train(Int_t nEpochs)
 
    Int_t nEvents=GetNEvents();
    Int_t nSynapses=fSynapses->GetEntriesFast();
-   if (nSynapses>nEvents)
+   if (nSynapses>nEvents) 
       Log()<<kWARNING<<"ANN too complicated: #events="<<nEvents<<"\t#synapses="<<nSynapses<<Endl;
 
 #ifdef MethodMLP_UseMinuit__
@@ -661,7 +661,7 @@ void TMVA::MethodMLP::ComputeDEDw()
    for (Int_t i=0;i<nEvents;i++) {
 
       const Event* ev = GetEvent(i);
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          --nPosEvents;
          continue;
@@ -810,7 +810,7 @@ Bool_t TMVA::MethodMLP::LineSearch(TMatrixD &Dir, std::vector<Double_t> &buffer,
 
    SetDirWeights( Origin, Dir, alpha2 );
    Double_t err2 = GetError();
-   //Double_t err2 = err1;
+   //Double_t err2 = err1; 
    Double_t err3 = err2;
    Bool_t bingo = kFALSE;
 
@@ -918,7 +918,7 @@ Double_t TMVA::MethodMLP::GetError()
    for (Int_t i=0;i<nEvents;i++) {
       const Event* ev = GetEvent(i);
 
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
@@ -1089,11 +1089,11 @@ void TMVA::MethodMLP::TrainOneEpoch()
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event * ev = GetEvent(index[i]);
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
-
+      
       TrainOneEvent(index[i]);
 
       // do adjustments if in batch mode
@@ -1146,7 +1146,7 @@ void TMVA::MethodMLP::DecaySynapseWeights(Bool_t lateEpoch)
    TSynapse* synapse;
    Int_t numSynapses = fSynapses->GetEntriesFast();
    for (Int_t i = 0; i < numSynapses; i++) {
-      synapse = (TSynapse*)fSynapses->At(i);
+      synapse = (TSynapse*)fSynapses->At(i);      
       if (lateEpoch) synapse->DecayLearningRate(TMath::Sqrt(fDecayRate)); // In order to lower the learning rate even more, we need to apply sqrt instead of square.
       else           synapse->DecayLearningRate(fDecayRate);
    }
@@ -1160,13 +1160,13 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    GetEvent(ievt);
 
    // as soon as we know how to get event weights, get that here
-
+   
    // note: the normalization of event weights will affect the choice
    // of learning rate, one will have to experiment to get the right value.
    // in general, if the "average" event weight is 1, the learning rate
    // should be good if set around 0.02 (a good value if all event weights are 1)
    Double_t eventWeight = 1.0;
-
+   
    // get the desired output of this event
    Double_t desired;
    if (type == 0) desired = fOutput->GetMin();  // background //zjh
@@ -1175,7 +1175,7 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    // force the value for each input neuron
    Double_t x;
    TNeuron* neuron;
-
+   
    for (UInt_t j = 0; j < GetNvar(); j++) {
       x = branchVar[j];
       if (IsNormalised()) x = gTools().NormVariable( x, GetXmin( j ), GetXmax( j ) );
@@ -1260,7 +1260,7 @@ void TMVA::MethodMLP::CalculateNeuronDeltas()
    for (Int_t i = numLayers-1; i >= 0; i--) {
       curLayer = (TObjArray*)fNetwork->At(i);
       numNeurons = curLayer->GetEntriesFast();
-
+  
       for (Int_t j = 0; j < numNeurons; j++) {
          neuron = (TNeuron*) curLayer->At(j);
          neuron->CalculateDelta();
@@ -1498,7 +1498,7 @@ Double_t TMVA::MethodMLP::GetMvaValue( Double_t* errLower, Double_t* errUpper )
      variance=0;
    }
    variance=sqrt(variance);
-
+ 
    //upper
    MvaUpper=fOutput->Eval(median+variance);
    if(errUpper)
@@ -1584,8 +1584,8 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
 }
 
 #if __cplusplus > 199711L
-static TTHREAD_TLS(Int_t)  nc   = 0;
-static TTHREAD_TLS(Double_t) minf = 1000000;
+static thread_local Int_t  nc   = 0;
+static thread_local double minf = 1000000;
 #else
 static Int_t  nc   = 0;
 static double minf = 1000000;
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 9281f2b414014..96d03cc58b61f 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -88,7 +88,7 @@ namespace TMVA {
 };
 
 #if __cplusplus > 199711L
-TTHREAD_TLS(TMVA::MethodPDERS*) TMVA::MethodPDERS::fgThisPDERS = NULL;
+thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
 #else
 TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
 #endif
@@ -189,7 +189,7 @@ void TMVA::MethodPDERS::Init( void )
    fInitialScale    = 0.99;
    fGaussSigma      = 0.1;
    fNormTree        = kFALSE;
-
+    
    fkNNMin      = Int_t(fNEventsMin);
    fkNNMax      = Int_t(fNEventsMax);
 
@@ -211,12 +211,12 @@ TMVA::MethodPDERS::~MethodPDERS( void )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::DeclareOptions()
+void TMVA::MethodPDERS::DeclareOptions() 
 {
-   // define the options (their key words) that can be set in the option string
+   // define the options (their key words) that can be set in the option string 
    // know options:
    // VolumeRangeMode   <string>  Method to determine volume range
-   //    available values are:        MinMax
+   //    available values are:        MinMax 
    //                                 Unscaled
    //                                 RMS
    //                                 kNN
@@ -239,10 +239,10 @@ void TMVA::MethodPDERS::DeclareOptions()
    //                                 Trim
    //
    // DeltaFrac         <float>   Ratio of #EventsMin/#EventsMax for MinMax and RMS volume range
-   // NEventsMin        <int>     Minimum number of events for adaptive volume range
+   // NEventsMin        <int>     Minimum number of events for adaptive volume range             
    // NEventsMax        <int>     Maximum number of events for adaptive volume range
    // MaxVIterations    <int>     Maximum number of iterations for adaptive volume range
-   // InitialScale      <float>   Initial scale for adaptive volume range
+   // InitialScale      <float>   Initial scale for adaptive volume range           
    // GaussSigma        <float>   Width with respect to the volume size of Gaussian kernel estimator
    DeclareOptionRef(fVolumeRange="Adaptive", "VolumeRangeMode", "Method to determine volume size");
    AddPreDefVal(TString("Unscaled"));
@@ -277,13 +277,13 @@ void TMVA::MethodPDERS::DeclareOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::ProcessOptions()
+void TMVA::MethodPDERS::ProcessOptions() 
 {
    // process the options specified by the user
-
+   
    if (IgnoreEventsWithNegWeightsInTraining()) {
       Log() << kFATAL << "Mechanism to ignore events with negative weights in training not yet available for method: "
-            << GetMethodTypeName()
+            << GetMethodTypeName() 
             << " --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
             << Endl;
    }
@@ -342,13 +342,13 @@ void TMVA::MethodPDERS::Train( void )
    // trainingTree in the weight file, and to rebuild the binary tree in the
    // test phase from scratch
 
-   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; "
+   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; " 
                                << "please remove the option from the configuration string, or "
                                << "use \"!Normalise\""
                                << Endl;
 
    CreateBinarySearchTree( Types::kTraining );
-
+    
    CalcAverages();
    SetVolumeElement();
 
@@ -425,7 +425,7 @@ void TMVA::MethodPDERS::CalcAverages()
       fAverageRMS.clear();
       fBinaryTree->CalcStatistics();
 
-      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
+      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) { 
          if (!DoRegression()){ //why there are separate rms for signal and background?
             Float_t rmsS = fBinaryTree->RMS(Types::kSignal, ivar);
             Float_t rmsB = fBinaryTree->RMS(Types::kBackground, ivar);
@@ -436,7 +436,7 @@ void TMVA::MethodPDERS::CalcAverages()
          }
       }
    }
-}
+}   
 
 //_______________________________________________________________________
 void TMVA::MethodPDERS::CreateBinarySearchTree( Types::ETreeType type )
@@ -474,7 +474,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    // init relative scales
    fkNNMin      = Int_t(fNEventsMin);
-   fkNNMax      = Int_t(fNEventsMax);
+   fkNNMax      = Int_t(fNEventsMax);   
 
    if (fDelta) delete fDelta;
    if (fShift) delete fShift;
@@ -483,7 +483,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       switch (fVRangeMode) {
-
+         
       case kRMS:
       case kkNN:
       case kAdaptive:
@@ -778,7 +778,7 @@ Double_t TMVA::MethodPDERS::CRScalc( const Event& e )
    }
 
    Volume *volume = new Volume( lb, ub );
-
+   
    GetSample( e, events, volume );
    Double_t count = CKernelEstimate( e, events, *volume );
    delete volume;
@@ -948,22 +948,22 @@ Double_t TMVA::MethodPDERS::ApplyKernelFunction (Double_t normalized_distance)
 
    return 0;
 }
-
+      
 //_______________________________________________________________________
-Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
+Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf) 
 {
-   // Calculating the normalization factor only once (might need a reset at some point.
+   // Calculating the normalization factor only once (might need a reset at some point. 
    // Can the method be restarted with different params?)
 
-   // Caching jammed to disable function.
+   // Caching jammed to disable function. 
    // It's not really useful afterall, badly implemented and untested :-)
 #if __cplusplus > 199711L
-   static TTHREAD_TLS(Double_t) ret = 1.0;
+   static thread_local Double_t ret = 1.0; 
 #else
-   static Double_t ret = 1.0;
+   static Double_t ret = 1.0; 
 #endif
-
-   if (ret != 0.0) return ret*pdf;
+   
+   if (ret != 0.0) return ret*pdf; 
 
    // We first normalize by the volume of the hypersphere.
    switch (fKernelEstimator) {
@@ -1005,7 +1005,7 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 //_______________________________________________________________________
 Double_t TMVA::MethodPDERS::GetNormalizedDistance ( const Event &base_event,
                                                     const BinarySearchTreeNode &sample_event,
-                                                    Double_t *dim_normalization)
+                                                    Double_t *dim_normalization) 
 {
    // We use Euclidian metric here. Might not be best or most efficient.
    Double_t ret=0;
@@ -1155,16 +1155,16 @@ void TMVA::MethodPDERS::ReadWeightsFromStream( TFile& /*rf*/ )
 }
 
 //_______________________________________________________________________
-TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void )
-{
+TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void ) 
+{ 
    // static pointer to this object
-   return fgThisPDERS;
+   return fgThisPDERS; 
 }
 //_______________________________________________________________________
-void TMVA::MethodPDERS::UpdateThis( void )
+void TMVA::MethodPDERS::UpdateThis( void ) 
 {
    // update static this pointer
-   fgThisPDERS = this;
+   fgThisPDERS = this; 
 }
 
 //_______________________________________________________________________
@@ -1180,7 +1180,7 @@ void TMVA::MethodPDERS::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line:
+   // typical length of text line: 
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index 8925db79de4e3..e6ee4baca6918 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -129,7 +129,7 @@ void TMVA::MethodTMlpANN::Init( void )
 //_______________________________________________________________________
 TMVA::MethodTMlpANN::~MethodTMlpANN( void )
 {
-   // destructor
+   // destructor 
    if (fMLP) delete fMLP;
 }
 
@@ -224,7 +224,7 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
 #if __cplusplus > 199711L
-   static TTHREAD_TLS(Double_t*) d = new Double_t[Data()->GetNVariables()];
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
 #endif
@@ -258,17 +258,17 @@ void TMVA::MethodTMlpANN::Train( void )
    Int_t type;
    Float_t weight;
    const Long_t basketsize = 128000;
-   Float_t* vArr = new Float_t[GetNvar()];
+   Float_t* vArr = new Float_t[GetNvar()]; 
 
    TTree *localTrainingTree = new TTree( "TMLPtrain", "Local training tree for TMlpANN" );
    localTrainingTree->Branch( "type",       &type,        "type/I",        basketsize );
    localTrainingTree->Branch( "weight",     &weight,      "weight/F",      basketsize );
-
+   
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       const char* myVar = GetInternalVarName(ivar).Data();
       localTrainingTree->Branch( myVar, &vArr[ivar], Form("Var%02i/F", ivar), basketsize );
    }
-
+   
    for (UInt_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
       const Event *ev = GetEvent(ievt);
       for (UInt_t i=0; i<GetNvar(); i++) {
@@ -399,15 +399,15 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
          }
       }
       if (strcmp(gTools().GetName(ch),"neurons")==0) {
-         fout << "#neurons weights" << std::endl;
+         fout << "#neurons weights" << std::endl;         
          while (content >> temp1) {
             fout << temp1 << std::endl;
          }
       }
       if (strcmp(gTools().GetName(ch),"synapses")==0) {
-         fout << "#synapses weights" ;
+         fout << "#synapses weights" ;         
          while (content >> temp1) {
-            fout << std::endl << temp1 ;
+            fout << std::endl << temp1 ;                
          }
       }
       ch = gTools().GetNextChild(ch);
@@ -417,8 +417,8 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
 #if __cplusplus > 199711L
-   static TTHREAD_TLS(Double_t*) d = new Double_t[Data()->GetNVariables()] ;
-   static TTHREAD_TLS(Int_t) type;
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
+   static thread_local Int_t type;
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
@@ -436,7 +436,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    fMLP = new TMultiLayerPerceptron( fMLPBuildOptions.Data(), dummyTree );
    fMLP->LoadWeights( fname );
 }
-
+ 
 //_______________________________________________________________________
 void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
 {
@@ -450,7 +450,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    // the MLP is already build
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
-   Double_t* d = new Double_t[Data()->GetNVariables()] ;
+   Double_t* d = new Double_t[Data()->GetNVariables()] ; 
    Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -499,7 +499,7 @@ void TMVA::MethodTMlpANN::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line:
+   // typical length of text line: 
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index e803c16c36076..2160b5dfee708 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Rustem Ospanov
+// Author: Rustem Ospanov 
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -14,8 +14,8 @@
  *      Rustem Ospanov <rustem@fnal.gov> - U. of Texas at Austin, USA             *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
- *      CERN, Switzerland                                                         *
- *      MPI-K Heidelberg, Germany                                                 *
+ *      CERN, Switzerland                                                         * 
+ *      MPI-K Heidelberg, Germany                                                 * 
  *      U. of Texas at Austin, USA                                                *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -33,13 +33,12 @@
 #include <algorithm>
 
 #include "TMath.h"
-#include "ThreadLocalStorage.h"
 
 // TMVA
 #include "TMVA/MsgLogger.h"
-
+ 
 //-------------------------------------------------------------------------------------------
-TMVA::kNN::Event::Event()
+TMVA::kNN::Event::Event() 
    :fVar(),
     fWeight(-1.0),
     fType(-1)
@@ -82,12 +81,12 @@ TMVA::kNN::VarType TMVA::kNN::Event::GetDist(const Event &other) const
       std::cerr << "Distance: two events have different dimensions" << std::endl;
       return -1.0;
    }
-
+   
    VarType sum = 0.0;
    for (UInt_t ivar = 0; ivar < nvar; ++ivar) {
       sum += GetDist(other.GetVar(ivar), ivar);
    }
-
+   
    return sum;
 }
 
@@ -155,7 +154,7 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
 
 
 #if __cplusplus > 199711L
-TTHREAD_TLS(TRandom3) TMVA::kNN::ModulekNN::fgRndm(1);
+thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
 #else
 TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
 #endif
@@ -198,11 +197,11 @@ void TMVA::kNN::ModulekNN::Clear()
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::Add(const Event &event)
-{
+{   
    // add an event to tree
    if (fTree) {
       Log() << kFATAL << "<Add> Cannot add event: tree is already built" << Endl;
-      return;
+      return;      
    }
 
    if (fDimn < 1) {
@@ -235,7 +234,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    if (fTree) {
       Log() << kFATAL << "ModulekNN::Fill - tree has already been created" << Endl;
       return kFALSE;
-   }
+   }   
 
    // If trim option is set then find class with lowest number of events
    // and set that as maximum number of events for all other classes.
@@ -246,14 +245,14 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
             min = it->second;
          }
       }
-
+      
       Log() << kINFO << "<Fill> Will trim all event types to " << min << " events" << Endl;
-
+      
       fCount.clear();
       fVar.clear();
-
+      
       EventVec evec;
-
+      
       for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
          std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
          if (cit == fCount.end()) {
@@ -274,7 +273,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
       }
 
       Log() << kINFO << "<Fill> Erased " << fEvent.size() - evec.size() << " events" << Endl;
-
+      
       fEvent = evec;
    }
 
@@ -288,7 +287,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
 
    if (option.find("metric") != std::string::npos && ifrac > 0) {
       ComputeMetric(ifrac);
-
+      
       // sort again each variable for all events - needs this before Optimize()
       // rescaling has changed variable values
       for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
@@ -301,15 +300,15 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    // all child nodes. If odepth = 0 then split variable 0
    // at the median (in half) and return it as root node
    fTree = Optimize(odepth);
-
+   
    if (!fTree) {
       Log() << kFATAL << "ModulekNN::Fill() - failed to create tree" << Endl;
-      return kFALSE;
-   }
-
+      return kFALSE;      
+   }      
+   
    for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
       fTree->Add(*event, 0);
-
+      
       std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
       if (cit == fCount.end()) {
          fCount[event->GetType()] = 1;
@@ -318,20 +317,20 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
          ++(cit->second);
       }
    }
-
+   
    for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
-      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8)
+      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8) 
               << it->second << " events" << Endl;
    }
-
+   
    return kTRUE;
 }
 
 //-------------------------------------------------------------------------------------------
 Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::string &option) const
-{
+{  
    // find in tree
-   // if tree has been filled then search for nfind closest events
+   // if tree has been filled then search for nfind closest events 
    // if metic (fVarScale map) is computed then rescale event variables
    // using previsouly computed width of variable distribution
 
@@ -357,7 +356,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    // latest event for k-nearest neighbor search
    fkNNEvent = event;
    fkNNList.clear();
-
+   
    if(option.find("weight") != std::string::npos)
    {
       // recursive kd-tree search for nfind-nearest neighbors
@@ -369,7 +368,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    {
       // recursive kd-tree search for nfind-nearest neighbors
       // count nodes and do not use event weight
-      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);
+      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);      
    }
 
    return kTRUE;
@@ -382,11 +381,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
    if (fCount.empty() || !fTree) {
       return kFALSE;
    }
-
+   
 #if __cplusplus > 199711L
-   //this to be able to use the macro
-   using stdMapShorttUinnttconstIterator = std::map<Short_t, UInt_t>::const_iterator;
-   static TTHREAD_TLS(stdMapShorttUinnttconstIterator) cit = fCount.end();
+   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
 #else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
 #endif
@@ -404,9 +401,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          if (vit == fVar.end()) {
             return kFALSE;
          }
-
+         
          const std::vector<Double_t> &vvec = vit->second;
-
+         
          if (vvec.empty()) {
             return kFALSE;
          }
@@ -415,7 +412,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          const VarType min = vvec.front();
          const VarType max = vvec.back();
          const VarType width = max - min;
-
+         
          if (width < 0.0 || width > 0.0) {
             dvec.push_back(min + width*fgRndm.Rndm());
          }
@@ -425,9 +422,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       }
 
       const Event event(dvec, 1.0, etype);
-
+      
       Find(event, nfind);
-
+      
       return kTRUE;
    }
 
@@ -462,8 +459,8 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
 
    if (double(fDimn*size) < TMath::Power(2.0, double(odepth))) {
       Log() << kWARNING << "<Optimize> Optimization depth exceeds number of events" << Endl;
-      return 0;
-   }
+      return 0;      
+   }   
 
    Log() << kINFO << "Optimizing tree for " << fDimn << " variables with " << size << " values" << Endl;
 
@@ -476,14 +473,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
    }
 
    const Event pevent(VarVec(fDimn, (it->second)[size/2]), -1.0, -1);
-
+   
    Node<Event> *tree = new Node<Event>(0, pevent, 0);
-
+   
    pvec.push_back(tree);
 
-   for (UInt_t depth = 1; depth < odepth; ++depth) {
+   for (UInt_t depth = 1; depth < odepth; ++depth) {            
       const UInt_t mod = depth % fDimn;
-
+      
       VarMap::const_iterator vit = fVar.find(mod);
       if (vit == fVar.end()) {
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
@@ -495,26 +492,26 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
          return 0;
       }
-
+      
       UInt_t ichild = 1;
       for (std::vector<Node<Event> *>::iterator pit = pvec.begin(); pit != pvec.end(); ++pit) {
          Node<Event> *parent = *pit;
-
+         
          const VarType lmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
 
          const VarType rmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
-
+      
          const Event levent(VarVec(fDimn, lmedian), -1.0, -1);
          const Event revent(VarVec(fDimn, rmedian), -1.0, -1);
-
+         
          Node<Event> *lchild = new Node<Event>(parent, levent, mod);
          Node<Event> *rchild = new Node<Event>(parent, revent, mod);
-
+         
          parent->SetNodeL(lchild);
          parent->SetNodeR(rchild);
-
+         
          cvec.push_back(lchild);
          cvec.push_back(rchild);
       }
@@ -522,14 +519,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
       pvec = cvec;
       cvec.clear();
    }
-
+   
    return tree;
 }
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
 {
-   // compute scale factor for each variable (dimension) so that
+   // compute scale factor for each variable (dimension) so that 
    // distance is computed uniformely along each dimension
    // compute width of interval that includes (100 - 2*ifrac)% of events
    // below, assume that in fVar each vector of values is sorted
@@ -540,37 +537,37 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
    if (ifrac > 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - fraction can not exceed 100%" << Endl;
       return;
-   }
+   }   
    if (!fVarScale.empty()) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - metric is already computed" << Endl;
       return;
    }
    if (fEvent.size() < 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - number of events is too small" << Endl;
-      return;
+      return;      
    }
 
    const UInt_t lfrac = (100 - ifrac)/2;
    const UInt_t rfrac = 100 - (100 - ifrac)/2;
 
-   Log() << kINFO << "Computing scale factor for 1d distributions: "
-           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;
+   Log() << kINFO << "Computing scale factor for 1d distributions: " 
+           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;   
 
    fVarScale.clear();
-
+   
    for (VarMap::const_iterator vit = fVar.begin(); vit != fVar.end(); ++vit) {
       const std::vector<Double_t> &dvec = vit->second;
-
+      
       std::vector<Double_t>::const_iterator beg_it = dvec.end();
       std::vector<Double_t>::const_iterator end_it = dvec.end();
-
+      
       Int_t dist = 0;
       for (std::vector<Double_t>::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit, ++dist) {
-
+         
          if ((100*dist)/dvec.size() == lfrac && beg_it == dvec.end()) {
             beg_it = dit;
          }
-
+         
          if ((100*dist)/dvec.size() == rfrac && end_it == dvec.end()) {
             end_it = dit;
          }
@@ -579,35 +576,35 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
       if (beg_it == dvec.end() || end_it == dvec.end()) {
          beg_it = dvec.begin();
          end_it = dvec.end();
-
+         
          assert(beg_it != end_it && "Empty vector");
-
+         
          --end_it;
       }
 
       const Double_t lpos = *beg_it;
       const Double_t rpos = *end_it;
-
+      
       if (!(lpos < rpos)) {
          Log() << kFATAL << "ModulekNN::ComputeMetric() - min value is greater than max value" << Endl;
          continue;
       }
-
+      
       // Rustem: please find a solution that does not use distance (it does not exist on solaris)
-      //       Log() << kINFO << "Variable " << vit->first
+      //       Log() << kINFO << "Variable " << vit->first 
       //               << " included " << distance(beg_it, end_it) + 1
       //               << " events: width = " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos - lpos
-      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos
+      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos 
       //               << ", " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos << ")" << Endl;
-
+      
       fVarScale[vit->first] = rpos - lpos;
    }
 
    fVar.clear();
 
-   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {
+   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {      
       fEvent[ievent] = Scale(fEvent[ievent]);
-
+      
       for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
          fVar[ivar].push_back(fEvent[ievent].GetVar(ivar));
       }
@@ -619,7 +616,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
 {
    // scale each event variable so that rms of variables is approximately 1.0
    // this allows comparisons of variables with distinct scales and units
-
+   
    if (fVarScale.empty()) {
       return event;
    }
@@ -637,7 +634,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
          Log() << kFATAL << "ModulekNN::Scale() - failed to find scale for " << ivar << Endl;
          continue;
       }
-
+      
       if (fit->second > 0.0) {
          vvec[ivar] = event.GetVar(ivar)/fit->second;
       }
@@ -671,7 +668,7 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
    os << "Printing " << fkNNList.size() << " nearest neighbors" << std::endl;
    for (List::const_iterator it = fkNNList.begin(); it != fkNNList.end(); ++it) {
       os << ++count << ": " << it->second << ": " << it->first->GetEvent() << std::endl;
-
+      
       const Event &event = it->first->GetEvent();
       for (UShort_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
          if (min.find(ivar) == min.end()) {
@@ -696,6 +693,6 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
          Log() << kINFO << "(var, min, max) = (" << i << "," << min[i] << ", " << max[i] << ")" << Endl;
       }
    }
-
+   
    os << "----------------------------------------------------------------------" << std::endl;
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index 405f117ec21c6..8f6bbf3d68e40 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$
+// @(#)root/tmva $Id$   
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         *
- *      U. of Victoria, Canada                                                    *
- *      MPI-K Heidelberg, Germany                                                 *
+ *      CERN, Switzerland                                                         * 
+ *      U. of Victoria, Canada                                                    * 
+ *      MPI-K Heidelberg, Germany                                                 * 
  *      LAPP, Annecy, France                                                      *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -27,14 +27,13 @@
  **********************************************************************************/
 
 #include "TMVA/Option.h"
-#include "ThreadLocalStorage.h"
 
 //______________________________________________________________________
-TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
-   : TObject(),
-     fName        ( name ),
-     fNameAllLower( name ),
-     fDescription ( desc ),
+TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
+   : TObject(), 
+     fName        ( name ), 
+     fNameAllLower( name ), 
+     fDescription ( desc ), 
      fIsSet       ( kFALSE )
 {
    // constructor
@@ -42,7 +41,7 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
 }
 
 //______________________________________________________________________
-Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
+Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t ) 
 {
    // set value for option
    fIsSet = kTRUE;
@@ -53,7 +52,7 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
 TMVA::MsgLogger& TMVA::OptionBase::Log()
 {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("Option",kDEBUG);  // message logger
+  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
 #else
   static MsgLogger logger("Option",kDEBUG);  // message logger
 #endif
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 2519d300daea5..875ca43f4b04b 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -50,7 +50,7 @@ const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
 #if __cplusplus > 199711L
-TTHREAD_TLS(TMVA::PDF*) TMVA::PDF::fgThisPDF  = 0;
+thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
 #else
 TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
 #endif
@@ -597,7 +597,7 @@ void TMVA::PDF::ValidatePDF( TH1* originalHist ) const
       if (y > 0) {
          ndof++;
          Double_t d = TMath::Abs( (y - yref*rref)/ey );
-         //         std::cout << "bin: " << bin << "  val: " << x << "  data(err): " << y << "(" << ey << ")   pdf: "
+         //         std::cout << "bin: " << bin << "  val: " << x << "  data(err): " << y << "(" << ey << ")   pdf: " 
          //              << yref << "  dev(chi2): " << d << "(" << chi2 << ")  rref: " << rref << std::endl;
          chi2 += d*d;
          if (d > 1) { nc1++; if (d > 2) { nc2++; if (d > 3) { nc3++; if (d > 6) nc6++; } } }
@@ -723,7 +723,7 @@ Double_t TMVA::PDF::GetValInverse( Double_t y, Bool_t isMonotonouslyIncreasingFu
    Int_t    lowerBin=0,      higherBin=0;
    Double_t lowerBinValue=0, higherBinValue=0;
    FindBinInverse(fPDFHist,lowerBin,higherBin,lowerBinValue,higherBinValue,y,isMonotonouslyIncreasingFunction);
-
+   
    Double_t xValueLowerBin =fPDFHist->GetBinCenter (lowerBin);
    Double_t xValueHigherBin=fPDFHist->GetBinCenter (higherBin);
 
@@ -743,7 +743,7 @@ Double_t TMVA::PDF::GetValInverse( Double_t y, Bool_t isMonotonouslyIncreasingFu
 }
 
 //_____________________________________________________________________
-void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue,
+void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue, 
 				Double_t y, Bool_t isMonotonouslyIncreasingFunction ) const
 {
    // find bin from value on ordinate
@@ -752,7 +752,7 @@ void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& hi
       lowerBin =0;
 
       Int_t bin=higherBin/2;
-
+      
       while (bin>lowerBin && bin<higherBin) {
 	 Double_t binContent=histogram->GetBinContent(bin);
 
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index 7e776158d142e..1099a9caa3ff1 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -151,7 +151,7 @@ void TMVA::TNeuron::CalculateDelta()
 void TMVA::TNeuron::SetInputCalculator(TNeuronInput* calculator)
 {
    // set input calculator
-   if (fInputCalculator != NULL) delete fInputCalculator;
+   if (fInputCalculator != NULL) delete fInputCalculator; 
    fInputCalculator = calculator;
 }
 
@@ -294,7 +294,7 @@ void TMVA::TNeuron::InitSynapseDeltas()
 }
 
 //______________________________________________________________________________
-void TMVA::TNeuron::PrintLinks(TObjArray* links) const
+void TMVA::TNeuron::PrintLinks(TObjArray* links) const 
 {
    // print an array of TSynapses, for debugging
 
@@ -308,7 +308,7 @@ void TMVA::TNeuron::PrintLinks(TObjArray* links) const
    Int_t numLinks = links->GetEntriesFast();
    for  (Int_t i = 0; i < numLinks; i++) {
       synapse = (TSynapse*)links->At(i);
-      Log() << kDEBUG <<
+      Log() << kDEBUG <<  
          "\t\t\tweighta: " << synapse->GetWeight()
            << "\t\tw-value: " << synapse->GetWeightedValue()
            << "\t\tw-delta: " << synapse->GetWeightedDelta()
@@ -333,10 +333,10 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
 }
 
 //______________________________________________________________________________
-TMVA::MsgLogger& TMVA::TNeuron::Log() const
+TMVA::MsgLogger& TMVA::TNeuron::Log() const 
 {
   #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("TNeuron",kDEBUG);    //! message logger, static to save resources
+  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
 #else
   static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
 #endif
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index c38a9f6726fe9..ab03d79f8b173 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -36,8 +36,6 @@
 #include "TMVA/MsgLogger.h"
 #endif
 
-#include "ThreadLocalStorage.h"
-
 static const Int_t fgUNINITIALIZED = -1;
 
 ClassImp(TMVA::TSynapse);
@@ -112,7 +110,7 @@ void TMVA::TSynapse::CalculateDelta()
 TMVA::MsgLogger& TMVA::TSynapse::Log() const
 {
 #if __cplusplus > 199711L
-  static TTHREAD_TLS(MsgLogger) logger("TSynapse");  //! message logger, static to save resources
+  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
 #else
   static MsgLogger logger("TSynapse");               //! message logger, static to save resources
 #endif

From 13811582640c3f4acb718d4841f554820e0f43be Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 21:45:27 +0100
Subject: [PATCH 160/200] Revert "Stress the MT features of the Reader class
 with a new unit test"

Removing the test of a feature which needs attention on Mac OSx

This reverts commit 6273c14202edeffc8492954e6318312899775882.
---
 test/stressTMVA.cxx | 132 +-------------------------------------------
 1 file changed, 3 insertions(+), 129 deletions(-)

diff --git a/test/stressTMVA.cxx b/test/stressTMVA.cxx
index ea488b6f2fcbc..cdb7e397f6ba4 100644
--- a/test/stressTMVA.cxx
+++ b/test/stressTMVA.cxx
@@ -60,7 +60,6 @@ Regression_BDTG2 [4/4]...........................................OK
 *  CPUTIME   =  90.2   *  Root5.27/07   20100929/1318
 ******************************************************************
 */
-#include "TThread.h"
 // including file tmvaut/UnitTest.h
 #ifndef UNITTEST_H
 #define UNITTEST_H
@@ -71,7 +70,6 @@ Regression_BDTG2 [4/4]...........................................OK
 #include <string>
 #include <iostream>
 #include <cassert>
-#include <atomic>
 
 // The following have underscores because
 // they are macros. For consistency,
@@ -106,8 +104,8 @@ namespace UnitTesting
       bool floatCompare(float x1, float x2);
    private:
       std::ostream* osptr;
-      std::atomic<long> nPass;
-      std::atomic<long> nFail;
+      long nPass;
+      long nFail;
       mutable std::string fName;
       std::string fFileName;
       // Disallowed:
@@ -209,7 +207,7 @@ long UnitTest::report() const
 {
    if (osptr)
       {
-         std::string counts(Form(" [%li/%li]", nPass.load(), nPass+nFail));
+         std::string counts(Form(" [%li/%li]", nPass, nPass+nFail));
 
          *osptr << name() << counts;
 
@@ -1294,128 +1292,6 @@ void utReader::run()
    reader[2]->EvaluateMVA( "LD method");
    test_(1>0);
 }
-#ifndef UTREADERMT_H
-#define UTREADERMT_H
-
-// Author: D. Piparo, 2015
-// TMVA unit tests
-//
-// this class acts as interface to several reader applications in MT mode
-
-#include <string>
-#include <iostream>
-#include <cassert>
-#include <vector>
-#include <thread>
-
-#include "TTree.h"
-#include "TString.h"
-
-#include "TMVA/Reader.h"
-#include "TMVA/Types.h"
-
-
-
-namespace UnitTesting
-{
-  class utReaderMT : public UnitTest
-  {
-  public:
-    utReaderMT(const char* theOption="");
-    virtual ~utReaderMT();
-
-    virtual void run();
-
-  protected:
-
-  private:
-     // disallow copy constructor and assignment
-     utReaderMT(const utReaderMT&);
-     utReaderMT& operator=(const utReaderMT&);
-  };
-} // namespace UnitTesting
-#endif //
-
-
-#include <string>
-#include <iostream>
-#include <cassert>
-#include <vector>
-
-#include "TTree.h"
-#include "TString.h"
-
-#include "TMVA/Reader.h"
-#include "TMVA/Types.h"
-
-
-
-using namespace std;
-using namespace UnitTesting;
-using namespace TMVA;
-
-utReaderMT::utReaderMT(const char* /*theOption*/)
-   : UnitTest(string("Reader"))
-{
-
-}
-utReaderMT::~utReaderMT(){ }
-
-void utReaderMT::run()
-{
-   auto runSingleReader = [&] () {
-      float xtest,xtest2;
-      Reader* reader2 = new Reader();
-      Reader* reader3 = new Reader();
-      reader2->AddVariable("test", &xtest);
-      reader2->AddVariable("test2", &xtest2);
-      reader3->AddVariable("test", &xtest);
-
-      delete reader2;
-      delete reader3;
-      test_(1>0);
-      const int nTest=3;
-      int ievt;
-      vector<float> testvar(10);
-      std::vector< TMVA::Reader* > reader(nTest);
-      for (int iTest=0;iTest<nTest;iTest++){
-         reader[iTest] = new TMVA::Reader( "!Color:Silent" );
-         if (iTest==0){
-            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
-            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
-            reader[iTest]->AddSpectator( "ievt" ,&ievt);
-            reader[iTest]->BookMVA( "LD method", "weights/TMVATest_LD.weights.xml") ;
-         }
-         if (iTest==1){
-            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
-            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
-            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
-            reader[iTest]->AddSpectator( "ievt" ,&ievt);
-            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3Var_LD.weights.xml") ;
-         }
-         if (iTest==2){
-            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
-            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
-            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
-            reader[iTest]->AddVariable( "ivar0" ,&testvar[3]);
-            reader[iTest]->AddVariable( "ivar1" ,&testvar[4]);
-            reader[iTest]->AddSpectator( "ievt" ,&ievt);
-            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3VarF2VarI_LD.weights.xml") ;
-         }
-      }
-      reader[0]->EvaluateMVA( "LD method");
-      reader[1]->EvaluateMVA( "LD method");
-      reader[2]->EvaluateMVA( "LD method");
-      test_(1>0);
-   };
-   for (int j=0;j<5;++j){ // challenge non reproducibility repeating the loop
-      vector<thread> threads;
-      for (int i=0;i<10;++i) threads.emplace_back(runSingleReader);
-      for (auto&& t : threads) t.join();
-   }
-
-}
-
 // including file tmvaut/utFactory.h
 #ifndef UTFACTORY_H
 #define UTFACTORY_H
@@ -3007,7 +2883,6 @@ int main(int argc, char **argv)
    TMVA_test.addTest(new utDataSet);
    TMVA_test.addTest(new utFactory);
    TMVA_test.addTest(new utReader);
-   TMVA_test.addTest(new utReaderMT);
 
    addClassificationTests(TMVA_test, full);
    addRegressionTests(TMVA_test, full);
@@ -3015,7 +2890,6 @@ int main(int argc, char **argv)
    addComplexClassificationTests(TMVA_test, full);
 
    // run all
-   TThread::Initialize();
    TMVA_test.run();
 
 #ifdef COUTDEBUG

From e9e54b5f228256b9ed79ee04755a06f5df744aa5 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Thu, 5 Mar 2015 21:46:12 +0100
Subject: [PATCH 161/200] Revert "Make TMVA thread-safe with respect to use of
 Reader"

Some the perfectly sane constructs, such as for example static thread_local,
are not supported on OSx 108,109,1010 versions. Revert the change
until a workaround for this *bug* is implemented in TMVA.

This reverts commit a4e64073cbfd7fa8002befa5e9ba6d16b0cc6513.
---
 tmva/inc/TMVA/BDTEventWrapper.h      |   4 -
 tmva/inc/TMVA/BinaryTree.h           |   3 +-
 tmva/inc/TMVA/Config.h               |  19 +-
 tmva/inc/TMVA/DataSetFactory.h       |   8 +-
 tmva/inc/TMVA/DataSetManager.h       |   4 +-
 tmva/inc/TMVA/DecisionTreeNode.h     |   2 +-
 tmva/inc/TMVA/Interval.h             |   3 +-
 tmva/inc/TMVA/LogInterval.h          |   3 +-
 tmva/inc/TMVA/MethodBase.h           |   5 +-
 tmva/inc/TMVA/MethodCFMlpANN_Utils.h |  12 +-
 tmva/inc/TMVA/MethodPDERS.h          |   4 -
 tmva/inc/TMVA/ModulekNN.h            |   5 +-
 tmva/inc/TMVA/MsgLogger.h            |  20 +-
 tmva/inc/TMVA/Option.h               |  15 +-
 tmva/inc/TMVA/PDF.h                  |   4 -
 tmva/inc/TMVA/TNeuron.h              |   3 +-
 tmva/inc/TMVA/TSynapse.h             |   3 +-
 tmva/inc/TMVA/Tools.h                |   7 -
 tmva/inc/TMVA/Types.h                |   7 -
 tmva/src/BDTEventWrapper.cxx         |   4 -
 tmva/src/BinaryTree.cxx              |  13 +-
 tmva/src/Config.cxx                  |  20 --
 tmva/src/DataSetManager.cxx          |  14 +-
 tmva/src/DecisionTreeNode.cxx        |  48 +++--
 tmva/src/Interval.cxx                |  14 +-
 tmva/src/LogInterval.cxx             |  99 +++++-----
 tmva/src/MethodANNBase.cxx           |  13 +-
 tmva/src/MethodBase.cxx              |   8 -
 tmva/src/MethodCFMlpANN_Utils.cxx    |  12 +-
 tmva/src/MethodMLP.cxx               |   5 -
 tmva/src/MethodPDERS.cxx             |   8 -
 tmva/src/MethodTMlpANN.cxx           |  11 +-
 tmva/src/ModulekNN.cxx               |   8 -
 tmva/src/MsgLogger.cxx               |  91 ++++-----
 tmva/src/Option.cxx                  |  12 +-
 tmva/src/PDF.cxx                     |   4 -
 tmva/src/TNeuron.cxx                 |  14 +-
 tmva/src/TSynapse.cxx                |  26 +--
 tmva/src/Tools.cxx                   | 273 ++++++++++++---------------
 tmva/src/Types.cxx                   |  69 ++-----
 40 files changed, 325 insertions(+), 572 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index cc3d0ae17814e..8a2ec791bcf72 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -67,11 +67,7 @@ namespace TMVA {
     
    private:
 
-#if __cplusplus > 199711L
-      static thread_local Int_t fVarIndex;  // index of the variable to sort on
-#else
       static Int_t fVarIndex;  // index of the variable to sort on
-#endif
       const Event* fEvent;     // pointer to the event
     
       Double_t     fBkgWeight; // cumulative background weight for splitting
diff --git a/tmva/inc/TMVA/BinaryTree.h b/tmva/inc/TMVA/BinaryTree.h
index d76ed44a1214a..81fe591789c4c 100644
--- a/tmva/inc/TMVA/BinaryTree.h
+++ b/tmva/inc/TMVA/BinaryTree.h
@@ -123,7 +123,8 @@ namespace TMVA {
       UInt_t     fNNodes;           // total number of nodes in the tree (counted)
       UInt_t     fDepth;            // maximal depth in tree reached
 
-      MsgLogger& Log() const;
+      static MsgLogger* fgLogger;   // message logger, static to save resources    
+      MsgLogger& Log() const { return *fgLogger; }
 
       ClassDef(BinaryTree,0) // Base class for BinarySearch and Decision Trees
    };  
diff --git a/tmva/inc/TMVA/Config.h b/tmva/inc/TMVA/Config.h
index d8d56fa33bc90..08e55ff89e47d 100644
--- a/tmva/inc/TMVA/Config.h
+++ b/tmva/inc/TMVA/Config.h
@@ -36,9 +36,7 @@
 // Singleton class for global configuration settings used by TMVA       //
 //                                                                      //
 //////////////////////////////////////////////////////////////////////////
-#if __cplusplus > 199711L
-#include <atomic>
-#endif
+
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
 #endif
@@ -105,27 +103,16 @@ namespace TMVA {
 
       // private constructor
       Config();
-      Config( const Config& );
-      Config& operator=( const Config&);
       virtual ~Config();
-#if __cplusplus > 199711L
-      static std::atomic<Config*> fgConfigPtr;
-#else
       static Config* fgConfigPtr;
-#endif                  
+                  
    private:
 
-#if __cplusplus > 199711L
-      std::atomic<Bool_t> fUseColoredConsole;     // coloured standard output
-      std::atomic<Bool_t> fSilent;                // no output at all
-      std::atomic<Bool_t> fWriteOptionsReference; // if set true: Configurable objects write file with option reference
-      std::atomic<Bool_t> fDrawProgressBar;       // draw progress bar to indicate training evolution
-#else
       Bool_t fUseColoredConsole;     // coloured standard output
       Bool_t fSilent;                // no output at all
       Bool_t fWriteOptionsReference; // if set true: Configurable objects write file with option reference
       Bool_t fDrawProgressBar;       // draw progress bar to indicate training evolution
-#endif
+
       mutable MsgLogger* fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }
          
diff --git a/tmva/inc/TMVA/DataSetFactory.h b/tmva/inc/TMVA/DataSetFactory.h
index de1d85fbc5496..bfd54f04830a1 100644
--- a/tmva/inc/TMVA/DataSetFactory.h
+++ b/tmva/inc/TMVA/DataSetFactory.h
@@ -254,8 +254,6 @@ namespace TMVA {
 
       DataSet* CreateDataSet( DataSetInfo &, DataInputHandler& );
 
-      static DataSetFactory* NewInstance() { return new DataSetFactory(); }
-      static void destroyNewInstance(DataSetFactory* iOther) { delete iOther;}
    protected:
 
       ~DataSetFactory();
@@ -316,8 +314,8 @@ namespace TMVA {
       Bool_t                     fScaleWithPreselEff; //! how to deal with requested #events in connection with preselection cuts 
 
       // the event
-      TTree*                     fCurrentTree;       //! the tree, events are currently read from
-      UInt_t                     fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
+      mutable TTree*             fCurrentTree;       //! the tree, events are currently read from
+      mutable UInt_t             fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
 
       // the formulas for reading the original tree
       std::vector<TTreeFormula*> fInputFormulas;   //! input variables
@@ -326,7 +324,7 @@ namespace TMVA {
       std::vector<TTreeFormula*> fWeightFormula;   //! weights
       std::vector<TTreeFormula*> fSpectatorFormulas; //! spectators
 
-      MsgLogger*                 fLogger;          //! message logger
+      mutable MsgLogger*         fLogger;          //! message logger
       MsgLogger& Log() const { return *fLogger; }
    };
 }
diff --git a/tmva/inc/TMVA/DataSetManager.h b/tmva/inc/TMVA/DataSetManager.h
index 6bef1c6d579b1..864a5e5ab161b 100644
--- a/tmva/inc/TMVA/DataSetManager.h
+++ b/tmva/inc/TMVA/DataSetManager.h
@@ -84,14 +84,14 @@ namespace TMVA {
 /*       DataSetManager(); */ // DSMTEST
 /*       DataSetManager( DataInputHandler& dataInput ); */ // DSMTEST
 
-      TMVA::DataSetFactory* fDatasetFactory;
+// //      TMVA::DataSetFactory* fDatasetFactory; // DSMTEST
 
       // access to input data
       DataInputHandler& DataInput() { return fDataInput; }
 
       DataInputHandler&          fDataInput;             //! source of input data
       TList                      fDataSetInfoCollection; //! all registered dataset definitions
-      MsgLogger*                 fLogger;   // message logger
+      mutable MsgLogger*         fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }    
    };
 }
diff --git a/tmva/inc/TMVA/DecisionTreeNode.h b/tmva/inc/TMVA/DecisionTreeNode.h
index 0b590ef79f41e..8e1935a42fe58 100644
--- a/tmva/inc/TMVA/DecisionTreeNode.h
+++ b/tmva/inc/TMVA/DecisionTreeNode.h
@@ -355,7 +355,7 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger& Log();
+      static MsgLogger* fgLogger;    // static because there is a huge number of nodes...
 
       std::vector<Double_t>       fFisherCoeff;    // the fisher coeff (offset at the last element)
 
diff --git a/tmva/inc/TMVA/Interval.h b/tmva/inc/TMVA/Interval.h
index b1afa1bf29a18..c057bb883dc6e 100644
--- a/tmva/inc/TMVA/Interval.h
+++ b/tmva/inc/TMVA/Interval.h
@@ -90,7 +90,8 @@ namespace TMVA {
       Int_t    fNbins;        // when >0 : number of bins (discrete interval); when ==0 continuous interval
 
    private:
-      MsgLogger& Log() const;          
+      static MsgLogger* fgLogger;   // message logger
+      MsgLogger& Log() const { return *fgLogger; }          
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/LogInterval.h b/tmva/inc/TMVA/LogInterval.h
index 687705a8e6b47..f251e81cd1c67 100644
--- a/tmva/inc/TMVA/LogInterval.h
+++ b/tmva/inc/TMVA/LogInterval.h
@@ -105,7 +105,8 @@ namespace TMVA {
       void SetMax( Double_t m ) { fMax = m; }
       void SetMin( Double_t m ) { fMin = m; }
 
-      MsgLogger& Log() const;
+      static MsgLogger* fgLogger;   // message logger
+      MsgLogger& Log() const { return *fgLogger; }          
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 8a1c2d28610b9..02bffb8ac9df5 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -629,11 +629,8 @@ namespace TMVA {
    private:
 
       // this carrier
-#if __cplusplus > 199711L
-      static thread_local MethodBase* fgThisBase;         // this pointer
-#else
       static MethodBase* fgThisBase;         // this pointer
-#endif
+
 
       // ===== depreciated options, kept for backward compatibility  =====
    private:
diff --git a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
index d0f9ba4f08578..3d1fa1a1ae62c 100644
--- a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
+++ b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
@@ -99,12 +99,12 @@ namespace TMVA {
 
    protected:
 
-      static Int_t             fg_100;          // constant
-      static Int_t             fg_0;            // constant
-      static const Int_t       fg_max_nVar_;    // static maximum number of input variables
-      static const Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
-      static Int_t             fg_999;          // constant
-      static const char* const fg_MethodName;   // method name for print
+      static Int_t       fg_100;          // constant
+      static Int_t       fg_0;            // constant
+      static Int_t       fg_max_nVar_;    // static maximum number of input variables
+      static Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
+      static Int_t       fg_999;          // constant
+      static const char* fg_MethodName;   // method name for print
 
       Double_t W_ref(const Double_t wNN[], Int_t a_1, Int_t a_2, Int_t a_3) const {
          return wNN [(a_3*max_nNodes_ + a_2)*max_nLayers_ + a_1 - 187];
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index 9d1a4f7bd1e61..3ae5d497451eb 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -220,11 +220,7 @@ namespace TMVA {
                                  Float_t sumW2S, Float_t sumW2B ) const;
 
       // this carrier
-#if __cplusplus > 199711L
-      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
-#else
       static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
-#endif
       void UpdateThis();
 
       void Init( void );
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index 569ee5e80b46c..1851491e408f5 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -148,11 +148,8 @@ namespace TMVA {
 
       private:
 
-#if __cplusplus > 199711L
-         static thread_local TRandom3 fgRndm;
-#else
          static TRandom3 fgRndm;
-#endif
+
          UInt_t fDimn;
 
          Node<Event> *fTree;
diff --git a/tmva/inc/TMVA/MsgLogger.h b/tmva/inc/TMVA/MsgLogger.h
index 44505dd03d50f..d93e3f6c00469 100644
--- a/tmva/inc/TMVA/MsgLogger.h
+++ b/tmva/inc/TMVA/MsgLogger.h
@@ -43,9 +43,6 @@
 #include <sstream>
 #include <iostream>
 #include <map>
-#if __cplusplus > 199711L
-#include <atomic>
-#endif
 
 // ROOT include(s)
 #ifndef ROOT_TObject
@@ -78,7 +75,7 @@ namespace TMVA {
       std::string GetPrintedSource()   const;
       std::string GetFormattedSource() const;
 
-      static UInt_t GetMaxSourceSize()                    { return (const UInt_t)fgMaxSourceSize; }
+      static UInt_t GetMaxSourceSize()                    { return (UInt_t)fgMaxSourceSize; }
 
       // Needed for copying
       MsgLogger& operator= ( const MsgLogger& parent );
@@ -116,20 +113,13 @@ namespace TMVA {
       static const std::string fgPrefix;          // the prefix of the source name
       static const std::string fgSuffix;          // suffix following source name
       EMsgType                 fActiveType;       // active type
-      static const UInt_t      fgMaxSourceSize;   // maximum length of source name
-#if __cplusplus > 199711L
-      static std::atomic<Bool_t> fgOutputSupressed; // disable the output globaly (used by generic booster)
-      static std::atomic<Bool_t> fgInhibitOutput;   // flag to suppress all output
-
-      static std::atomic<const std::map<EMsgType, std::string>*> fgTypeMap;   // matches output types with strings
-      static std::atomic<const std::map<EMsgType, std::string>*> fgColorMap;  // matches output types with terminal colors
-#else
+      static UInt_t            fgMaxSourceSize;   // maximum length of source name
       static Bool_t            fgOutputSupressed; // disable the output globaly (used by generic booster)
       static Bool_t            fgInhibitOutput;   // flag to suppress all output
+      static Int_t             fgInstanceCounter; // counts open MsgLogger instances
 
-      static const std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
-      static const std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
-#endif
+      static std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
+      static std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
       EMsgType                                fMinType;    // minimum type for output
 
       ClassDef(MsgLogger,0) // Ostringstream derivative to redirect and format logging output
diff --git a/tmva/inc/TMVA/Option.h b/tmva/inc/TMVA/Option.h
index 4a0d80e8b41eb..458b3acb8ac1a 100644
--- a/tmva/inc/TMVA/Option.h
+++ b/tmva/inc/TMVA/Option.h
@@ -93,7 +93,8 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger& Log();
+      static MsgLogger* fgLogger;  // message logger
+
    };
       
    // ---------------------------------------------------------------------------
@@ -248,16 +249,16 @@ namespace TMVA {
    inline void TMVA::Option<Bool_t>::AddPreDefVal( const Bool_t& ) 
    {
       // template specialization for Bool_t 
-      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
-	    << Endl;
+      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
+                << Endl;
    }
 
    template<>
    inline void TMVA::Option<Float_t>::AddPreDefVal( const Float_t& ) 
    {
       // template specialization for Float_t 
-      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
-	    << Endl;
+      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
+                << Endl;
    }
 
    template<class T>
@@ -357,8 +358,8 @@ namespace TMVA {
          this->Value() = false;
       }
       else {
-         Log() << kFATAL << "<SetValueLocal> value \'" << val 
-	       << "\' can not be interpreted as boolean" << Endl;
+         *fgLogger << kFATAL << "<SetValueLocal> value \'" << val 
+                   << "\' can not be interpreted as boolean" << Endl;
       }
    }
 }
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index e6387c99b496d..9962198ec37d8 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -205,11 +205,7 @@ namespace TMVA {
       MsgLogger&               Log() const { return *fLogger; }    
 
       // static pointer to this object
-#if __cplusplus > 199711L
-      static thread_local PDF* fgThisPDF;             // this PDF pointer 
-#else
       static PDF*              fgThisPDF;             // this PDF pointer 
-#endif
       static PDF*              ThisPDF( void ); 
 
       // external auxiliary functions 
diff --git a/tmva/inc/TMVA/TNeuron.h b/tmva/inc/TMVA/TNeuron.h
index eff915cfbc569..101b1413319e8 100644
--- a/tmva/inc/TMVA/TNeuron.h
+++ b/tmva/inc/TMVA/TNeuron.h
@@ -163,7 +163,8 @@ namespace TMVA {
       TActivation*  fActivation;              // activation equation
       TNeuronInput* fInputCalculator;         // input calculator
 
-      MsgLogger& Log() const;
+      static MsgLogger* fgLogger;                     //! message logger, static to save resources
+      MsgLogger& Log() const { return *fgLogger; }                       
 
       ClassDef(TNeuron,0) // Neuron class used by MethodANNBase derivative ANNs
    };
diff --git a/tmva/inc/TMVA/TSynapse.h b/tmva/inc/TMVA/TSynapse.h
index d8bf444c30d7d..66107687d25c5 100644
--- a/tmva/inc/TMVA/TSynapse.h
+++ b/tmva/inc/TMVA/TSynapse.h
@@ -102,7 +102,8 @@ namespace TMVA {
       TNeuron* fPreNeuron;         // pointer to pre-neuron
       TNeuron* fPostNeuron;        // pointer to post-neuron
 
-      MsgLogger& Log() const;
+      static MsgLogger* fgLogger;                     //! message logger, static to save resources
+      MsgLogger& Log() const { return *fgLogger; }                       
 
       ClassDef(TSynapse,0) // Synapse class used by MethodANNBase and derivatives
    };
diff --git a/tmva/inc/TMVA/Tools.h b/tmva/inc/TMVA/Tools.h
index cb6d51722a280..011196cd3e0eb 100644
--- a/tmva/inc/TMVA/Tools.h
+++ b/tmva/inc/TMVA/Tools.h
@@ -41,9 +41,6 @@
 #include <sstream>
 #include <iostream>
 #include <iomanip>
-#if __cplusplus > 199711L
-#include <atomic>
-#endif
 
 #ifndef ROOT_TXMLEngine
 #include "TXMLEngine.h"
@@ -241,11 +238,7 @@ namespace TMVA {
       const TString fRegexp;
       mutable MsgLogger*    fLogger;
       MsgLogger& Log() const { return *fLogger; }
-#if __cplusplus > 199711L
-      static std::atomic<Tools*> fgTools;
-#else
       static Tools* fgTools;
-#endif
 
       // xml tools
 
diff --git a/tmva/inc/TMVA/Types.h b/tmva/inc/TMVA/Types.h
index e245cf0c2abf4..cb5f45ce67039 100644
--- a/tmva/inc/TMVA/Types.h
+++ b/tmva/inc/TMVA/Types.h
@@ -38,9 +38,6 @@
 //////////////////////////////////////////////////////////////////////////
 
 #include <map>
-#if __cplusplus > 199711L
-#include <atomic>
-#endif
 
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
@@ -157,11 +154,7 @@ namespace TMVA {
    private:
 
       Types();
-#if __cplusplus > 199711L
-      static std::atomic<Types*> fgTypesPtr;
-#else
       static Types* fgTypesPtr;
-#endif
 
    private:
 
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index 0820339c01c41..c7429e0bcb13b 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -26,11 +26,7 @@
 
 using namespace TMVA;
 
-#if __cplusplus > 199711L
-thread_local Int_t BDTEventWrapper::fVarIndex = 0;
-#else
 Int_t BDTEventWrapper::fVarIndex = 0;
-#endif
 
 BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
    // constuctor
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index dca177c92dbd2..4b3b7d2d5e27b 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -46,6 +46,8 @@
 
 ClassImp(TMVA::BinaryTree)
 
+TMVA::MsgLogger* TMVA::BinaryTree::fgLogger = 0;
+
 //_______________________________________________________________________
 TMVA::BinaryTree::BinaryTree( void )
    : fRoot  ( NULL ),
@@ -53,6 +55,7 @@ TMVA::BinaryTree::BinaryTree( void )
      fDepth ( 0 )
 {
    // constructor for a yet "empty" tree. Needs to be filled afterwards
+   if (!fgLogger) fgLogger =  new MsgLogger("BinaryTree");
 }
 
 //_______________________________________________________________________
@@ -218,13 +221,3 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 
    return;
 }
-
-//_______________________________________________________________________
-TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("BinaryTree");
-#else
-  static MsgLogger logger("BinaryTree");
-#endif
-  return logger;
-}
diff --git a/tmva/src/Config.cxx b/tmva/src/Config.cxx
index 6dd287a9c51d1..de124def90151 100644
--- a/tmva/src/Config.cxx
+++ b/tmva/src/Config.cxx
@@ -31,11 +31,7 @@
 
 ClassImp(TMVA::Config)
 
-#if __cplusplus > 199711L
-std::atomic<TMVA::Config*> TMVA::Config::fgConfigPtr{ 0 };
-#else
 TMVA::Config* TMVA::Config::fgConfigPtr = 0;
-#endif
 
 TMVA::Config& TMVA::gConfig() { return TMVA::Config::Instance(); }
 
@@ -75,29 +71,13 @@ TMVA::Config::~Config()
 void TMVA::Config::DestroyInstance()
 {
    // static function: destroy TMVA instance
-#if __cplusplus > 199711L
-  delete fgConfigPtr.exchange(0);
-#else
    if (fgConfigPtr != 0) { delete fgConfigPtr; fgConfigPtr = 0;}
-#endif
 }
 
 //_______________________________________________________________________
 TMVA::Config& TMVA::Config::Instance()
 {
    // static function: returns  TMVA instance
-#if __cplusplus > 199711L
-  if(!fgConfigPtr) {
-    TMVA::Config* tmp = new Config();
-    TMVA::Config* expected = 0;
-    if(! fgConfigPtr.compare_exchange_strong(expected,tmp) ) {
-      //another thread beat us to the switch
-      delete tmp;
-    }
-  }
-  return *fgConfigPtr;
-#else
    return fgConfigPtr ? *fgConfigPtr :*(fgConfigPtr = new Config());
-#endif
 }
 
diff --git a/tmva/src/DataSetManager.cxx b/tmva/src/DataSetManager.cxx
index 9ed04df3ee4d0..63c81e0ea142d 100644
--- a/tmva/src/DataSetManager.cxx
+++ b/tmva/src/DataSetManager.cxx
@@ -52,8 +52,7 @@ using std::endl;
 
 //_______________________________________________________________________
 TMVA::DataSetManager::DataSetManager( DataInputHandler& dataInput )
-   : fDatasetFactory(0),
-     fDataInput(dataInput),
+   : fDataInput(dataInput),
      fDataSetInfoCollection(),
      fLogger( new MsgLogger("DataSetManager", kINFO) )
 {
@@ -66,8 +65,8 @@ TMVA::DataSetManager::~DataSetManager()
    // destructor
 //   fDataSetInfoCollection.SetOwner(); // DSMTEST --> created a segfault because the DataSetInfo-objects got deleted twice
 
-   DataSetFactory::destroyNewInstance(fDatasetFactory);
-
+   TMVA::DataSetFactory::destroyInstance();
+   
    delete fLogger;
 }
 
@@ -79,19 +78,18 @@ TMVA::DataSet* TMVA::DataSetManager::CreateDataSet( const TString& dsiName )
    if (!dsi) Log() << kFATAL << "DataSetInfo object '" << dsiName << "' not found" << Endl;
 
    // factory to create dataset from datasetinfo and datainput
-   if(!fDatasetFactory) { fDatasetFactory = DataSetFactory::NewInstance(); }
-   return fDatasetFactory->CreateDataSet( *dsi, fDataInput );
+   return TMVA::DataSetFactory::Instance().CreateDataSet( *dsi, fDataInput );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName)
+TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName) 
 {
    // returns datasetinfo object for given name
    return (DataSetInfo*)fDataSetInfoCollection.FindObject( dsiName );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi)
+TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi) 
 {
    // stores a copy of the dataset info object
 
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index 37425a83b94f7..235ebeb396948 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -50,6 +50,7 @@ using std::string;
 
 ClassImp(TMVA::DecisionTreeNode)
 
+TMVA::MsgLogger* TMVA::DecisionTreeNode::fgLogger = 0;
 bool     TMVA::DecisionTreeNode::fgIsTraining = false;
 UInt_t   TMVA::DecisionTreeNode::fgTmva_Version_Code = 0;
 //_______________________________________________________________________
@@ -65,6 +66,8 @@ TMVA::DecisionTreeNode::DecisionTreeNode()
      fIsTerminalNode( kFALSE )
 {
    // constructor of an essentially "empty" node floating in space
+   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
+
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -88,6 +91,8 @@ TMVA::DecisionTreeNode::DecisionTreeNode(TMVA::Node* p, char pos)
      fIsTerminalNode( kFALSE )
 {
    // constructor of a daughter node as a daughter of 'p'
+   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
+
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -113,6 +118,8 @@ TMVA::DecisionTreeNode::DecisionTreeNode(const TMVA::DecisionTreeNode &n,
 {
    // copy constructor of a node. It will result in an explicit copy of
    // the node and recursively all it's daughters
+   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
+
    this->SetParent( parent );
    if (n.GetLeft() == 0 ) this->SetLeft(NULL);
    else this->SetLeft( new DecisionTreeNode( *((DecisionTreeNode*)(n.GetLeft())),this));
@@ -144,11 +151,11 @@ Bool_t TMVA::DecisionTreeNode::GoesRight(const TMVA::Event & e) const
    Bool_t result;
    // first check if the fisher criterium is used or ordinary cuts:
    if (GetNFisherCoeff() == 0){
-
+      
       result = (e.GetValue(this->GetSelector()) >= this->GetCutValue() );
 
    }else{
-
+      
       Double_t fisher = this->GetFisherCoeff(fFisherCoeff.size()-1); // the offset
       for (UInt_t ivar=0; ivar<fFisherCoeff.size()-1; ivar++)
          fisher += this->GetFisherCoeff(ivar)*(e.GetValue(ivar));
@@ -180,8 +187,8 @@ void TMVA::DecisionTreeNode::SetPurity( void )
       fPurity = this->GetNSigEvents() / ( this->GetNSigEvents() + this->GetNBkgEvents());
    }
    else {
-      Log() << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
-      this->Print(Log());
+      *fgLogger << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
+      this->Print(*fgLogger);
       fPurity = 0.5;
    }
    return;
@@ -198,7 +205,7 @@ void TMVA::DecisionTreeNode::Print(std::ostream& os) const
       << "NCoef: "  << this->GetNFisherCoeff();
    for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) { os << "fC"<<i<<": " << this->GetFisherCoeff(i);}
    os << " ivar: "  << this->GetSelector()
-      << " cut: "   << this->GetCutValue()
+      << " cut: "   << this->GetCutValue() 
       << " cType: " << this->GetCutType()
       << " s: "     << this->GetNSigEvents()
       << " b: "     << this->GetNBkgEvents()
@@ -383,7 +390,7 @@ void TMVA::DecisionTreeNode::PrintRecPrune( std::ostream& os ) const {
 void TMVA::DecisionTreeNode::SetCC(Double_t cc)
 {
    if (fTrainInfo) fTrainInfo->fCC = cc;
-   else Log() << kFATAL << "call to SetCC without trainingInfo" << Endl;
+   else *fgLogger << kFATAL << "call to SetCC without trainingInfo" << Endl;
 }
 
 //_______________________________________________________________________
@@ -391,8 +398,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMin(UInt_t ivar) const {
    // return the minimum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMin[ivar];
-   else Log() << kFATAL << "You asked for Min of the event sample in node for variable "
-              << ivar << " that is out of range" << Endl;
+   else *fgLogger << kFATAL << "You asked for Min of the event sample in node for variable "
+                  << ivar << " that is out of range" << Endl;
    return -9999;
 }
 
@@ -401,8 +408,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMax(UInt_t ivar) const {
    // return the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMax[ivar];
-   else Log() << kFATAL << "You asked for Max of the event sample in node for variable "
-              << ivar << " that is out of range" << Endl;
+   else *fgLogger << kFATAL << "You asked for Max of the event sample in node for variable "
+                  << ivar << " that is out of range" << Endl;
    return 9999;
 }
 
@@ -421,7 +428,7 @@ void TMVA::DecisionTreeNode::SetSampleMax(UInt_t ivar, Float_t xmax){
    // set the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if( ! fTrainInfo ) return;
-   if ( ivar >= fTrainInfo->fSampleMax.size() )
+   if ( ivar >= fTrainInfo->fSampleMax.size() ) 
       fTrainInfo->fSampleMax.resize(ivar+1);
    fTrainInfo->fSampleMax[ivar]=xmax;
 }
@@ -445,10 +452,10 @@ void TMVA::DecisionTreeNode::ReadAttributes(void* node, UInt_t /* tmva_Version_C
    }
    gTools().ReadAttr(node, "IVar",  fSelector               );
    gTools().ReadAttr(node, "Cut",   fCutValue               );
-   gTools().ReadAttr(node, "cType", fCutType                );
+   gTools().ReadAttr(node, "cType", fCutType                );               
    if (gTools().HasAttr(node,"res")) gTools().ReadAttr(node, "res",   fResponse);
    if (gTools().HasAttr(node,"rms")) gTools().ReadAttr(node, "rms",   fRMS);
-   //   else {
+   //   else { 
    if( gTools().HasAttr(node, "purity") ) {
       gTools().ReadAttr(node, "purity",fPurity );
    } else {
@@ -466,7 +473,7 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 {
    // add attribute to xml
    gTools().AddAttr(node, "NCoef", GetNFisherCoeff());
-   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++)
+   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) 
       gTools().AddAttr(node, Form("fC%d",i),  this->GetFisherCoeff(i));
 
    gTools().AddAttr(node, "IVar",  GetSelector());
@@ -487,8 +494,8 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 void  TMVA::DecisionTreeNode::SetFisherCoeff(Int_t ivar, Double_t coeff)
 {
    // set fisher coefficients
-   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ;
-   fFisherCoeff[ivar]=coeff;
+   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ; 
+   fFisherCoeff[ivar]=coeff;      
 }
 
 //_______________________________________________________________________
@@ -506,12 +513,3 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
    // and somehow I guess someone programmed it such that we need this in
    // this tree too, although we don't..)
 }
-//_______________________________________________________________________
-TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
-#else
-  static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
-#endif
-  return logger;
-}
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index d89b023679f49..e37ac0ac02c5f 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -75,12 +75,16 @@ End_Html */
 
 ClassImp(TMVA::Interval)
 
+TMVA::MsgLogger* TMVA::Interval::fgLogger = 0;
+
 //_______________________________________________________________________
 TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
    fMin(min),
    fMax(max),
    fNbins(nbins)
 {
+   if (!fgLogger) fgLogger = new MsgLogger("Interval");
+
    // defines minimum and maximum of an interval
    // when nbins > 0, interval describes a discrete distribution (equally distributed in the interval)
    // when nbins == 0, interval describes a continous interval
@@ -101,6 +105,7 @@ TMVA::Interval::Interval( const Interval& other ) :
    fMax  ( other.fMax ),
    fNbins( other.fNbins )
 {
+   if (!fgLogger) fgLogger = new MsgLogger("Interval");
 }
 
 //_______________________________________________________________________
@@ -163,12 +168,3 @@ void TMVA::Interval::Print(std::ostream &os) const
       os << "| " << GetElement(i)<<" |" ;
    }  
 }
-
-TMVA::MsgLogger& TMVA::Interval::Log() const {
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Interval");   // message logger
-#else
-  static MsgLogger logger("Interval");   // message logger
-#endif
-  return logger;
-}
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 922ae5ace5991..6bdbb1c0c20c3 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -13,8 +13,8 @@
  *      Helge Voss <helge.voss@cern.ch>  - MPI-K Heidelberg, Germany              *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         *
- *      MPI-K Heidelberg, Germany                                                 *
+ *      CERN, Switzerland                                                         * 
+ *      MPI-K Heidelberg, Germany                                                 * 
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -35,39 +35,39 @@
    </ul>
 </ul>
 <pre>
-    Example:
- LogInterval(1,10000,5)
-     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!
-     i=1 --> 10                    StepSize(ibin=1) = 9
-     i=2 --> 100                   StepSize(ibin=2) = 99
-     i=3 --> 1000                  StepSize(ibin=3) = 999
-     i=4 --> 10000                 StepSize(ibin=4) = 9999
-
- LogInterval(1,1000,11)
-    i=0 --> 1
-    i=1 --> 1.99526
-    i=2 --> 3.98107
-    i=3 --> 7.94328
-    i=4 --> 15.8489
-    i=5 --> 31.6228
-    i=6 --> 63.0957
-    i=7 --> 125.893
-    i=8 --> 251.189
-    i=9 --> 501.187
-    i=10 --> 1000
-
- LogInterval(1,1024,11)
-    i=0 --> 1
-    i=1 --> 2
-    i=2 --> 4
-    i=3 --> 8
-    i=4 --> 16
-    i=5 --> 32
-    i=6 --> 64
-    i=7 --> 128
-    i=8 --> 256
-    i=9 --> 512
-    i=10 --> 1024
+    Example:             
+ LogInterval(1,10000,5)                                          
+     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!  
+     i=1 --> 10                    StepSize(ibin=1) = 9              
+     i=2 --> 100                   StepSize(ibin=2) = 99                         
+     i=3 --> 1000                  StepSize(ibin=3) = 999                     
+     i=4 --> 10000                 StepSize(ibin=4) = 9999                 
+                                                
+ LogInterval(1,1000,11)                     
+    i=0 --> 1                           
+    i=1 --> 1.99526                 
+    i=2 --> 3.98107             
+    i=3 --> 7.94328         
+    i=4 --> 15.8489      
+    i=5 --> 31.6228      
+    i=6 --> 63.0957      
+    i=7 --> 125.893      
+    i=8 --> 251.189      
+    i=9 --> 501.187      
+    i=10 --> 1000        
+                         
+ LogInterval(1,1024,11)  
+    i=0 --> 1            
+    i=1 --> 2            
+    i=2 --> 4            
+    i=3 --> 8            
+    i=4 --> 16           
+    i=5 --> 32           
+    i=6 --> 64           
+    i=7 --> 128          
+    i=8 --> 256          
+    i=9 --> 512          
+    i=10 --> 1024        
 
 
 </pre>
@@ -81,16 +81,19 @@ End_Html */
 
 ClassImp(TMVA::LogInterval)
 
+TMVA::MsgLogger* TMVA::LogInterval::fgLogger = 0;
 //_______________________________________________________________________
 TMVA::LogInterval::LogInterval( Double_t min, Double_t max, Int_t nbins ) :
 TMVA::Interval(min,max,nbins)
 {
+   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
    if (min<=0) Log() << kFATAL << "logarithmic intervals have to have Min>0 !!" << Endl;
 }
 
 TMVA::LogInterval::LogInterval( const LogInterval& other ) :
    TMVA::Interval(other)
 {
+   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
 }
 
 //_______________________________________________________________________
@@ -102,9 +105,9 @@ TMVA::LogInterval::~LogInterval()
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval.
+   // calculates the value of the "number" bin in a discrete interval. 
    // Parameters:
-   //        Double_t position
+   //        Double_t position 
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
@@ -120,7 +123,7 @@ Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete LogInterval"
+   // retuns the step size between the numbers of a "discrete LogInterval" 
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
    }
@@ -138,20 +141,12 @@ Double_t TMVA::LogInterval::GetRndm( TRandom3& rnd )  const
    return TMath::Exp(rnd.Rndm()*(TMath::Log(fMax/fMin) - TMath::Log(fMin)) + TMath::Log(fMin));
 }
 
-Double_t TMVA::LogInterval::GetWidth() const
-{
-   return fMax - fMin;
+Double_t TMVA::LogInterval::GetWidth() const 
+{ 
+   return fMax - fMin; 
 }
-Double_t TMVA::LogInterval::GetMean()  const
-{
-   return (fMax + fMin)/2;
+Double_t TMVA::LogInterval::GetMean()  const 
+{ 
+   return (fMax + fMin)/2; 
 }
 
-TMVA::MsgLogger& TMVA::LogInterval::Log() const {
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("LogInterval");   // message logger
-#else
-  static MsgLogger logger("LogInterval");   // message logger
-#endif
-  return logger;
-}
diff --git a/tmva/src/MethodANNBase.cxx b/tmva/src/MethodANNBase.cxx
index ede12dc7d443b..0cc220816b585 100644
--- a/tmva/src/MethodANNBase.cxx
+++ b/tmva/src/MethodANNBase.cxx
@@ -40,9 +40,6 @@
 #include <vector>
 #include <cstdlib>
 #include <stdexcept>
-#if __cplusplus > 199711L
-#include <atomic>
-#endif
 
 #include "TString.h"
 #include "TTree.h"
@@ -983,17 +980,13 @@ void TMVA::MethodANNBase::WriteMonitoringHistosToFile() const
    CreateWeightMonitoringHists( "weights_hist" );
 
    // now save all the epoch-wise monitoring information
-#if __cplusplus > 199711L
-   static std::atomic<int> epochMonitoringDirectoryNumber{0};
-#else
    static int epochMonitoringDirectoryNumber = 0;
-#endif
-   int epochVal = epochMonitoringDirectoryNumber++;
    TDirectory* epochdir = NULL;
-   if( epochVal == 0 )
+   if( epochMonitoringDirectoryNumber == 0 )
       epochdir = BaseDir()->mkdir( "EpochMonitoring" );
    else
-      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochVal) );
+      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochMonitoringDirectoryNumber) );
+   ++epochMonitoringDirectoryNumber;
 
    epochdir->cd();
    for (std::vector<TH1*>::const_iterator it = fEpochMonHistS.begin(); it != fEpochMonHistS.end(); it++) {
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index 71b7af726cd1a..99589d559eea2 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -2171,11 +2171,7 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmin = effhist->GetXaxis()->GetXmin();
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
-#if __cplusplus > 199711L
-   static thread_local Double_t nevtS;
-#else
    static Double_t nevtS;
-#endif
 
    // first round ? --> create histograms
    if (results->DoesExist("MVA_EFF_S")==0) {
@@ -3089,11 +3085,7 @@ void TMVA::MethodBase::PrintHelpMessage() const
 
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
-#if __cplusplus > 199711L
-thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
-#else
 TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
-#endif
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::IGetEffForRoot( Double_t theCut )
diff --git a/tmva/src/MethodCFMlpANN_Utils.cxx b/tmva/src/MethodCFMlpANN_Utils.cxx
index ecbdafb7b5eb4..c35521acc8055 100644
--- a/tmva/src/MethodCFMlpANN_Utils.cxx
+++ b/tmva/src/MethodCFMlpANN_Utils.cxx
@@ -72,12 +72,12 @@ using std::endl;
 
 ClassImp(TMVA::MethodCFMlpANN_Utils)
    
-Int_t             TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
-Int_t             TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
-const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
-const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
-Int_t             TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
-const char* const TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
+Int_t       TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
+Int_t       TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
+Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
+Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
+Int_t       TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
+const char* TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
 
 TMVA::MethodCFMlpANN_Utils::MethodCFMlpANN_Utils()
 {
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 9e4f58143e1b5..18797d2025370 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -1583,13 +1583,8 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
    ((MethodMLP*)GetThisPtr())->FCN( npars, grad, f, fitPars, iflag );
 }
 
-#if __cplusplus > 199711L
-static thread_local Int_t  nc   = 0;
-static thread_local double minf = 1000000;
-#else
 static Int_t  nc   = 0;
 static double minf = 1000000;
-#endif
 
 void TMVA::MethodMLP::FCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t* fitPars, Int_t iflag )
 {
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 96d03cc58b61f..368b769728068 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -87,11 +87,7 @@ namespace TMVA {
    const Bool_t MethodPDERS_UseFindRoot = kFALSE;
 };
 
-#if __cplusplus > 199711L
-thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
-#else
 TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
-#endif
 
 REGISTER_METHOD(PDERS)
 
@@ -957,11 +953,7 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 
    // Caching jammed to disable function. 
    // It's not really useful afterall, badly implemented and untested :-)
-#if __cplusplus > 199711L
-   static thread_local Double_t ret = 1.0; 
-#else
    static Double_t ret = 1.0; 
-#endif
    
    if (ret != 0.0) return ret*pdf; 
 
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index e6ee4baca6918..7027d4658c6a4 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -223,11 +223,7 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
 {
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
-#if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
-#else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
-#endif
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
       d[ivar] = (Double_t)ev->GetValue(ivar);
    }
@@ -416,13 +412,8 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
 
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
-#if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
-   static thread_local Int_t type;
-#else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
-#endif
 
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -451,7 +442,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
    Double_t* d = new Double_t[Data()->GetNVariables()] ; 
-   Int_t type;
+   static Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index 2160b5dfee708..0018a579bc104 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -153,11 +153,7 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
 
 
 
-#if __cplusplus > 199711L
-thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
-#else
 TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
-#endif
 
 //-------------------------------------------------------------------------------------------
 TMVA::kNN::ModulekNN::ModulekNN()
@@ -382,11 +378,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       return kFALSE;
    }
    
-#if __cplusplus > 199711L
-   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
-#else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
-#endif
 
    if (cit == fCount.end()) {
       cit = fCount.begin();
diff --git a/tmva/src/MsgLogger.cxx b/tmva/src/MsgLogger.cxx
index 86093c0189a53..5db9cfd190c93 100644
--- a/tmva/src/MsgLogger.cxx
+++ b/tmva/src/MsgLogger.cxx
@@ -40,30 +40,20 @@
 
 #include <assert.h>
 
-#include <memory>
-
 // ROOT include(s):
 
 ClassImp(TMVA::MsgLogger)
 
 // declaration of global variables
 // this is the hard-coded maximum length of the source names
-const UInt_t                           TMVA::MsgLogger::fgMaxSourceSize = 25;
+UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
+Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;
 
 const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
 const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
-#if __cplusplus > 199711L
-std::atomic<Bool_t>                                       TMVA::MsgLogger::fgInhibitOutput{kFALSE};
-std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgTypeMap{0};
-std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgColorMap{0};
-#else
-Bool_t                                       TMVA::MsgLogger::fgInhibitOutput = kFALSE;
-const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
-const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
-#endif
-static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnTypeMap;
-static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnColorMap;
- 
+std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
+std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
+Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;
 
 void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
 void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
@@ -75,6 +65,7 @@ TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
+   fgInstanceCounter++;
    InitMaps();   
 }
 
@@ -86,6 +77,7 @@ TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
+   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -97,6 +89,7 @@ TMVA::MsgLogger::MsgLogger( EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
+   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -108,6 +101,7 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
      fObjSource(0)
 {
    // copy constructor
+   fgInstanceCounter++;
    InitMaps();
    *this = parent;
 }
@@ -116,6 +110,12 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
 TMVA::MsgLogger::~MsgLogger()
 {
    // destructor
+   fgInstanceCounter--;
+   if (fgInstanceCounter == 0) {
+      // last MsgLogger instance has been deleted, can also delete the maps
+      delete fgTypeMap;  fgTypeMap  = 0;
+      delete fgColorMap; fgColorMap = 0;
+   }
 }
 
 //_______________________________________________________________________
@@ -202,14 +202,14 @@ void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
 
    std::map<EMsgType, std::string>::const_iterator stype;
 
-   if ((stype = fgTypeMap.load()->find( type )) != fgTypeMap.load()->end()) {
+   if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
       if (!gConfig().IsSilent() || type==kFATAL) {
          if (gConfig().UseColor()) {
             // no text for INFO or VERBOSE
             if (type == kINFO || type == kVERBOSE)
                std::cout << fgPrefix << line << std::endl; // no color for info
             else
- 	       std::cout << fgColorMap.load()->find( type )->second << fgPrefix << "<"
+               std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
                          << stype->second << "> " << line  << "\033[0m" << std::endl;
          }
          else {
@@ -239,45 +239,24 @@ TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
 void TMVA::MsgLogger::InitMaps()
 {
    // Create the message type and color maps
+   if (fgTypeMap != 0 && fgColorMap != 0) return;
 
-   if(!fgTypeMap) {
-     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
+   fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
+   fgColorMap = new std::map<TMVA::EMsgType, std::string>();
    
-     (*tmp)[kVERBOSE]  = std::string("VERBOSE");
-     (*tmp)[kDEBUG]    = std::string("DEBUG");
-     (*tmp)[kINFO]     = std::string("INFO");
-     (*tmp)[kWARNING]  = std::string("WARNING");
-     (*tmp)[kERROR]    = std::string("ERROR");
-     (*tmp)[kFATAL]    = std::string("FATAL");
-     (*tmp)[kSILENT]   = std::string("SILENT");
-     const std::map<TMVA::EMsgType, std::string>* expected=0;
-     if(fgTypeMap.compare_exchange_strong(expected,tmp)) {
-       //Have the global own this
-       gOwnTypeMap.reset(tmp);
-     } else {
-       //Another thread beat us in creating the instance
-       delete tmp;
-     }
-   }
-
-   if(!fgColorMap) {
-     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
-
-     (*tmp)[kVERBOSE] = std::string("");
-     (*tmp)[kDEBUG]   = std::string("\033[34m");
-     (*tmp)[kINFO]    = std::string("");
-     (*tmp)[kWARNING] = std::string("\033[1;31m");
-     (*tmp)[kERROR]   = std::string("\033[31m");
-     (*tmp)[kFATAL]   = std::string("\033[37;41;1m");
-     (*tmp)[kSILENT]  = std::string("\033[30m");
-
-     const std::map<TMVA::EMsgType, std::string>* expected=0;
-     if(fgColorMap.compare_exchange_strong(expected,tmp)) {
-       //Have the global own this
-       gOwnColorMap.reset(tmp);
-     } else {
-       //Another thread beat us in creating the instance
-       delete tmp;
-     }
-   }
+   (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
+   (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
+   (*fgTypeMap)[kINFO]     = std::string("INFO");
+   (*fgTypeMap)[kWARNING]  = std::string("WARNING");
+   (*fgTypeMap)[kERROR]    = std::string("ERROR");
+   (*fgTypeMap)[kFATAL]    = std::string("FATAL");
+   (*fgTypeMap)[kSILENT]   = std::string("SILENT");
+
+   (*fgColorMap)[kVERBOSE] = std::string("");
+   (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
+   (*fgColorMap)[kINFO]    = std::string("");
+   (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
+   (*fgColorMap)[kERROR]   = std::string("\033[31m");
+   (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
+   (*fgColorMap)[kSILENT]  = std::string("\033[30m");
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index 8f6bbf3d68e40..b56c920e516a6 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -28,6 +28,8 @@
 
 #include "TMVA/Option.h"
 
+TMVA::MsgLogger* TMVA::OptionBase::fgLogger = 0;
+
 //______________________________________________________________________
 TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
    : TObject(), 
@@ -37,6 +39,7 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
      fIsSet       ( kFALSE )
 {
    // constructor
+   if (!fgLogger) fgLogger = new MsgLogger("Option",kDEBUG);
    fNameAllLower.ToLower();
 }
 
@@ -49,12 +52,3 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
    return kTRUE;
 }
 
-TMVA::MsgLogger& TMVA::OptionBase::Log()
-{
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
-#else
-  static MsgLogger logger("Option",kDEBUG);  // message logger
-#endif
-  return logger;
-}
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 875ca43f4b04b..3495c4d369f26 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -49,11 +49,7 @@
 const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
-#if __cplusplus > 199711L
-thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
-#else
 TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
-#endif
 
 ClassImp(TMVA::PDF)
 
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index 1099a9caa3ff1..f7506064c7e05 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -51,10 +51,13 @@ using std::vector;
 
 ClassImp(TMVA::TNeuron)
 
+TMVA::MsgLogger* TMVA::TNeuron::fgLogger = 0;
+
 //______________________________________________________________________________
 TMVA::TNeuron::TNeuron()
 {
    // standard constructor
+   if (!fgLogger) fgLogger = new MsgLogger("TNeuron",kDEBUG);
    InitNeuron();
 }
 
@@ -331,14 +334,3 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
    // print message, for debugging
    Log() << type << message << Endl;
 }
-
-//______________________________________________________________________________
-TMVA::MsgLogger& TMVA::TNeuron::Log() const 
-{
-  #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
-#else
-  static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
-#endif
-  return logger;
-}
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index ab03d79f8b173..da3c0a84646bc 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Matt Jachowski
+// Author: Matt Jachowski 
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -20,10 +20,10 @@
  * modification, are permitted according to the terms listed in LICENSE           *
  * (http://tmva.sourceforge.net/LICENSE)                                          *
  **********************************************************************************/
-
+   
 //_______________________________________________________________________
-//
-// Synapse class used by TMVA artificial neural network methods
+//                                                                      
+// Synapse class used by TMVA artificial neural network methods      
 //_______________________________________________________________________
 
 #include "TMVA/TSynapse.h"
@@ -40,6 +40,8 @@ static const Int_t fgUNINITIALIZED = -1;
 
 ClassImp(TMVA::TSynapse);
 
+TMVA::MsgLogger* TMVA::TSynapse::fgLogger = 0;
+
 //______________________________________________________________________________
 TMVA::TSynapse::TSynapse()
   : fWeight( 0 ),
@@ -52,6 +54,7 @@ TMVA::TSynapse::TSynapse()
 {
    // constructor
    fWeight     = fgUNINITIALIZED;
+   if (!fgLogger) fgLogger = new MsgLogger("TSynapse");
 }
 
 
@@ -72,7 +75,7 @@ void TMVA::TSynapse::SetWeight(Double_t weight)
 Double_t TMVA::TSynapse::GetWeightedValue()
 {
    // get output of pre-neuron weighted by synapse weight
-   if (fPreNeuron == NULL)
+   if (fPreNeuron == NULL) 
       Log() << kFATAL << "<GetWeightedValue> synapse not connected to neuron" << Endl;
 
    return (fWeight * fPreNeuron->GetActivationValue());
@@ -83,7 +86,7 @@ Double_t TMVA::TSynapse::GetWeightedDelta()
 {
    // get error field of post-neuron weighted by synapse weight
 
-   if (fPostNeuron == NULL)
+   if (fPostNeuron == NULL) 
       Log() << kFATAL << "<GetWeightedDelta> synapse not connected to neuron" << Endl;
 
    return fWeight * fPostNeuron->GetDelta();
@@ -105,14 +108,3 @@ void TMVA::TSynapse::CalculateDelta()
    fDelta += fPostNeuron->GetDelta() * fPreNeuron->GetActivationValue();
    fCount++;
 }
-
-//______________________________________________________________________________
-TMVA::MsgLogger& TMVA::TSynapse::Log() const
-{
-#if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
-#else
-  static MsgLogger logger("TSynapse");               //! message logger, static to save resources
-#endif
-  return logger;
-}
diff --git a/tmva/src/Tools.cxx b/tmva/src/Tools.cxx
index f00bfa3447f94..d968043eb668e 100644
--- a/tmva/src/Tools.cxx
+++ b/tmva/src/Tools.cxx
@@ -70,37 +70,10 @@
 
 using namespace std;
 
-#if __cplusplus > 199711L
-std::atomic<TMVA::Tools*> TMVA::Tools::fgTools{0};
-#else
 TMVA::Tools* TMVA::Tools::fgTools = 0;
-#endif
-
 TMVA::Tools& TMVA::gTools()                 { return TMVA::Tools::Instance(); }
-TMVA::Tools& TMVA::Tools::Instance()        {
-#if __cplusplus > 199711L
-  if(!fgTools) {
-    Tools* tmp = new Tools();
-    Tools* expected = 0;
-    if(! fgTools.compare_exchange_strong(expected,tmp)) {
-      //another thread beat us
-      delete tmp;
-    }
-  }
-  return *fgTools;
-#else
-  return fgTools?*(fgTools): *(fgTools = new Tools());
-#endif
-}
-void         TMVA::Tools::DestroyInstance() {
-  //NOTE: there is no thread safe way to do this so
-  // one must only call this method ones in an executable
-#if __cplusplus > 199711L
-  if (fgTools != 0) { delete fgTools.load(); fgTools=0; }
-#else
-  if (fgTools != 0) { delete fgTools; fgTools=0; }
-#endif
-}
+TMVA::Tools& TMVA::Tools::Instance()        { return fgTools?*(fgTools): *(fgTools = new Tools()); }
+void         TMVA::Tools::DestroyInstance() { if (fgTools != 0) { delete fgTools; fgTools=0; } }
 
 //_______________________________________________________________________
 TMVA::Tools::Tools() :
@@ -134,19 +107,19 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
    Double_t separation = 0;
 
    // sanity checks
-   // signal and background histograms must have same number of bins and
+   // signal and background histograms must have same number of bins and 
    // same limits
    if ((S->GetNbinsX() != B->GetNbinsX()) || (S->GetNbinsX() <= 0)) {
       Log() << kFATAL << "<GetSeparation> signal and background"
-            << " histograms have different number of bins: "
+            << " histograms have different number of bins: " 
             << S->GetNbinsX() << " : " << B->GetNbinsX() << Endl;
    }
 
-   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() ||
-       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() ||
+   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() || 
+       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() || 
        S->GetXaxis()->GetXmax() <= S->GetXaxis()->GetXmin()) {
-      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin()
-            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax()
+      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin() 
+            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax() 
             << " " << S->GetXaxis()->GetXmax() << " " << S->GetXaxis()->GetXmin() << Endl;
       Log() << kFATAL << "<GetSeparation> signal and background"
             << " histograms have different or invalid dimensions:" << Endl;
@@ -167,7 +140,7 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
       separation *= intBin;
    }
    else {
-      Log() << kWARNING << "<GetSeparation> histograms with zero entries: "
+      Log() << kWARNING << "<GetSeparation> histograms with zero entries: " 
             << nS << " : " << nB << " cannot compute separation"
             << Endl;
       separation = 0;
@@ -213,11 +186,11 @@ void TMVA::Tools::ComputeStat( const std::vector<TMVA::Event*>& events, std::vec
                                Int_t signalClass, Bool_t  norm )
 {
    // sanity check
-   if (0 == valVec)
+   if (0 == valVec) 
       Log() << kFATAL << "<Tools::ComputeStat> value vector is zero pointer" << Endl;
-
-   if ( events.size() != valVec->size() )
-      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths "
+   
+   if ( events.size() != valVec->size() ) 
+      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths " 
             << events.size() << "!=" << valVec->size() << Endl;
 
    Long64_t entries = valVec->size();
@@ -328,14 +301,14 @@ TMatrixD* TMVA::Tools::GetSQRootMatrix( TMatrixDSym* symMat )
 //_______________________________________________________________________
 const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
 {
-   // turns covariance into correlation matrix
+   // turns covariance into correlation matrix   
    if (covMat == 0) return 0;
 
    // sanity check
    Int_t nvar = covMat->GetNrows();
-   if (nvar != covMat->GetNcols())
+   if (nvar != covMat->GetNcols()) 
       Log() << kFATAL << "<GetCorrelationMatrix> input matrix not quadratic" << Endl;
-
+   
    TMatrixD* corrMat = new TMatrixD( nvar, nvar );
 
    for (Int_t ivar=0; ivar<nvar; ivar++) {
@@ -350,12 +323,12 @@ const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
             }
             if (TMath::Abs( (*corrMat)(ivar,jvar))  > 1){
                Log() << kWARNING
-                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)
+                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)  
                      << " sigma2="<<d
                      << " cov("<<ivar<<","<<ivar<<")=" <<(*covMat)(ivar, ivar)
                      << " cov("<<jvar<<","<<jvar<<")=" <<(*covMat)(jvar, jvar)
-                     << Endl;
-
+                     << Endl; 
+               
             }
          }
          else (*corrMat)(ivar, ivar) = 1.0;
@@ -371,10 +344,10 @@ TH1* TMVA::Tools::projNormTH1F( TTree* theTree, const TString& theVarName,
                                 Double_t xmin, Double_t xmax, const TString& cut )
 {
    // projects variable from tree into normalised histogram
-
+ 
    // needed because of ROOT bug (feature) that excludes events that have value == xmax
-   xmax += 0.00001;
-
+   xmax += 0.00001; 
+   
    TH1* hist = new TH1F( name, name, nbins, xmin, xmax );
    hist->Sumw2(); // enable quadratic errors
    theTree->Project( name, theVarName, cut );
@@ -417,11 +390,11 @@ TList* TMVA::Tools::ParseFormatLine( TString formatString, const char* sep )
       Ssiz_t posSep = formatString.First(sep);
       labelList->Add(new TObjString(TString(formatString(0,posSep)).Data()));
       formatString.Remove(0,posSep+1);
-
+      
       while (formatString.First(sep)==0) formatString.Remove(0,1); // remove additional separators
-
+      
    }
-   return labelList;
+   return labelList;                                                 
 }
 
 //_______________________________________________________________________
@@ -527,9 +500,9 @@ void TMVA::Tools::Scale( std::vector<Float_t>& v, Float_t f )
 
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::vector<TString>* vs ){
-   // sort 2D vector (AND in parallel a TString vector) in such a way
+   // sort 2D vector (AND in parallel a TString vector) in such a way 
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted.
+   // in the same way as necessary to have the first vector sorted. 
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -553,9 +526,9 @@ void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::v
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortDescending( std::vector<std::vector<Double_t> >& v, std::vector<TString>* vs )
 {
-   // sort 2D vector (AND in parallel a TString vector) in such a way
+   // sort 2D vector (AND in parallel a TString vector) in such a way 
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted.
+   // in the same way as necessary to have the first vector sorted. 
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -583,13 +556,13 @@ Double_t TMVA::Tools::GetMutualInformation( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0) return -1;
+   if (hi == 0) return -1; 
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
-
+   
    Double_t mutualInfo = 0.;
    Int_t maxBinX = h.GetNbinsX();
    Int_t maxBinY = h.GetNbinsY();
@@ -614,14 +587,14 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0.) return -1;
+   if (hi == 0.) return -1; 
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
 
-   Double_t corrRatio = 0.;
+   Double_t corrRatio = 0.;    
    Double_t y_mean = h.ProjectionY()->GetMean();
    for (Int_t ix=1; ix<=h.GetNbinsX(); ix++) {
       corrRatio += (h.Integral(ix,ix,1,h.GetNbinsY())/hi)*pow((GetYMean_binX(h,ix)-y_mean),2);
@@ -634,7 +607,7 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
 Double_t TMVA::Tools::GetYMean_binX( const TH2& h, Int_t bin_x )
 {
    // Compute the mean in Y for a given bin X of a 2D histogram
-
+ 
    if (h.Integral(bin_x,bin_x,1,h.GetNbinsY()) == 0.) {return 0;}
    Double_t y_bin_mean = 0.;
    TH1* py = h.ProjectionY();
@@ -654,8 +627,8 @@ TH2F* TMVA::Tools::TransposeHist( const TH2F& h )
    if (h.GetNbinsX() != h.GetNbinsY()) {
       Log() << kFATAL << "<TransposeHist> cannot transpose non-quadratic histogram" << Endl;
    }
-
-   TH2F *transposedHisto = new TH2F( h );
+   
+   TH2F *transposedHisto = new TH2F( h ); 
    for (Int_t ix=1; ix <= h.GetNbinsX(); ix++){
       for (Int_t iy=1; iy <= h.GetNbinsY(); iy++){
          transposedHisto->SetBinContent(iy,ix,h.GetBinContent(ix,iy));
@@ -685,8 +658,8 @@ Bool_t TMVA::Tools::CheckForSilentOption( const TString& cs ) const
    // check for "silence" option in configuration option string
    Bool_t isSilent = kFALSE;
 
-   TString s( cs );
-   s.ToLower();
+   TString s( cs ); 
+   s.ToLower(); 
    s.ReplaceAll(" ","");
    if (s.Contains("silent") && !s.Contains("silent=f")) {
       if (!s.Contains("!silent") || s.Contains("silent=t")) isSilent = kTRUE;
@@ -701,8 +674,8 @@ Bool_t TMVA::Tools::CheckForVerboseOption( const TString& cs ) const
    // check if verbosity "V" set in option
    Bool_t isVerbose = kFALSE;
 
-   TString s( cs );
-   s.ToLower();
+   TString s( cs ); 
+   s.ToLower(); 
    s.ReplaceAll(" ","");
    std::vector<TString> v = SplitString( s, ':' );
    for (std::vector<TString>::iterator it = v.begin(); it != v.end(); it++) {
@@ -766,27 +739,27 @@ Int_t TMVA::Tools::GetIndexMinElement( std::vector<Double_t>& v )
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )
+Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )  
 {
    // check if regular expression
    // helper function to search for "$!%^&()'<>?= " in a string
 
    Bool_t  regular = kFALSE;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
       if (s.Contains( Tools::fRegexp[i] )) { regular = kTRUE; break; }
 
    return regular;
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )
+TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )  
 {
    // replace regular expressions
    // helper function to remove all occurences "$!%^&()'<>?= " from a string
    // and replace all ::,$,*,/,+,- with _M_,_S_,_T_,_D_,_P_,_M_ respectively
 
    TString snew = s;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
       snew.ReplaceAll( Tools::fRegexp[i], r );
 
    snew.ReplaceAll( "::", r );
@@ -811,56 +784,56 @@ TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString&
 }
 
 //_______________________________________________________________________
-const TString& TMVA::Tools::Color( const TString& c )
+const TString& TMVA::Tools::Color( const TString& c ) 
 {
    // human readable color strings
-   static const TString gClr_none         = "" ;
-   static const TString gClr_white        = "\033[1;37m";  // white
-   static const TString gClr_black        = "\033[30m";    // black
-   static const TString gClr_blue         = "\033[34m";    // blue
-   static const TString gClr_red          = "\033[1;31m" ; // red
-   static const TString gClr_yellow       = "\033[1;33m";  // yellow
-   static const TString gClr_darkred      = "\033[31m";    // dark red
-   static const TString gClr_darkgreen    = "\033[32m";    // dark green
-   static const TString gClr_darkyellow   = "\033[33m";    // dark yellow
-
-   static const TString gClr_bold         = "\033[1m"    ; // bold
-   static const TString gClr_black_b      = "\033[30m"   ; // bold black
-   static const TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
-   static const TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
-   static const TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
-
-   static const TString gClr_blue_bg      = "\033[44m";    // blue background
-   static const TString gClr_red_bg       = "\033[1;41m";  // white on red background
-   static const TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
-   static const TString gClr_whiteongreen = "\033[1;42m";  // white on green background
-   static const TString gClr_grey_bg      = "\033[47m";    // grey background
-
-   static const TString gClr_reset  = "\033[0m";     // reset
+   static TString gClr_none         = "" ;
+   static TString gClr_white        = "\033[1;37m";  // white
+   static TString gClr_black        = "\033[30m";    // black
+   static TString gClr_blue         = "\033[34m";    // blue
+   static TString gClr_red          = "\033[1;31m" ; // red
+   static TString gClr_yellow       = "\033[1;33m";  // yellow
+   static TString gClr_darkred      = "\033[31m";    // dark red
+   static TString gClr_darkgreen    = "\033[32m";    // dark green
+   static TString gClr_darkyellow   = "\033[33m";    // dark yellow
+                                    
+   static TString gClr_bold         = "\033[1m"    ; // bold 
+   static TString gClr_black_b      = "\033[30m"   ; // bold black
+   static TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
+   static TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
+   static TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
+                                    
+   static TString gClr_blue_bg      = "\033[44m";    // blue background
+   static TString gClr_red_bg       = "\033[1;41m";  // white on red background
+   static TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
+   static TString gClr_whiteongreen = "\033[1;42m";  // white on green background
+   static TString gClr_grey_bg      = "\033[47m";    // grey background
+
+   static TString gClr_reset  = "\033[0m";     // reset
 
    if (!gConfig().UseColor()) return gClr_none;
 
-   if (c == "white" )         return gClr_white;
-   if (c == "blue"  )         return gClr_blue;
-   if (c == "black"  )        return gClr_black;
+   if (c == "white" )         return gClr_white; 
+   if (c == "blue"  )         return gClr_blue; 
+   if (c == "black"  )        return gClr_black; 
    if (c == "lightblue")      return gClr_cyan_b;
-   if (c == "yellow")         return gClr_yellow;
-   if (c == "red"   )         return gClr_red;
-   if (c == "dred"  )         return gClr_darkred;
-   if (c == "dgreen")         return gClr_darkgreen;
+   if (c == "yellow")         return gClr_yellow; 
+   if (c == "red"   )         return gClr_red; 
+   if (c == "dred"  )         return gClr_darkred; 
+   if (c == "dgreen")         return gClr_darkgreen; 
    if (c == "lgreenb")        return gClr_lgreen_b;
-   if (c == "dyellow")        return gClr_darkyellow;
-
-   if (c == "bold")           return gClr_bold;
-   if (c == "bblack")         return gClr_black_b;
+   if (c == "dyellow")        return gClr_darkyellow; 
 
-   if (c == "blue_bgd")       return gClr_blue_bg;
-   if (c == "red_bgd" )       return gClr_red_bg;
+   if (c == "bold")           return gClr_bold; 
+   if (c == "bblack")         return gClr_black_b; 
 
-   if (c == "white_on_blue" ) return gClr_whiteonblue;
-   if (c == "white_on_green") return gClr_whiteongreen;
+   if (c == "blue_bgd")       return gClr_blue_bg; 
+   if (c == "red_bgd" )       return gClr_red_bg; 
+ 
+   if (c == "white_on_blue" ) return gClr_whiteonblue; 
+   if (c == "white_on_green") return gClr_whiteongreen; 
 
-   if (c == "reset") return gClr_reset;
+   if (c == "reset") return gClr_reset; 
 
    std::cout << "Unknown color " << c << std::endl;
    exit(1);
@@ -869,7 +842,7 @@ const TString& TMVA::Tools::Color( const TString& c )
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V,
+void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V, 
                                    const TString titleVars, const TString titleValues, MsgLogger& logger,
                                    TString format )
 {
@@ -878,7 +851,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    // sanity check
    UInt_t nvar = V.size();
    if ((UInt_t)values.size() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
              << values.size() << " OR " << " != " << nvar << Endl;
    }
 
@@ -899,7 +872,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar
+   // title bar   
    logger << setw(maxL) << titleVars << ":";
    logger << setw(maxV+1) << titleValues << ":";
    logger << Endl;
@@ -926,11 +899,11 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    // sanity check: matrix must be quadratic
    UInt_t nvar = V.size();
    if ((UInt_t)M.GetNcols() != nvar || (UInt_t)M.GetNrows() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
              << M.GetNcols() << " OR " << M.GetNrows() << " != " << nvar << " ==> abort" << Endl;
    }
 
-   // get length of each variable, and maximum length
+   // get length of each variable, and maximum length  
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -938,7 +911,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       vLengths.push_back(TMath::Max( (UInt_t)V[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-
+   
    // count column length
    UInt_t clen = maxL+1;
    for (UInt_t icol=0; icol<nvar; icol++) clen += vLengths[icol]+1;
@@ -947,7 +920,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar
+   // title bar   
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nvar; icol++) logger << setw(vLengths[icol]+1) << V[icol];
    logger << Endl;
@@ -957,7 +930,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       logger << setw(maxL) << V[irow] << ":";
       for (UInt_t icol=0; icol<nvar; icol++) {
          logger << setw(vLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }
+      }      
       logger << Endl;
    }
 
@@ -967,17 +940,17 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const TMatrixD& M,
-                                   const std::vector<TString>& vert, const std::vector<TString>& horiz,
+void TMVA::Tools::FormattedOutput( const TMatrixD& M, 
+                                   const std::vector<TString>& vert, const std::vector<TString>& horiz, 
                                    MsgLogger& logger )
 {
    // formatted output of matrix (with labels)
 
    // sanity check: matrix must be quadratic
-   UInt_t nvvar = vert.size();
+   UInt_t nvvar = vert.size();   
    UInt_t nhvar = horiz.size();
 
-   // get length of each variable, and maximum length
+   // get length of each variable, and maximum length  
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -985,7 +958,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       vLengths.push_back(TMath::Max( (UInt_t)vert[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-
+   
    // count column length
    UInt_t minLh = 7;
    UInt_t maxLh = minLh;
@@ -1002,7 +975,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar
+   // title bar   
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nhvar; icol++) logger << setw(hLengths[icol]+1) << horiz[icol];
    logger << Endl;
@@ -1012,7 +985,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       logger << setw(maxL) << vert[irow] << ":";
       for (UInt_t icol=0; icol<nhvar; icol++) {
          logger << setw(hLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }
+      }      
       logger << Endl;
    }
 
@@ -1100,7 +1073,7 @@ void TMVA::Tools::AddAttr( void* node, const char* attrname, const char* value )
 }
 
 //_______________________________________________________________________
-void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode )
+void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode ) 
 {
    // add child node
    if( !isRootNode && parent == 0 ) return 0;
@@ -1117,7 +1090,7 @@ void* TMVA::Tools::GetParent( void* child)
 {
    // get parent node
    void* par = xmlengine().GetParent(child);
-
+   
    return par;
 }
 //_______________________________________________________________________
@@ -1188,7 +1161,7 @@ std::vector<TString> TMVA::Tools::SplitString(const TString& theOpt, const char
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromInt( Long_t i )
+TString TMVA::Tools::StringFromInt( Long_t i ) 
 {
    // string tools
    std::stringstream s;
@@ -1197,7 +1170,7 @@ TString TMVA::Tools::StringFromInt( Long_t i )
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromDouble( Double_t d )
+TString TMVA::Tools::StringFromDouble( Double_t d ) 
 {
    // string tools
    std::stringstream s;
@@ -1277,7 +1250,7 @@ void TMVA::Tools::TMVAWelcomeMessage()
 void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 {
    // prints the TMVA release number and date
-   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE
+   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE 
           << "" << Endl;
 }
 
@@ -1285,10 +1258,10 @@ void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 void TMVA::Tools::ROOTVersionMessage( MsgLogger& logger )
 {
    // prints the ROOT release number and date
-   static const char * const months[] = { "Jan","Feb","Mar","Apr","May",
+   static const char *months[] = { "Jan","Feb","Mar","Apr","May",
                                    "Jun","Jul","Aug","Sep","Oct",
                                    "Nov","Dec" };
-   Int_t   idatqq = gROOT->GetVersionDate();
+   Int_t   idatqq = gROOT->GetVersionDate();   
    Int_t   iday   = idatqq%100;
    Int_t   imonth = (idatqq/100)%100;
    Int_t   iyear  = (idatqq/10000);
@@ -1369,27 +1342,27 @@ void TMVA::Tools::TMVAWelcomeMessage( MsgLogger& logger, EWelcomeMessage msgType
       break;
 
    case kOriginalWelcomeMsgColor:
-      logger << kINFO << "" << Color("red")
+      logger << kINFO << "" << Color("red") 
              << "_______________________________________" << Color("reset") << Endl;
       logger << kINFO << "" << Color("blue")
              << Color("red_bgd") << Color("bwhite") << " // " << Color("reset")
-             << Color("white") << Color("blue_bgd")
+             << Color("white") << Color("blue_bgd") 
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Color("reset") << Endl;
       logger << kINFO << ""<< Color("blue")
              << Color("red_bgd") << Color("white") << "//  " << Color("reset")
-             << Color("white") << Color("blue_bgd")
+             << Color("white") << Color("blue_bgd") 
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Color("reset") << Endl;
       break;
-
+      
    case kOriginalWelcomeMsgBW:
-      logger << kINFO << ""
+      logger << kINFO << "" 
              << "_______________________________________" << Endl;
       logger << kINFO << " // "
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Endl;
-      logger << kINFO << "//  "
+      logger << kINFO << "//  " 
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Endl;
       break;
-
+      
    default:
       logger << kFATAL << "unknown message type: " << msgType << Endl;
    }
@@ -1434,11 +1407,11 @@ void TMVA::Tools::TMVACitation( MsgLogger& logger, ECitation citType )
 
    case kHtmlLink:
       logger << kINFO << "  " << Endl;
-      logger << kINFO << gTools().Color("bold")
+      logger << kINFO << gTools().Color("bold") 
              << "Thank you for using TMVA!" << gTools().Color("reset") << Endl;
-      logger << kINFO << gTools().Color("bold")
+      logger << kINFO << gTools().Color("bold") 
              << "For citation information, please visit: http://tmva.sf.net/citeTMVA.html"
-             << gTools().Color("reset") << Endl;
+             << gTools().Color("reset") << Endl; 
    }
 }
 
@@ -1477,7 +1450,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
    }
 
    UInt_t nvars=0, ntgts=0, nspcts=0;
-   if (transformBase)
+   if (transformBase) 
       transformBase->CountVariableTypes( nvars, ntgts, nspcts );
    else {
       nvars =events.at(0)->GetNVariables ();
@@ -1531,7 +1504,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
             input.push_back (ev->GetValue(ivar));
          }
       }
-
+       
       if (maxCls > 1) {
          v = vec->at(matNum-1);
          m = mat2->at(matNum-1);
@@ -1603,7 +1576,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    int i = 0;
    if (w==NULL)
    {
-      while ( first != last )
+      while ( first != last ) 
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1621,7 +1594,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    }
    else
    {
-      while ( first != last )
+      while ( first != last ) 
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1669,7 +1642,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble;
+         sum  += adouble; 
          sum2 += adouble*adouble;
          sumw += 1.0;
          ++first;
@@ -1679,7 +1652,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble * (*w);
+         sum  += adouble * (*w); 
          sum2 += adouble*adouble * (*w);
          sumw += (*w);
          ++first;
@@ -1715,7 +1688,7 @@ TH1* TMVA::Tools::GetCumulativeDist( TH1* h)
 
    Float_t partialSum = 0;
    Float_t inverseSum = 0.;
-
+   
    Float_t val;
    for (Int_t ibinEnd=1, ibin=cumulativeDist->GetNbinsX(); ibin >=ibinEnd ; ibin--){
       val = cumulativeDist->GetBinContent(ibin);
diff --git a/tmva/src/Types.cxx b/tmva/src/Types.cxx
index 88701c8f410f5..6d8d060b38bde 100644
--- a/tmva/src/Types.cxx
+++ b/tmva/src/Types.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$
+// @(#)root/tmva $Id$   
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         *
- *      U. of Victoria, Canada                                                    *
- *      MPI-K Heidelberg, Germany                                                 *
+ *      CERN, Switzerland                                                         * 
+ *      U. of Victoria, Canada                                                    * 
+ *      MPI-K Heidelberg, Germany                                                 * 
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -27,19 +27,11 @@
 
 #include <map>
 #include <iostream>
-#if __cplusplus > 199711L
-#include <mutex>
-#endif
 
 #include "TMVA/Types.h"
 #include "TMVA/MsgLogger.h"
 
-#if __cplusplus > 199711L
-std::atomic<TMVA::Types*> TMVA::Types::fgTypesPtr{0};
-static std::mutex gTypesMutex;
-#else
 TMVA::Types* TMVA::Types::fgTypesPtr = 0;
-#endif
 
 //_______________________________________________________________________
 TMVA::Types::Types()
@@ -48,52 +40,33 @@ TMVA::Types::Types()
    // constructor
 }
 
-TMVA::Types::~Types()
+TMVA::Types::~Types() 
 {
    // destructor
    delete fLogger;
 }
 
 //_______________________________________________________________________
-TMVA::Types& TMVA::Types::Instance()
-{
-   // the the single instance of "Types" if existin already, or create it  (Signleton)
-#if __cplusplus > 199711L
-  if(!fgTypesPtr) {
-    Types* tmp = new Types();
-    Types* expected = 0;
-    if(!fgTypesPtr.compare_exchange_strong(expected,tmp)) {
-      //Another thread already did it
-      delete tmp;
-    }
-  }
-  return *fgTypesPtr;
-#else
-   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types());
-#endif
+TMVA::Types& TMVA::Types::Instance() 
+{ 
+   // the the single instance of "Types" if existin already, or create it  (Signleton) 
+   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types()); 
 }
 //_______________________________________________________________________
-void   TMVA::Types::DestroyInstance()
-{
+void   TMVA::Types::DestroyInstance() 
+{ 
    // "destructor" of the single instance
-#if __cplusplus > 199711L
-   if (fgTypesPtr != 0) { delete fgTypesPtr.load(); fgTypesPtr = 0; }
-#else
-   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; }
-#endif
+   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; } 
 }
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname )
+Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname ) 
 {
-#if __cplusplus > 199711L
-   std::lock_guard<std::mutex> guard(gTypesMutex);
-#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( methodname );
    if (it != fStr2type.end()) {
-      Log() << kFATAL
-            << "Cannot add method " << methodname
+      Log() << kFATAL 
+            << "Cannot add method " << methodname 
             << " to the name->type map because it exists already" << Endl;
       return kFALSE;
    }
@@ -103,11 +76,8 @@ Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodnam
 }
 
 //_______________________________________________________________________
-TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
-{
-#if __cplusplus > 199711L
-   std::lock_guard<std::mutex> guard(gTypesMutex);
-#endif
+TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const 
+{ 
    // returns the method type (enum) for a given method (string)
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( method );
    if (it == fStr2type.end()) {
@@ -118,11 +88,8 @@ TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
 }
 
 //_______________________________________________________________________
-TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const
+TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const 
 {
-#if __cplusplus > 199711L
-   std::lock_guard<std::mutex> guard(gTypesMutex);
-#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.begin();
    for (; it!=fStr2type.end(); it++) if (it->second == method) return it->first;
    Log() << kFATAL << "Unknown method index in map: " << method << Endl;

From dc203f7e31a357b00298672c6bc86ee90596635d Mon Sep 17 00:00:00 2001
From: Pere Mato <pere.mato@cern.ch>
Date: Thu, 5 Mar 2015 22:47:17 +0100
Subject: [PATCH 162/200] Changes needed to make Xcode generation working

---
 interpreter/CMakeLists.txt                        | 10 +++++++---
 interpreter/cling/Module.mk                       |  2 +-
 interpreter/cling/lib/Interpreter/CMakeLists.txt  |  2 +-
 interpreter/cling/lib/Interpreter/Interpreter.cpp |  6 ++++--
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/interpreter/CMakeLists.txt b/interpreter/CMakeLists.txt
index 9229d24b99597..b073e14c24356 100644
--- a/interpreter/CMakeLists.txt
+++ b/interpreter/CMakeLists.txt
@@ -44,8 +44,12 @@ else()
 endif()
 set(CMAKE_BUILD_TYPE ${LLVM_BUILD_TYPE})
 
-#---Add the sub-directory exclusing all the targets from all-----------------------------------------
-add_subdirectory(llvm/src EXCLUDE_FROM_ALL)
+#---Add the sub-directory excluding all the targets from all-----------------------------------------
+if(CMAKE_GENERATOR MATCHES "Xcode")
+  add_subdirectory(llvm/src)
+else()
+  add_subdirectory(llvm/src EXCLUDE_FROM_ALL)
+endif()
 
 #---Mark the LLVM/CLANG variables as advanced--------------------------------------------------------
 get_cmake_property(variables CACHE_VARIABLES)
@@ -59,7 +63,7 @@ mark_as_advanced(FORCE BUG_REPORT_URL BUILD_CLANG_FORMAT_VS_PLUGIN BUILD_SHARED_
                        GCC_INSTALL_PREFIX LIBCLANG_BUILD_STATIC TOOL_INFO_PLIST)
 mark_as_advanced(CLEAR LLVM_ENABLE_ASSERTIONS LLVM_BUILD_TYPE)
 #---Set into parent scope LLVM_VERSION --------------------------------------------------------------
-file(READ ${CMAKE_SOURCE_DIR}/interpreter/llvm/src/configure _filestr)
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/llvm/src/configure _filestr)
 string(REGEX REPLACE ".*PACKAGE_VERSION='([0-9]+[.][0-9]+[.][0-9]+).*" "\\1" _llvm_version ${_filestr})
 set(LLVM_VERSION ${_llvm_version} PARENT_SCOPE)
 
diff --git a/interpreter/cling/Module.mk b/interpreter/cling/Module.mk
index 091df9ff620d6..f70d2dfa0ada1 100644
--- a/interpreter/cling/Module.mk
+++ b/interpreter/cling/Module.mk
@@ -171,5 +171,5 @@ $(call stripsrc,$(MODDIR)/lib/Interpreter/CIFactory.o): $(CLINGCOMPDH)
 $(call stripsrc,$(MODDIR)/lib/Interpreter/CIFactory.o): CLINGCXXFLAGS += -I$(dir $(CLINGCOMPDH))
 $(call stripsrc,$(MODDIR)/lib/Interpreter/Interpreter.o): $(CLINGCOMPDH)
 $(call stripsrc,$(MODDIR)/lib/Interpreter/Interpreter.o): CLINGCXXFLAGS += -I$(dir $(CLINGCOMPDH))
-$(call stripsrc,$(MODDIR)/lib/Interpreter/Interpreter.o): CLINGCXXFLAGS += -DCLING_VERSION='"$(CLING_VERSION)"'
+$(call stripsrc,$(MODDIR)/lib/Interpreter/Interpreter.o): CLINGCXXFLAGS += -DCLING_VERSION=$(CLING_VERSION)
 
diff --git a/interpreter/cling/lib/Interpreter/CMakeLists.txt b/interpreter/cling/lib/Interpreter/CMakeLists.txt
index 4b3a48e660274..ac82739ed2968 100644
--- a/interpreter/cling/lib/Interpreter/CMakeLists.txt
+++ b/interpreter/cling/lib/Interpreter/CMakeLists.txt
@@ -58,7 +58,7 @@ if(NOT WIN32)
 set_source_files_properties(RuntimeException.cpp COMPILE_FLAGS -fexceptions)
 endif()
 
-set_source_files_properties(Interpreter.cpp COMPILE_FLAGS -DCLING_VERSION=\\\"${CLING_VERSION}\\\")
+set_source_files_properties(Interpreter.cpp COMPILE_FLAGS -DCLING_VERSION=${CLING_VERSION})
 
 #set_source_files_properties(RuntimeException.cpp COMPILE_FLAGS " /EHsc ")
 # the line above doesn't work, and it gives the following warnings:
diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index 7138ec2acc559..222c11c8cc654 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -47,6 +47,8 @@
 #include <string>
 #include <vector>
 
+#define stringify(s) #s
+
 using namespace clang;
 
 namespace {
@@ -219,7 +221,7 @@ namespace cling {
          I != E; ++I)
       m_IncrParser->commitTransaction(*I);
     // Disable suggestions for ROOT
-    bool showSuggestions = !llvm::StringRef(CLING_VERSION).startswith("ROOT");
+       bool showSuggestions = !llvm::StringRef(stringify(CLING_VERSION)).startswith("ROOT");
     std::unique_ptr<InterpreterCallbacks>
        AutoLoadCB(new AutoloadCallback(this, showSuggestions));
     setCallbacks(std::move(AutoLoadCB));
@@ -239,7 +241,7 @@ namespace cling {
   }
 
   const char* Interpreter::getVersion() const {
-    return CLING_VERSION;
+     return stringify(CLING_VERSION);
   }
 
   void Interpreter::handleFrontendOptions() {

From 5109eacab817047a49f7e4377fde50e2770b746c Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 6 Mar 2015 08:28:59 +0100
Subject: [PATCH 163/200] Fix ROOT-7151: link error for rootcling (Makefile
 infrastructure)

---
 core/utils/Module.mk | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/utils/Module.mk b/core/utils/Module.mk
index c5142ab43f7d4..72351142936b4 100644
--- a/core/utils/Module.mk
+++ b/core/utils/Module.mk
@@ -28,7 +28,7 @@ ROOTCLINGEXEEXTRAO = $(COREO) $(COREDO) $(IOO) $(IODO) $(THREADO) $(THREADDO) $(
 $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 	   $(CLINGMETAUTILSO) $(SNPRINTFO) $(CLINGO) $(ROOTCLINGEXEEXTRAO) \
            $(PCREDEP) $(CORELIBDEP)
-	$(LD) $(LDFLAGS) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) -pthread -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
 	   $(ROOTCLINGTCLINGO) $(CLINGMETAUTILSO) \
 	   $(SNPRINTFO)  $(CLINGO) $(ROOTCLINGEXEEXTRAO) $(CLINGLIBEXTRA) \
 	   $(RPATH) $(CILIBS) $(CORELIBEXTRA) $(PCRELDFLAGS) $(PCRELIB) \
@@ -36,7 +36,7 @@ $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 
 $(ROOTCLINGTMPEXE): $(CINTTMPO) $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) $(CLINGO)
-	$(LD) $(LDFLAGS) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) -pthread -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) \
 	   $(CINTTMPLIBS) $(CLINGO) $(CLINGLIBEXTRA) $(CILIBS)
 

From 4a5053afe582792626c90185e6ee6b4b7baac83c Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Fri, 6 Mar 2015 09:49:31 +0100
Subject: [PATCH 164/200] Only handle .lnk files on Windows (fix Jira issue
 #ROOT-7147)

---
 gui/gui/src/TGFileBrowser.cxx | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gui/gui/src/TGFileBrowser.cxx b/gui/gui/src/TGFileBrowser.cxx
index 1d608c6764418..5284dbdc0884f 100644
--- a/gui/gui/src/TGFileBrowser.cxx
+++ b/gui/gui/src/TGFileBrowser.cxx
@@ -1101,6 +1101,8 @@ TString TGFileBrowser::FullPathName(TGListTreeItem* item)
       itm = parent;
    }
    dirname = gSystem->ExpandPathName(dirname.Data());
+#ifdef R__WIN32
+   // only handle .lnk files on Windows
    while (dirname.Contains(".lnk")) {
       Ssiz_t idx = dirname.Index(".lnk") + 4;
       TString resolved = dirname;
@@ -1108,6 +1110,7 @@ TString TGFileBrowser::FullPathName(TGListTreeItem* item)
       resolved = gSystem->ExpandPathName(resolved.Data());
       dirname = resolved.Append(dirname.Remove(0, idx));
    }
+#endif
    return dirname;
 }
 

From 158d93d5cc6a8766e5d6900f54d16dd4ac7ef0ee Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 6 Mar 2015 09:49:04 +0100
Subject: [PATCH 165/200] Revert "Revert "Make TMVA thread-safe with respect to
 use of Reader""

This reverts commit e9e54b5f228256b9ed79ee04755a06f5df744aa5.
---
 tmva/inc/TMVA/BDTEventWrapper.h      |   4 +
 tmva/inc/TMVA/BinaryTree.h           |   3 +-
 tmva/inc/TMVA/Config.h               |  19 +-
 tmva/inc/TMVA/DataSetFactory.h       |   8 +-
 tmva/inc/TMVA/DataSetManager.h       |   4 +-
 tmva/inc/TMVA/DecisionTreeNode.h     |   2 +-
 tmva/inc/TMVA/Interval.h             |   3 +-
 tmva/inc/TMVA/LogInterval.h          |   3 +-
 tmva/inc/TMVA/MethodBase.h           |   5 +-
 tmva/inc/TMVA/MethodCFMlpANN_Utils.h |  12 +-
 tmva/inc/TMVA/MethodPDERS.h          |   4 +
 tmva/inc/TMVA/ModulekNN.h            |   5 +-
 tmva/inc/TMVA/MsgLogger.h            |  20 +-
 tmva/inc/TMVA/Option.h               |  15 +-
 tmva/inc/TMVA/PDF.h                  |   4 +
 tmva/inc/TMVA/TNeuron.h              |   3 +-
 tmva/inc/TMVA/TSynapse.h             |   3 +-
 tmva/inc/TMVA/Tools.h                |   7 +
 tmva/inc/TMVA/Types.h                |   7 +
 tmva/src/BDTEventWrapper.cxx         |   4 +
 tmva/src/BinaryTree.cxx              |  13 +-
 tmva/src/Config.cxx                  |  20 ++
 tmva/src/DataSetManager.cxx          |  14 +-
 tmva/src/DecisionTreeNode.cxx        |  48 ++---
 tmva/src/Interval.cxx                |  14 +-
 tmva/src/LogInterval.cxx             |  99 +++++-----
 tmva/src/MethodANNBase.cxx           |  13 +-
 tmva/src/MethodBase.cxx              |   8 +
 tmva/src/MethodCFMlpANN_Utils.cxx    |  12 +-
 tmva/src/MethodMLP.cxx               |   5 +
 tmva/src/MethodPDERS.cxx             |   8 +
 tmva/src/MethodTMlpANN.cxx           |  11 +-
 tmva/src/ModulekNN.cxx               |   8 +
 tmva/src/MsgLogger.cxx               |  91 +++++----
 tmva/src/Option.cxx                  |  12 +-
 tmva/src/PDF.cxx                     |   4 +
 tmva/src/TNeuron.cxx                 |  14 +-
 tmva/src/TSynapse.cxx                |  26 ++-
 tmva/src/Tools.cxx                   | 273 +++++++++++++++------------
 tmva/src/Types.cxx                   |  69 +++++--
 40 files changed, 572 insertions(+), 325 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index 8a2ec791bcf72..cc3d0ae17814e 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -67,7 +67,11 @@ namespace TMVA {
     
    private:
 
+#if __cplusplus > 199711L
+      static thread_local Int_t fVarIndex;  // index of the variable to sort on
+#else
       static Int_t fVarIndex;  // index of the variable to sort on
+#endif
       const Event* fEvent;     // pointer to the event
     
       Double_t     fBkgWeight; // cumulative background weight for splitting
diff --git a/tmva/inc/TMVA/BinaryTree.h b/tmva/inc/TMVA/BinaryTree.h
index 81fe591789c4c..d76ed44a1214a 100644
--- a/tmva/inc/TMVA/BinaryTree.h
+++ b/tmva/inc/TMVA/BinaryTree.h
@@ -123,8 +123,7 @@ namespace TMVA {
       UInt_t     fNNodes;           // total number of nodes in the tree (counted)
       UInt_t     fDepth;            // maximal depth in tree reached
 
-      static MsgLogger* fgLogger;   // message logger, static to save resources    
-      MsgLogger& Log() const { return *fgLogger; }
+      MsgLogger& Log() const;
 
       ClassDef(BinaryTree,0) // Base class for BinarySearch and Decision Trees
    };  
diff --git a/tmva/inc/TMVA/Config.h b/tmva/inc/TMVA/Config.h
index 08e55ff89e47d..d8d56fa33bc90 100644
--- a/tmva/inc/TMVA/Config.h
+++ b/tmva/inc/TMVA/Config.h
@@ -36,7 +36,9 @@
 // Singleton class for global configuration settings used by TMVA       //
 //                                                                      //
 //////////////////////////////////////////////////////////////////////////
-
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
 #endif
@@ -103,16 +105,27 @@ namespace TMVA {
 
       // private constructor
       Config();
+      Config( const Config& );
+      Config& operator=( const Config&);
       virtual ~Config();
+#if __cplusplus > 199711L
+      static std::atomic<Config*> fgConfigPtr;
+#else
       static Config* fgConfigPtr;
-                  
+#endif                  
    private:
 
+#if __cplusplus > 199711L
+      std::atomic<Bool_t> fUseColoredConsole;     // coloured standard output
+      std::atomic<Bool_t> fSilent;                // no output at all
+      std::atomic<Bool_t> fWriteOptionsReference; // if set true: Configurable objects write file with option reference
+      std::atomic<Bool_t> fDrawProgressBar;       // draw progress bar to indicate training evolution
+#else
       Bool_t fUseColoredConsole;     // coloured standard output
       Bool_t fSilent;                // no output at all
       Bool_t fWriteOptionsReference; // if set true: Configurable objects write file with option reference
       Bool_t fDrawProgressBar;       // draw progress bar to indicate training evolution
-
+#endif
       mutable MsgLogger* fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }
          
diff --git a/tmva/inc/TMVA/DataSetFactory.h b/tmva/inc/TMVA/DataSetFactory.h
index bfd54f04830a1..de1d85fbc5496 100644
--- a/tmva/inc/TMVA/DataSetFactory.h
+++ b/tmva/inc/TMVA/DataSetFactory.h
@@ -254,6 +254,8 @@ namespace TMVA {
 
       DataSet* CreateDataSet( DataSetInfo &, DataInputHandler& );
 
+      static DataSetFactory* NewInstance() { return new DataSetFactory(); }
+      static void destroyNewInstance(DataSetFactory* iOther) { delete iOther;}
    protected:
 
       ~DataSetFactory();
@@ -314,8 +316,8 @@ namespace TMVA {
       Bool_t                     fScaleWithPreselEff; //! how to deal with requested #events in connection with preselection cuts 
 
       // the event
-      mutable TTree*             fCurrentTree;       //! the tree, events are currently read from
-      mutable UInt_t             fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
+      TTree*                     fCurrentTree;       //! the tree, events are currently read from
+      UInt_t                     fCurrentEvtIdx;     //! the current event (to avoid reading of the same event)
 
       // the formulas for reading the original tree
       std::vector<TTreeFormula*> fInputFormulas;   //! input variables
@@ -324,7 +326,7 @@ namespace TMVA {
       std::vector<TTreeFormula*> fWeightFormula;   //! weights
       std::vector<TTreeFormula*> fSpectatorFormulas; //! spectators
 
-      mutable MsgLogger*         fLogger;          //! message logger
+      MsgLogger*                 fLogger;          //! message logger
       MsgLogger& Log() const { return *fLogger; }
    };
 }
diff --git a/tmva/inc/TMVA/DataSetManager.h b/tmva/inc/TMVA/DataSetManager.h
index 864a5e5ab161b..6bef1c6d579b1 100644
--- a/tmva/inc/TMVA/DataSetManager.h
+++ b/tmva/inc/TMVA/DataSetManager.h
@@ -84,14 +84,14 @@ namespace TMVA {
 /*       DataSetManager(); */ // DSMTEST
 /*       DataSetManager( DataInputHandler& dataInput ); */ // DSMTEST
 
-// //      TMVA::DataSetFactory* fDatasetFactory; // DSMTEST
+      TMVA::DataSetFactory* fDatasetFactory;
 
       // access to input data
       DataInputHandler& DataInput() { return fDataInput; }
 
       DataInputHandler&          fDataInput;             //! source of input data
       TList                      fDataSetInfoCollection; //! all registered dataset definitions
-      mutable MsgLogger*         fLogger;   // message logger
+      MsgLogger*                 fLogger;   // message logger
       MsgLogger& Log() const { return *fLogger; }    
    };
 }
diff --git a/tmva/inc/TMVA/DecisionTreeNode.h b/tmva/inc/TMVA/DecisionTreeNode.h
index 8e1935a42fe58..0b590ef79f41e 100644
--- a/tmva/inc/TMVA/DecisionTreeNode.h
+++ b/tmva/inc/TMVA/DecisionTreeNode.h
@@ -355,7 +355,7 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger* fgLogger;    // static because there is a huge number of nodes...
+      static MsgLogger& Log();
 
       std::vector<Double_t>       fFisherCoeff;    // the fisher coeff (offset at the last element)
 
diff --git a/tmva/inc/TMVA/Interval.h b/tmva/inc/TMVA/Interval.h
index c057bb883dc6e..b1afa1bf29a18 100644
--- a/tmva/inc/TMVA/Interval.h
+++ b/tmva/inc/TMVA/Interval.h
@@ -90,8 +90,7 @@ namespace TMVA {
       Int_t    fNbins;        // when >0 : number of bins (discrete interval); when ==0 continuous interval
 
    private:
-      static MsgLogger* fgLogger;   // message logger
-      MsgLogger& Log() const { return *fgLogger; }          
+      MsgLogger& Log() const;          
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/LogInterval.h b/tmva/inc/TMVA/LogInterval.h
index f251e81cd1c67..687705a8e6b47 100644
--- a/tmva/inc/TMVA/LogInterval.h
+++ b/tmva/inc/TMVA/LogInterval.h
@@ -105,8 +105,7 @@ namespace TMVA {
       void SetMax( Double_t m ) { fMax = m; }
       void SetMin( Double_t m ) { fMin = m; }
 
-      static MsgLogger* fgLogger;   // message logger
-      MsgLogger& Log() const { return *fgLogger; }          
+      MsgLogger& Log() const;
 
       ClassDef(Interval,0)    // Interval definition, continous and discrete
    };
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 02bffb8ac9df5..8a1c2d28610b9 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -629,8 +629,11 @@ namespace TMVA {
    private:
 
       // this carrier
+#if __cplusplus > 199711L
+      static thread_local MethodBase* fgThisBase;         // this pointer
+#else
       static MethodBase* fgThisBase;         // this pointer
-
+#endif
 
       // ===== depreciated options, kept for backward compatibility  =====
    private:
diff --git a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
index 3d1fa1a1ae62c..d0f9ba4f08578 100644
--- a/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
+++ b/tmva/inc/TMVA/MethodCFMlpANN_Utils.h
@@ -99,12 +99,12 @@ namespace TMVA {
 
    protected:
 
-      static Int_t       fg_100;          // constant
-      static Int_t       fg_0;            // constant
-      static Int_t       fg_max_nVar_;    // static maximum number of input variables
-      static Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
-      static Int_t       fg_999;          // constant
-      static const char* fg_MethodName;   // method name for print
+      static Int_t             fg_100;          // constant
+      static Int_t             fg_0;            // constant
+      static const Int_t       fg_max_nVar_;    // static maximum number of input variables
+      static const Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
+      static Int_t             fg_999;          // constant
+      static const char* const fg_MethodName;   // method name for print
 
       Double_t W_ref(const Double_t wNN[], Int_t a_1, Int_t a_2, Int_t a_3) const {
          return wNN [(a_3*max_nNodes_ + a_2)*max_nLayers_ + a_1 - 187];
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index 3ae5d497451eb..9d1a4f7bd1e61 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -220,7 +220,11 @@ namespace TMVA {
                                  Float_t sumW2S, Float_t sumW2B ) const;
 
       // this carrier
+#if __cplusplus > 199711L
+      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+#else
       static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+#endif
       void UpdateThis();
 
       void Init( void );
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index 1851491e408f5..569ee5e80b46c 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -148,8 +148,11 @@ namespace TMVA {
 
       private:
 
+#if __cplusplus > 199711L
+         static thread_local TRandom3 fgRndm;
+#else
          static TRandom3 fgRndm;
-
+#endif
          UInt_t fDimn;
 
          Node<Event> *fTree;
diff --git a/tmva/inc/TMVA/MsgLogger.h b/tmva/inc/TMVA/MsgLogger.h
index d93e3f6c00469..44505dd03d50f 100644
--- a/tmva/inc/TMVA/MsgLogger.h
+++ b/tmva/inc/TMVA/MsgLogger.h
@@ -43,6 +43,9 @@
 #include <sstream>
 #include <iostream>
 #include <map>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 // ROOT include(s)
 #ifndef ROOT_TObject
@@ -75,7 +78,7 @@ namespace TMVA {
       std::string GetPrintedSource()   const;
       std::string GetFormattedSource() const;
 
-      static UInt_t GetMaxSourceSize()                    { return (UInt_t)fgMaxSourceSize; }
+      static UInt_t GetMaxSourceSize()                    { return (const UInt_t)fgMaxSourceSize; }
 
       // Needed for copying
       MsgLogger& operator= ( const MsgLogger& parent );
@@ -113,13 +116,20 @@ namespace TMVA {
       static const std::string fgPrefix;          // the prefix of the source name
       static const std::string fgSuffix;          // suffix following source name
       EMsgType                 fActiveType;       // active type
-      static UInt_t            fgMaxSourceSize;   // maximum length of source name
+      static const UInt_t      fgMaxSourceSize;   // maximum length of source name
+#if __cplusplus > 199711L
+      static std::atomic<Bool_t> fgOutputSupressed; // disable the output globaly (used by generic booster)
+      static std::atomic<Bool_t> fgInhibitOutput;   // flag to suppress all output
+
+      static std::atomic<const std::map<EMsgType, std::string>*> fgTypeMap;   // matches output types with strings
+      static std::atomic<const std::map<EMsgType, std::string>*> fgColorMap;  // matches output types with terminal colors
+#else
       static Bool_t            fgOutputSupressed; // disable the output globaly (used by generic booster)
       static Bool_t            fgInhibitOutput;   // flag to suppress all output
-      static Int_t             fgInstanceCounter; // counts open MsgLogger instances
 
-      static std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
-      static std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
+      static const std::map<EMsgType, std::string>* fgTypeMap;   // matches output types with strings
+      static const std::map<EMsgType, std::string>* fgColorMap;  // matches output types with terminal colors
+#endif
       EMsgType                                fMinType;    // minimum type for output
 
       ClassDef(MsgLogger,0) // Ostringstream derivative to redirect and format logging output
diff --git a/tmva/inc/TMVA/Option.h b/tmva/inc/TMVA/Option.h
index 458b3acb8ac1a..4a0d80e8b41eb 100644
--- a/tmva/inc/TMVA/Option.h
+++ b/tmva/inc/TMVA/Option.h
@@ -93,8 +93,7 @@ namespace TMVA {
 
    protected:
 
-      static MsgLogger* fgLogger;  // message logger
-
+      static MsgLogger& Log();
    };
       
    // ---------------------------------------------------------------------------
@@ -249,16 +248,16 @@ namespace TMVA {
    inline void TMVA::Option<Bool_t>::AddPreDefVal( const Bool_t& ) 
    {
       // template specialization for Bool_t 
-      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
-                << Endl;
+      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Bool_t> don't make sense" 
+	    << Endl;
    }
 
    template<>
    inline void TMVA::Option<Float_t>::AddPreDefVal( const Float_t& ) 
    {
       // template specialization for Float_t 
-      *fgLogger << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
-                << Endl;
+      Log() << kFATAL << "<AddPreDefVal> predefined values for Option<Float_t> don't make sense" 
+	    << Endl;
    }
 
    template<class T>
@@ -358,8 +357,8 @@ namespace TMVA {
          this->Value() = false;
       }
       else {
-         *fgLogger << kFATAL << "<SetValueLocal> value \'" << val 
-                   << "\' can not be interpreted as boolean" << Endl;
+         Log() << kFATAL << "<SetValueLocal> value \'" << val 
+	       << "\' can not be interpreted as boolean" << Endl;
       }
    }
 }
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index 9962198ec37d8..e6387c99b496d 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -205,7 +205,11 @@ namespace TMVA {
       MsgLogger&               Log() const { return *fLogger; }    
 
       // static pointer to this object
+#if __cplusplus > 199711L
+      static thread_local PDF* fgThisPDF;             // this PDF pointer 
+#else
       static PDF*              fgThisPDF;             // this PDF pointer 
+#endif
       static PDF*              ThisPDF( void ); 
 
       // external auxiliary functions 
diff --git a/tmva/inc/TMVA/TNeuron.h b/tmva/inc/TMVA/TNeuron.h
index 101b1413319e8..eff915cfbc569 100644
--- a/tmva/inc/TMVA/TNeuron.h
+++ b/tmva/inc/TMVA/TNeuron.h
@@ -163,8 +163,7 @@ namespace TMVA {
       TActivation*  fActivation;              // activation equation
       TNeuronInput* fInputCalculator;         // input calculator
 
-      static MsgLogger* fgLogger;                     //! message logger, static to save resources
-      MsgLogger& Log() const { return *fgLogger; }                       
+      MsgLogger& Log() const;
 
       ClassDef(TNeuron,0) // Neuron class used by MethodANNBase derivative ANNs
    };
diff --git a/tmva/inc/TMVA/TSynapse.h b/tmva/inc/TMVA/TSynapse.h
index 66107687d25c5..d8bf444c30d7d 100644
--- a/tmva/inc/TMVA/TSynapse.h
+++ b/tmva/inc/TMVA/TSynapse.h
@@ -102,8 +102,7 @@ namespace TMVA {
       TNeuron* fPreNeuron;         // pointer to pre-neuron
       TNeuron* fPostNeuron;        // pointer to post-neuron
 
-      static MsgLogger* fgLogger;                     //! message logger, static to save resources
-      MsgLogger& Log() const { return *fgLogger; }                       
+      MsgLogger& Log() const;
 
       ClassDef(TSynapse,0) // Synapse class used by MethodANNBase and derivatives
    };
diff --git a/tmva/inc/TMVA/Tools.h b/tmva/inc/TMVA/Tools.h
index 011196cd3e0eb..cb6d51722a280 100644
--- a/tmva/inc/TMVA/Tools.h
+++ b/tmva/inc/TMVA/Tools.h
@@ -41,6 +41,9 @@
 #include <sstream>
 #include <iostream>
 #include <iomanip>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #ifndef ROOT_TXMLEngine
 #include "TXMLEngine.h"
@@ -238,7 +241,11 @@ namespace TMVA {
       const TString fRegexp;
       mutable MsgLogger*    fLogger;
       MsgLogger& Log() const { return *fLogger; }
+#if __cplusplus > 199711L
+      static std::atomic<Tools*> fgTools;
+#else
       static Tools* fgTools;
+#endif
 
       // xml tools
 
diff --git a/tmva/inc/TMVA/Types.h b/tmva/inc/TMVA/Types.h
index cb5f45ce67039..e245cf0c2abf4 100644
--- a/tmva/inc/TMVA/Types.h
+++ b/tmva/inc/TMVA/Types.h
@@ -38,6 +38,9 @@
 //////////////////////////////////////////////////////////////////////////
 
 #include <map>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #ifndef ROOT_Rtypes
 #include "Rtypes.h"
@@ -154,7 +157,11 @@ namespace TMVA {
    private:
 
       Types();
+#if __cplusplus > 199711L
+      static std::atomic<Types*> fgTypesPtr;
+#else
       static Types* fgTypesPtr;
+#endif
 
    private:
 
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index c7429e0bcb13b..0820339c01c41 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -26,7 +26,11 @@
 
 using namespace TMVA;
 
+#if __cplusplus > 199711L
+thread_local Int_t BDTEventWrapper::fVarIndex = 0;
+#else
 Int_t BDTEventWrapper::fVarIndex = 0;
+#endif
 
 BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
    // constuctor
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index 4b3b7d2d5e27b..dca177c92dbd2 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -46,8 +46,6 @@
 
 ClassImp(TMVA::BinaryTree)
 
-TMVA::MsgLogger* TMVA::BinaryTree::fgLogger = 0;
-
 //_______________________________________________________________________
 TMVA::BinaryTree::BinaryTree( void )
    : fRoot  ( NULL ),
@@ -55,7 +53,6 @@ TMVA::BinaryTree::BinaryTree( void )
      fDepth ( 0 )
 {
    // constructor for a yet "empty" tree. Needs to be filled afterwards
-   if (!fgLogger) fgLogger =  new MsgLogger("BinaryTree");
 }
 
 //_______________________________________________________________________
@@ -221,3 +218,13 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 
    return;
 }
+
+//_______________________________________________________________________
+TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("BinaryTree");
+#else
+  static MsgLogger logger("BinaryTree");
+#endif
+  return logger;
+}
diff --git a/tmva/src/Config.cxx b/tmva/src/Config.cxx
index de124def90151..6dd287a9c51d1 100644
--- a/tmva/src/Config.cxx
+++ b/tmva/src/Config.cxx
@@ -31,7 +31,11 @@
 
 ClassImp(TMVA::Config)
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Config*> TMVA::Config::fgConfigPtr{ 0 };
+#else
 TMVA::Config* TMVA::Config::fgConfigPtr = 0;
+#endif
 
 TMVA::Config& TMVA::gConfig() { return TMVA::Config::Instance(); }
 
@@ -71,13 +75,29 @@ TMVA::Config::~Config()
 void TMVA::Config::DestroyInstance()
 {
    // static function: destroy TMVA instance
+#if __cplusplus > 199711L
+  delete fgConfigPtr.exchange(0);
+#else
    if (fgConfigPtr != 0) { delete fgConfigPtr; fgConfigPtr = 0;}
+#endif
 }
 
 //_______________________________________________________________________
 TMVA::Config& TMVA::Config::Instance()
 {
    // static function: returns  TMVA instance
+#if __cplusplus > 199711L
+  if(!fgConfigPtr) {
+    TMVA::Config* tmp = new Config();
+    TMVA::Config* expected = 0;
+    if(! fgConfigPtr.compare_exchange_strong(expected,tmp) ) {
+      //another thread beat us to the switch
+      delete tmp;
+    }
+  }
+  return *fgConfigPtr;
+#else
    return fgConfigPtr ? *fgConfigPtr :*(fgConfigPtr = new Config());
+#endif
 }
 
diff --git a/tmva/src/DataSetManager.cxx b/tmva/src/DataSetManager.cxx
index 63c81e0ea142d..9ed04df3ee4d0 100644
--- a/tmva/src/DataSetManager.cxx
+++ b/tmva/src/DataSetManager.cxx
@@ -52,7 +52,8 @@ using std::endl;
 
 //_______________________________________________________________________
 TMVA::DataSetManager::DataSetManager( DataInputHandler& dataInput )
-   : fDataInput(dataInput),
+   : fDatasetFactory(0),
+     fDataInput(dataInput),
      fDataSetInfoCollection(),
      fLogger( new MsgLogger("DataSetManager", kINFO) )
 {
@@ -65,8 +66,8 @@ TMVA::DataSetManager::~DataSetManager()
    // destructor
 //   fDataSetInfoCollection.SetOwner(); // DSMTEST --> created a segfault because the DataSetInfo-objects got deleted twice
 
-   TMVA::DataSetFactory::destroyInstance();
-   
+   DataSetFactory::destroyNewInstance(fDatasetFactory);
+
    delete fLogger;
 }
 
@@ -78,18 +79,19 @@ TMVA::DataSet* TMVA::DataSetManager::CreateDataSet( const TString& dsiName )
    if (!dsi) Log() << kFATAL << "DataSetInfo object '" << dsiName << "' not found" << Endl;
 
    // factory to create dataset from datasetinfo and datainput
-   return TMVA::DataSetFactory::Instance().CreateDataSet( *dsi, fDataInput );
+   if(!fDatasetFactory) { fDatasetFactory = DataSetFactory::NewInstance(); }
+   return fDatasetFactory->CreateDataSet( *dsi, fDataInput );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName) 
+TMVA::DataSetInfo* TMVA::DataSetManager::GetDataSetInfo(const TString& dsiName)
 {
    // returns datasetinfo object for given name
    return (DataSetInfo*)fDataSetInfoCollection.FindObject( dsiName );
 }
 
 //_______________________________________________________________________
-TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi) 
+TMVA::DataSetInfo& TMVA::DataSetManager::AddDataSetInfo(DataSetInfo& dsi)
 {
    // stores a copy of the dataset info object
 
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index 235ebeb396948..37425a83b94f7 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -50,7 +50,6 @@ using std::string;
 
 ClassImp(TMVA::DecisionTreeNode)
 
-TMVA::MsgLogger* TMVA::DecisionTreeNode::fgLogger = 0;
 bool     TMVA::DecisionTreeNode::fgIsTraining = false;
 UInt_t   TMVA::DecisionTreeNode::fgTmva_Version_Code = 0;
 //_______________________________________________________________________
@@ -66,8 +65,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode()
      fIsTerminalNode( kFALSE )
 {
    // constructor of an essentially "empty" node floating in space
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -91,8 +88,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode(TMVA::Node* p, char pos)
      fIsTerminalNode( kFALSE )
 {
    // constructor of a daughter node as a daughter of 'p'
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    if (DecisionTreeNode::fgIsTraining){
       fTrainInfo = new DTNodeTrainingInfo();
       //std::cout << "Node constructor with TrainingINFO"<<std::endl;
@@ -118,8 +113,6 @@ TMVA::DecisionTreeNode::DecisionTreeNode(const TMVA::DecisionTreeNode &n,
 {
    // copy constructor of a node. It will result in an explicit copy of
    // the node and recursively all it's daughters
-   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
-
    this->SetParent( parent );
    if (n.GetLeft() == 0 ) this->SetLeft(NULL);
    else this->SetLeft( new DecisionTreeNode( *((DecisionTreeNode*)(n.GetLeft())),this));
@@ -151,11 +144,11 @@ Bool_t TMVA::DecisionTreeNode::GoesRight(const TMVA::Event & e) const
    Bool_t result;
    // first check if the fisher criterium is used or ordinary cuts:
    if (GetNFisherCoeff() == 0){
-      
+
       result = (e.GetValue(this->GetSelector()) >= this->GetCutValue() );
 
    }else{
-      
+
       Double_t fisher = this->GetFisherCoeff(fFisherCoeff.size()-1); // the offset
       for (UInt_t ivar=0; ivar<fFisherCoeff.size()-1; ivar++)
          fisher += this->GetFisherCoeff(ivar)*(e.GetValue(ivar));
@@ -187,8 +180,8 @@ void TMVA::DecisionTreeNode::SetPurity( void )
       fPurity = this->GetNSigEvents() / ( this->GetNSigEvents() + this->GetNBkgEvents());
    }
    else {
-      *fgLogger << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
-      this->Print(*fgLogger);
+      Log() << kINFO << "Zero events in purity calcuation , return purity=0.5" << Endl;
+      this->Print(Log());
       fPurity = 0.5;
    }
    return;
@@ -205,7 +198,7 @@ void TMVA::DecisionTreeNode::Print(std::ostream& os) const
       << "NCoef: "  << this->GetNFisherCoeff();
    for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) { os << "fC"<<i<<": " << this->GetFisherCoeff(i);}
    os << " ivar: "  << this->GetSelector()
-      << " cut: "   << this->GetCutValue() 
+      << " cut: "   << this->GetCutValue()
       << " cType: " << this->GetCutType()
       << " s: "     << this->GetNSigEvents()
       << " b: "     << this->GetNBkgEvents()
@@ -390,7 +383,7 @@ void TMVA::DecisionTreeNode::PrintRecPrune( std::ostream& os ) const {
 void TMVA::DecisionTreeNode::SetCC(Double_t cc)
 {
    if (fTrainInfo) fTrainInfo->fCC = cc;
-   else *fgLogger << kFATAL << "call to SetCC without trainingInfo" << Endl;
+   else Log() << kFATAL << "call to SetCC without trainingInfo" << Endl;
 }
 
 //_______________________________________________________________________
@@ -398,8 +391,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMin(UInt_t ivar) const {
    // return the minimum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMin[ivar];
-   else *fgLogger << kFATAL << "You asked for Min of the event sample in node for variable "
-                  << ivar << " that is out of range" << Endl;
+   else Log() << kFATAL << "You asked for Min of the event sample in node for variable "
+              << ivar << " that is out of range" << Endl;
    return -9999;
 }
 
@@ -408,8 +401,8 @@ Float_t TMVA::DecisionTreeNode::GetSampleMax(UInt_t ivar) const {
    // return the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if (fTrainInfo && ivar < fTrainInfo->fSampleMin.size()) return fTrainInfo->fSampleMax[ivar];
-   else *fgLogger << kFATAL << "You asked for Max of the event sample in node for variable "
-                  << ivar << " that is out of range" << Endl;
+   else Log() << kFATAL << "You asked for Max of the event sample in node for variable "
+              << ivar << " that is out of range" << Endl;
    return 9999;
 }
 
@@ -428,7 +421,7 @@ void TMVA::DecisionTreeNode::SetSampleMax(UInt_t ivar, Float_t xmax){
    // set the maximum of variable ivar from the training sample
    // that pass/end up in this node
    if( ! fTrainInfo ) return;
-   if ( ivar >= fTrainInfo->fSampleMax.size() ) 
+   if ( ivar >= fTrainInfo->fSampleMax.size() )
       fTrainInfo->fSampleMax.resize(ivar+1);
    fTrainInfo->fSampleMax[ivar]=xmax;
 }
@@ -452,10 +445,10 @@ void TMVA::DecisionTreeNode::ReadAttributes(void* node, UInt_t /* tmva_Version_C
    }
    gTools().ReadAttr(node, "IVar",  fSelector               );
    gTools().ReadAttr(node, "Cut",   fCutValue               );
-   gTools().ReadAttr(node, "cType", fCutType                );               
+   gTools().ReadAttr(node, "cType", fCutType                );
    if (gTools().HasAttr(node,"res")) gTools().ReadAttr(node, "res",   fResponse);
    if (gTools().HasAttr(node,"rms")) gTools().ReadAttr(node, "rms",   fRMS);
-   //   else { 
+   //   else {
    if( gTools().HasAttr(node, "purity") ) {
       gTools().ReadAttr(node, "purity",fPurity );
    } else {
@@ -473,7 +466,7 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 {
    // add attribute to xml
    gTools().AddAttr(node, "NCoef", GetNFisherCoeff());
-   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++) 
+   for (Int_t i=0; i< (Int_t) this->GetNFisherCoeff(); i++)
       gTools().AddAttr(node, Form("fC%d",i),  this->GetFisherCoeff(i));
 
    gTools().AddAttr(node, "IVar",  GetSelector());
@@ -494,8 +487,8 @@ void TMVA::DecisionTreeNode::AddAttributesToNode(void* node) const
 void  TMVA::DecisionTreeNode::SetFisherCoeff(Int_t ivar, Double_t coeff)
 {
    // set fisher coefficients
-   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ; 
-   fFisherCoeff[ivar]=coeff;      
+   if ((Int_t) fFisherCoeff.size()<ivar+1) fFisherCoeff.resize(ivar+1) ;
+   fFisherCoeff[ivar]=coeff;
 }
 
 //_______________________________________________________________________
@@ -513,3 +506,12 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
    // and somehow I guess someone programmed it such that we need this in
    // this tree too, although we don't..)
 }
+//_______________________________________________________________________
+TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+#else
+  static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+#endif
+  return logger;
+}
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index e37ac0ac02c5f..d89b023679f49 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -75,16 +75,12 @@ End_Html */
 
 ClassImp(TMVA::Interval)
 
-TMVA::MsgLogger* TMVA::Interval::fgLogger = 0;
-
 //_______________________________________________________________________
 TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
    fMin(min),
    fMax(max),
    fNbins(nbins)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("Interval");
-
    // defines minimum and maximum of an interval
    // when nbins > 0, interval describes a discrete distribution (equally distributed in the interval)
    // when nbins == 0, interval describes a continous interval
@@ -105,7 +101,6 @@ TMVA::Interval::Interval( const Interval& other ) :
    fMax  ( other.fMax ),
    fNbins( other.fNbins )
 {
-   if (!fgLogger) fgLogger = new MsgLogger("Interval");
 }
 
 //_______________________________________________________________________
@@ -168,3 +163,12 @@ void TMVA::Interval::Print(std::ostream &os) const
       os << "| " << GetElement(i)<<" |" ;
    }  
 }
+
+TMVA::MsgLogger& TMVA::Interval::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("Interval");   // message logger
+#else
+  static MsgLogger logger("Interval");   // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 6bdbb1c0c20c3..922ae5ace5991 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -13,8 +13,8 @@
  *      Helge Voss <helge.voss@cern.ch>  - MPI-K Heidelberg, Germany              *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      MPI-K Heidelberg, Germany                                                 *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -35,39 +35,39 @@
    </ul>
 </ul>
 <pre>
-    Example:             
- LogInterval(1,10000,5)                                          
-     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!  
-     i=1 --> 10                    StepSize(ibin=1) = 9              
-     i=2 --> 100                   StepSize(ibin=2) = 99                         
-     i=3 --> 1000                  StepSize(ibin=3) = 999                     
-     i=4 --> 10000                 StepSize(ibin=4) = 9999                 
-                                                
- LogInterval(1,1000,11)                     
-    i=0 --> 1                           
-    i=1 --> 1.99526                 
-    i=2 --> 3.98107             
-    i=3 --> 7.94328         
-    i=4 --> 15.8489      
-    i=5 --> 31.6228      
-    i=6 --> 63.0957      
-    i=7 --> 125.893      
-    i=8 --> 251.189      
-    i=9 --> 501.187      
-    i=10 --> 1000        
-                         
- LogInterval(1,1024,11)  
-    i=0 --> 1            
-    i=1 --> 2            
-    i=2 --> 4            
-    i=3 --> 8            
-    i=4 --> 16           
-    i=5 --> 32           
-    i=6 --> 64           
-    i=7 --> 128          
-    i=8 --> 256          
-    i=9 --> 512          
-    i=10 --> 1024        
+    Example:
+ LogInterval(1,10000,5)
+     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!
+     i=1 --> 10                    StepSize(ibin=1) = 9
+     i=2 --> 100                   StepSize(ibin=2) = 99
+     i=3 --> 1000                  StepSize(ibin=3) = 999
+     i=4 --> 10000                 StepSize(ibin=4) = 9999
+
+ LogInterval(1,1000,11)
+    i=0 --> 1
+    i=1 --> 1.99526
+    i=2 --> 3.98107
+    i=3 --> 7.94328
+    i=4 --> 15.8489
+    i=5 --> 31.6228
+    i=6 --> 63.0957
+    i=7 --> 125.893
+    i=8 --> 251.189
+    i=9 --> 501.187
+    i=10 --> 1000
+
+ LogInterval(1,1024,11)
+    i=0 --> 1
+    i=1 --> 2
+    i=2 --> 4
+    i=3 --> 8
+    i=4 --> 16
+    i=5 --> 32
+    i=6 --> 64
+    i=7 --> 128
+    i=8 --> 256
+    i=9 --> 512
+    i=10 --> 1024
 
 
 </pre>
@@ -81,19 +81,16 @@ End_Html */
 
 ClassImp(TMVA::LogInterval)
 
-TMVA::MsgLogger* TMVA::LogInterval::fgLogger = 0;
 //_______________________________________________________________________
 TMVA::LogInterval::LogInterval( Double_t min, Double_t max, Int_t nbins ) :
 TMVA::Interval(min,max,nbins)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
    if (min<=0) Log() << kFATAL << "logarithmic intervals have to have Min>0 !!" << Endl;
 }
 
 TMVA::LogInterval::LogInterval( const LogInterval& other ) :
    TMVA::Interval(other)
 {
-   if (!fgLogger) fgLogger = new MsgLogger("LogInterval");
 }
 
 //_______________________________________________________________________
@@ -105,9 +102,9 @@ TMVA::LogInterval::~LogInterval()
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval. 
+   // calculates the value of the "number" bin in a discrete interval.
    // Parameters:
-   //        Double_t position 
+   //        Double_t position
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
@@ -123,7 +120,7 @@ Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::LogInterval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete LogInterval" 
+   // retuns the step size between the numbers of a "discrete LogInterval"
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
    }
@@ -141,12 +138,20 @@ Double_t TMVA::LogInterval::GetRndm( TRandom3& rnd )  const
    return TMath::Exp(rnd.Rndm()*(TMath::Log(fMax/fMin) - TMath::Log(fMin)) + TMath::Log(fMin));
 }
 
-Double_t TMVA::LogInterval::GetWidth() const 
-{ 
-   return fMax - fMin; 
+Double_t TMVA::LogInterval::GetWidth() const
+{
+   return fMax - fMin;
 }
-Double_t TMVA::LogInterval::GetMean()  const 
-{ 
-   return (fMax + fMin)/2; 
+Double_t TMVA::LogInterval::GetMean()  const
+{
+   return (fMax + fMin)/2;
 }
 
+TMVA::MsgLogger& TMVA::LogInterval::Log() const {
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("LogInterval");   // message logger
+#else
+  static MsgLogger logger("LogInterval");   // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/MethodANNBase.cxx b/tmva/src/MethodANNBase.cxx
index 0cc220816b585..ede12dc7d443b 100644
--- a/tmva/src/MethodANNBase.cxx
+++ b/tmva/src/MethodANNBase.cxx
@@ -40,6 +40,9 @@
 #include <vector>
 #include <cstdlib>
 #include <stdexcept>
+#if __cplusplus > 199711L
+#include <atomic>
+#endif
 
 #include "TString.h"
 #include "TTree.h"
@@ -980,13 +983,17 @@ void TMVA::MethodANNBase::WriteMonitoringHistosToFile() const
    CreateWeightMonitoringHists( "weights_hist" );
 
    // now save all the epoch-wise monitoring information
+#if __cplusplus > 199711L
+   static std::atomic<int> epochMonitoringDirectoryNumber{0};
+#else
    static int epochMonitoringDirectoryNumber = 0;
+#endif
+   int epochVal = epochMonitoringDirectoryNumber++;
    TDirectory* epochdir = NULL;
-   if( epochMonitoringDirectoryNumber == 0 )
+   if( epochVal == 0 )
       epochdir = BaseDir()->mkdir( "EpochMonitoring" );
    else
-      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochMonitoringDirectoryNumber) );
-   ++epochMonitoringDirectoryNumber;
+      epochdir = BaseDir()->mkdir( Form("EpochMonitoring_%4d",epochVal) );
 
    epochdir->cd();
    for (std::vector<TH1*>::const_iterator it = fEpochMonHistS.begin(); it != fEpochMonHistS.end(); it++) {
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index 99589d559eea2..71b7af726cd1a 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -2171,7 +2171,11 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmin = effhist->GetXaxis()->GetXmin();
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
+#if __cplusplus > 199711L
+   static thread_local Double_t nevtS;
+#else
    static Double_t nevtS;
+#endif
 
    // first round ? --> create histograms
    if (results->DoesExist("MVA_EFF_S")==0) {
@@ -3085,7 +3089,11 @@ void TMVA::MethodBase::PrintHelpMessage() const
 
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
+#if __cplusplus > 199711L
+thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
+#else
 TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
+#endif
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::IGetEffForRoot( Double_t theCut )
diff --git a/tmva/src/MethodCFMlpANN_Utils.cxx b/tmva/src/MethodCFMlpANN_Utils.cxx
index c35521acc8055..ecbdafb7b5eb4 100644
--- a/tmva/src/MethodCFMlpANN_Utils.cxx
+++ b/tmva/src/MethodCFMlpANN_Utils.cxx
@@ -72,12 +72,12 @@ using std::endl;
 
 ClassImp(TMVA::MethodCFMlpANN_Utils)
    
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
-Int_t       TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
-const char* TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_100         = 100;
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_0           = 0;
+const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nVar_   = max_nVar_;
+const Int_t       TMVA::MethodCFMlpANN_Utils::fg_max_nNodes_ = max_nNodes_;
+Int_t             TMVA::MethodCFMlpANN_Utils::fg_999         = 999;
+const char* const TMVA::MethodCFMlpANN_Utils::fg_MethodName  = "--- CFMlpANN                 ";
 
 TMVA::MethodCFMlpANN_Utils::MethodCFMlpANN_Utils()
 {
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 18797d2025370..9e4f58143e1b5 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -1583,8 +1583,13 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
    ((MethodMLP*)GetThisPtr())->FCN( npars, grad, f, fitPars, iflag );
 }
 
+#if __cplusplus > 199711L
+static thread_local Int_t  nc   = 0;
+static thread_local double minf = 1000000;
+#else
 static Int_t  nc   = 0;
 static double minf = 1000000;
+#endif
 
 void TMVA::MethodMLP::FCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t* fitPars, Int_t iflag )
 {
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 368b769728068..96d03cc58b61f 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -87,7 +87,11 @@ namespace TMVA {
    const Bool_t MethodPDERS_UseFindRoot = kFALSE;
 };
 
+#if __cplusplus > 199711L
+thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
+#else
 TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
+#endif
 
 REGISTER_METHOD(PDERS)
 
@@ -953,7 +957,11 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 
    // Caching jammed to disable function. 
    // It's not really useful afterall, badly implemented and untested :-)
+#if __cplusplus > 199711L
+   static thread_local Double_t ret = 1.0; 
+#else
    static Double_t ret = 1.0; 
+#endif
    
    if (ret != 0.0) return ret*pdf; 
 
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index 7027d4658c6a4..e6ee4baca6918 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -223,7 +223,11 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
 {
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
+#if __cplusplus > 199711L
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
+#else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
+#endif
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
       d[ivar] = (Double_t)ev->GetValue(ivar);
    }
@@ -412,8 +416,13 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
 
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
+#if __cplusplus > 199711L
+   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
+   static thread_local Int_t type;
+#else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
+#endif
 
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -442,7 +451,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
    Double_t* d = new Double_t[Data()->GetNVariables()] ; 
-   static Int_t type;
+   Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
    for (UInt_t ivar = 0; ivar<Data()->GetNVariables(); ivar++) {
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index 0018a579bc104..2160b5dfee708 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -153,7 +153,11 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
 
 
 
+#if __cplusplus > 199711L
+thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
+#else
 TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
+#endif
 
 //-------------------------------------------------------------------------------------------
 TMVA::kNN::ModulekNN::ModulekNN()
@@ -378,7 +382,11 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       return kFALSE;
    }
    
+#if __cplusplus > 199711L
+   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+#else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+#endif
 
    if (cit == fCount.end()) {
       cit = fCount.begin();
diff --git a/tmva/src/MsgLogger.cxx b/tmva/src/MsgLogger.cxx
index 5db9cfd190c93..86093c0189a53 100644
--- a/tmva/src/MsgLogger.cxx
+++ b/tmva/src/MsgLogger.cxx
@@ -40,20 +40,30 @@
 
 #include <assert.h>
 
+#include <memory>
+
 // ROOT include(s):
 
 ClassImp(TMVA::MsgLogger)
 
 // declaration of global variables
 // this is the hard-coded maximum length of the source names
-UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
-Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;
+const UInt_t                           TMVA::MsgLogger::fgMaxSourceSize = 25;
 
 const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
 const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
-std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
-std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
-Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;
+#if __cplusplus > 199711L
+std::atomic<Bool_t>                                       TMVA::MsgLogger::fgInhibitOutput{kFALSE};
+std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgTypeMap{0};
+std::atomic<const std::map<TMVA::EMsgType, std::string>*> TMVA::MsgLogger::fgColorMap{0};
+#else
+Bool_t                                       TMVA::MsgLogger::fgInhibitOutput = kFALSE;
+const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
+const std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
+#endif
+static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnTypeMap;
+static std::auto_ptr<const std::map<TMVA::EMsgType, std::string> > gOwnColorMap;
+ 
 
 void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
 void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
@@ -65,7 +75,6 @@ TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();   
 }
 
@@ -77,7 +86,6 @@ TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -89,7 +97,6 @@ TMVA::MsgLogger::MsgLogger( EMsgType minType )
      fMinType   ( minType )
 {
    // constructor
-   fgInstanceCounter++;
    InitMaps();
 }
 
@@ -101,7 +108,6 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
      fObjSource(0)
 {
    // copy constructor
-   fgInstanceCounter++;
    InitMaps();
    *this = parent;
 }
@@ -110,12 +116,6 @@ TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
 TMVA::MsgLogger::~MsgLogger()
 {
    // destructor
-   fgInstanceCounter--;
-   if (fgInstanceCounter == 0) {
-      // last MsgLogger instance has been deleted, can also delete the maps
-      delete fgTypeMap;  fgTypeMap  = 0;
-      delete fgColorMap; fgColorMap = 0;
-   }
 }
 
 //_______________________________________________________________________
@@ -202,14 +202,14 @@ void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
 
    std::map<EMsgType, std::string>::const_iterator stype;
 
-   if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
+   if ((stype = fgTypeMap.load()->find( type )) != fgTypeMap.load()->end()) {
       if (!gConfig().IsSilent() || type==kFATAL) {
          if (gConfig().UseColor()) {
             // no text for INFO or VERBOSE
             if (type == kINFO || type == kVERBOSE)
                std::cout << fgPrefix << line << std::endl; // no color for info
             else
-               std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
+ 	       std::cout << fgColorMap.load()->find( type )->second << fgPrefix << "<"
                          << stype->second << "> " << line  << "\033[0m" << std::endl;
          }
          else {
@@ -239,24 +239,45 @@ TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
 void TMVA::MsgLogger::InitMaps()
 {
    // Create the message type and color maps
-   if (fgTypeMap != 0 && fgColorMap != 0) return;
 
-   fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
-   fgColorMap = new std::map<TMVA::EMsgType, std::string>();
+   if(!fgTypeMap) {
+     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
    
-   (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
-   (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
-   (*fgTypeMap)[kINFO]     = std::string("INFO");
-   (*fgTypeMap)[kWARNING]  = std::string("WARNING");
-   (*fgTypeMap)[kERROR]    = std::string("ERROR");
-   (*fgTypeMap)[kFATAL]    = std::string("FATAL");
-   (*fgTypeMap)[kSILENT]   = std::string("SILENT");
-
-   (*fgColorMap)[kVERBOSE] = std::string("");
-   (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
-   (*fgColorMap)[kINFO]    = std::string("");
-   (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
-   (*fgColorMap)[kERROR]   = std::string("\033[31m");
-   (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
-   (*fgColorMap)[kSILENT]  = std::string("\033[30m");
+     (*tmp)[kVERBOSE]  = std::string("VERBOSE");
+     (*tmp)[kDEBUG]    = std::string("DEBUG");
+     (*tmp)[kINFO]     = std::string("INFO");
+     (*tmp)[kWARNING]  = std::string("WARNING");
+     (*tmp)[kERROR]    = std::string("ERROR");
+     (*tmp)[kFATAL]    = std::string("FATAL");
+     (*tmp)[kSILENT]   = std::string("SILENT");
+     const std::map<TMVA::EMsgType, std::string>* expected=0;
+     if(fgTypeMap.compare_exchange_strong(expected,tmp)) {
+       //Have the global own this
+       gOwnTypeMap.reset(tmp);
+     } else {
+       //Another thread beat us in creating the instance
+       delete tmp;
+     }
+   }
+
+   if(!fgColorMap) {
+     std::map<TMVA::EMsgType, std::string>*tmp  = new std::map<TMVA::EMsgType, std::string>();
+
+     (*tmp)[kVERBOSE] = std::string("");
+     (*tmp)[kDEBUG]   = std::string("\033[34m");
+     (*tmp)[kINFO]    = std::string("");
+     (*tmp)[kWARNING] = std::string("\033[1;31m");
+     (*tmp)[kERROR]   = std::string("\033[31m");
+     (*tmp)[kFATAL]   = std::string("\033[37;41;1m");
+     (*tmp)[kSILENT]  = std::string("\033[30m");
+
+     const std::map<TMVA::EMsgType, std::string>* expected=0;
+     if(fgColorMap.compare_exchange_strong(expected,tmp)) {
+       //Have the global own this
+       gOwnColorMap.reset(tmp);
+     } else {
+       //Another thread beat us in creating the instance
+       delete tmp;
+     }
+   }
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index b56c920e516a6..8f6bbf3d68e40 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -28,8 +28,6 @@
 
 #include "TMVA/Option.h"
 
-TMVA::MsgLogger* TMVA::OptionBase::fgLogger = 0;
-
 //______________________________________________________________________
 TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
    : TObject(), 
@@ -39,7 +37,6 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
      fIsSet       ( kFALSE )
 {
    // constructor
-   if (!fgLogger) fgLogger = new MsgLogger("Option",kDEBUG);
    fNameAllLower.ToLower();
 }
 
@@ -52,3 +49,12 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
    return kTRUE;
 }
 
+TMVA::MsgLogger& TMVA::OptionBase::Log()
+{
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
+#else
+  static MsgLogger logger("Option",kDEBUG);  // message logger
+#endif
+  return logger;
+}
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 3495c4d369f26..875ca43f4b04b 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -49,7 +49,11 @@
 const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
+#if __cplusplus > 199711L
+thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
+#else
 TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
+#endif
 
 ClassImp(TMVA::PDF)
 
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index f7506064c7e05..1099a9caa3ff1 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -51,13 +51,10 @@ using std::vector;
 
 ClassImp(TMVA::TNeuron)
 
-TMVA::MsgLogger* TMVA::TNeuron::fgLogger = 0;
-
 //______________________________________________________________________________
 TMVA::TNeuron::TNeuron()
 {
    // standard constructor
-   if (!fgLogger) fgLogger = new MsgLogger("TNeuron",kDEBUG);
    InitNeuron();
 }
 
@@ -334,3 +331,14 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
    // print message, for debugging
    Log() << type << message << Endl;
 }
+
+//______________________________________________________________________________
+TMVA::MsgLogger& TMVA::TNeuron::Log() const 
+{
+  #if __cplusplus > 199711L
+  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
+#else
+  static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
+#endif
+  return logger;
+}
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index da3c0a84646bc..ab03d79f8b173 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Matt Jachowski 
+// Author: Matt Jachowski
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -20,10 +20,10 @@
  * modification, are permitted according to the terms listed in LICENSE           *
  * (http://tmva.sourceforge.net/LICENSE)                                          *
  **********************************************************************************/
-   
+
 //_______________________________________________________________________
-//                                                                      
-// Synapse class used by TMVA artificial neural network methods      
+//
+// Synapse class used by TMVA artificial neural network methods
 //_______________________________________________________________________
 
 #include "TMVA/TSynapse.h"
@@ -40,8 +40,6 @@ static const Int_t fgUNINITIALIZED = -1;
 
 ClassImp(TMVA::TSynapse);
 
-TMVA::MsgLogger* TMVA::TSynapse::fgLogger = 0;
-
 //______________________________________________________________________________
 TMVA::TSynapse::TSynapse()
   : fWeight( 0 ),
@@ -54,7 +52,6 @@ TMVA::TSynapse::TSynapse()
 {
    // constructor
    fWeight     = fgUNINITIALIZED;
-   if (!fgLogger) fgLogger = new MsgLogger("TSynapse");
 }
 
 
@@ -75,7 +72,7 @@ void TMVA::TSynapse::SetWeight(Double_t weight)
 Double_t TMVA::TSynapse::GetWeightedValue()
 {
    // get output of pre-neuron weighted by synapse weight
-   if (fPreNeuron == NULL) 
+   if (fPreNeuron == NULL)
       Log() << kFATAL << "<GetWeightedValue> synapse not connected to neuron" << Endl;
 
    return (fWeight * fPreNeuron->GetActivationValue());
@@ -86,7 +83,7 @@ Double_t TMVA::TSynapse::GetWeightedDelta()
 {
    // get error field of post-neuron weighted by synapse weight
 
-   if (fPostNeuron == NULL) 
+   if (fPostNeuron == NULL)
       Log() << kFATAL << "<GetWeightedDelta> synapse not connected to neuron" << Endl;
 
    return fWeight * fPostNeuron->GetDelta();
@@ -108,3 +105,14 @@ void TMVA::TSynapse::CalculateDelta()
    fDelta += fPostNeuron->GetDelta() * fPreNeuron->GetActivationValue();
    fCount++;
 }
+
+//______________________________________________________________________________
+TMVA::MsgLogger& TMVA::TSynapse::Log() const
+{
+#if __cplusplus > 199711L
+  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
+#else
+  static MsgLogger logger("TSynapse");               //! message logger, static to save resources
+#endif
+  return logger;
+}
diff --git a/tmva/src/Tools.cxx b/tmva/src/Tools.cxx
index d968043eb668e..f00bfa3447f94 100644
--- a/tmva/src/Tools.cxx
+++ b/tmva/src/Tools.cxx
@@ -70,10 +70,37 @@
 
 using namespace std;
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Tools*> TMVA::Tools::fgTools{0};
+#else
 TMVA::Tools* TMVA::Tools::fgTools = 0;
+#endif
+
 TMVA::Tools& TMVA::gTools()                 { return TMVA::Tools::Instance(); }
-TMVA::Tools& TMVA::Tools::Instance()        { return fgTools?*(fgTools): *(fgTools = new Tools()); }
-void         TMVA::Tools::DestroyInstance() { if (fgTools != 0) { delete fgTools; fgTools=0; } }
+TMVA::Tools& TMVA::Tools::Instance()        {
+#if __cplusplus > 199711L
+  if(!fgTools) {
+    Tools* tmp = new Tools();
+    Tools* expected = 0;
+    if(! fgTools.compare_exchange_strong(expected,tmp)) {
+      //another thread beat us
+      delete tmp;
+    }
+  }
+  return *fgTools;
+#else
+  return fgTools?*(fgTools): *(fgTools = new Tools());
+#endif
+}
+void         TMVA::Tools::DestroyInstance() {
+  //NOTE: there is no thread safe way to do this so
+  // one must only call this method ones in an executable
+#if __cplusplus > 199711L
+  if (fgTools != 0) { delete fgTools.load(); fgTools=0; }
+#else
+  if (fgTools != 0) { delete fgTools; fgTools=0; }
+#endif
+}
 
 //_______________________________________________________________________
 TMVA::Tools::Tools() :
@@ -107,19 +134,19 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
    Double_t separation = 0;
 
    // sanity checks
-   // signal and background histograms must have same number of bins and 
+   // signal and background histograms must have same number of bins and
    // same limits
    if ((S->GetNbinsX() != B->GetNbinsX()) || (S->GetNbinsX() <= 0)) {
       Log() << kFATAL << "<GetSeparation> signal and background"
-            << " histograms have different number of bins: " 
+            << " histograms have different number of bins: "
             << S->GetNbinsX() << " : " << B->GetNbinsX() << Endl;
    }
 
-   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() || 
-       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() || 
+   if (S->GetXaxis()->GetXmin() != B->GetXaxis()->GetXmin() ||
+       S->GetXaxis()->GetXmax() != B->GetXaxis()->GetXmax() ||
        S->GetXaxis()->GetXmax() <= S->GetXaxis()->GetXmin()) {
-      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin() 
-            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax() 
+      Log() << kINFO << S->GetXaxis()->GetXmin() << " " << B->GetXaxis()->GetXmin()
+            << " " << S->GetXaxis()->GetXmax() << " " << B->GetXaxis()->GetXmax()
             << " " << S->GetXaxis()->GetXmax() << " " << S->GetXaxis()->GetXmin() << Endl;
       Log() << kFATAL << "<GetSeparation> signal and background"
             << " histograms have different or invalid dimensions:" << Endl;
@@ -140,7 +167,7 @@ Double_t TMVA::Tools::GetSeparation( TH1* S, TH1* B ) const
       separation *= intBin;
    }
    else {
-      Log() << kWARNING << "<GetSeparation> histograms with zero entries: " 
+      Log() << kWARNING << "<GetSeparation> histograms with zero entries: "
             << nS << " : " << nB << " cannot compute separation"
             << Endl;
       separation = 0;
@@ -186,11 +213,11 @@ void TMVA::Tools::ComputeStat( const std::vector<TMVA::Event*>& events, std::vec
                                Int_t signalClass, Bool_t  norm )
 {
    // sanity check
-   if (0 == valVec) 
+   if (0 == valVec)
       Log() << kFATAL << "<Tools::ComputeStat> value vector is zero pointer" << Endl;
-   
-   if ( events.size() != valVec->size() ) 
-      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths " 
+
+   if ( events.size() != valVec->size() )
+      Log() << kWARNING << "<Tools::ComputeStat> event and value vector have different lengths "
             << events.size() << "!=" << valVec->size() << Endl;
 
    Long64_t entries = valVec->size();
@@ -301,14 +328,14 @@ TMatrixD* TMVA::Tools::GetSQRootMatrix( TMatrixDSym* symMat )
 //_______________________________________________________________________
 const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
 {
-   // turns covariance into correlation matrix   
+   // turns covariance into correlation matrix
    if (covMat == 0) return 0;
 
    // sanity check
    Int_t nvar = covMat->GetNrows();
-   if (nvar != covMat->GetNcols()) 
+   if (nvar != covMat->GetNcols())
       Log() << kFATAL << "<GetCorrelationMatrix> input matrix not quadratic" << Endl;
-   
+
    TMatrixD* corrMat = new TMatrixD( nvar, nvar );
 
    for (Int_t ivar=0; ivar<nvar; ivar++) {
@@ -323,12 +350,12 @@ const TMatrixD* TMVA::Tools::GetCorrelationMatrix( const TMatrixD* covMat )
             }
             if (TMath::Abs( (*corrMat)(ivar,jvar))  > 1){
                Log() << kWARNING
-                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)  
+                     <<  " Element  corr("<<ivar<<","<<ivar<<")=" << (*corrMat)(ivar,jvar)
                      << " sigma2="<<d
                      << " cov("<<ivar<<","<<ivar<<")=" <<(*covMat)(ivar, ivar)
                      << " cov("<<jvar<<","<<jvar<<")=" <<(*covMat)(jvar, jvar)
-                     << Endl; 
-               
+                     << Endl;
+
             }
          }
          else (*corrMat)(ivar, ivar) = 1.0;
@@ -344,10 +371,10 @@ TH1* TMVA::Tools::projNormTH1F( TTree* theTree, const TString& theVarName,
                                 Double_t xmin, Double_t xmax, const TString& cut )
 {
    // projects variable from tree into normalised histogram
- 
+
    // needed because of ROOT bug (feature) that excludes events that have value == xmax
-   xmax += 0.00001; 
-   
+   xmax += 0.00001;
+
    TH1* hist = new TH1F( name, name, nbins, xmin, xmax );
    hist->Sumw2(); // enable quadratic errors
    theTree->Project( name, theVarName, cut );
@@ -390,11 +417,11 @@ TList* TMVA::Tools::ParseFormatLine( TString formatString, const char* sep )
       Ssiz_t posSep = formatString.First(sep);
       labelList->Add(new TObjString(TString(formatString(0,posSep)).Data()));
       formatString.Remove(0,posSep+1);
-      
+
       while (formatString.First(sep)==0) formatString.Remove(0,1); // remove additional separators
-      
+
    }
-   return labelList;                                                 
+   return labelList;
 }
 
 //_______________________________________________________________________
@@ -500,9 +527,9 @@ void TMVA::Tools::Scale( std::vector<Float_t>& v, Float_t f )
 
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::vector<TString>* vs ){
-   // sort 2D vector (AND in parallel a TString vector) in such a way 
+   // sort 2D vector (AND in parallel a TString vector) in such a way
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted. 
+   // in the same way as necessary to have the first vector sorted.
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -526,9 +553,9 @@ void TMVA::Tools::UsefulSortAscending( std::vector<vector<Double_t> >& v, std::v
 //_______________________________________________________________________
 void TMVA::Tools::UsefulSortDescending( std::vector<std::vector<Double_t> >& v, std::vector<TString>* vs )
 {
-   // sort 2D vector (AND in parallel a TString vector) in such a way 
+   // sort 2D vector (AND in parallel a TString vector) in such a way
    // that the "first vector is sorted" and the other vectors are reshuffled
-   // in the same way as necessary to have the first vector sorted. 
+   // in the same way as necessary to have the first vector sorted.
    // I.e. the correlation between the elements is kept.
    UInt_t nArrays=v.size();
    Double_t temp;
@@ -556,13 +583,13 @@ Double_t TMVA::Tools::GetMutualInformation( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0) return -1; 
+   if (hi == 0) return -1;
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
-   
+
    Double_t mutualInfo = 0.;
    Int_t maxBinX = h.GetNbinsX();
    Int_t maxBinY = h.GetNbinsY();
@@ -587,14 +614,14 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
    // Author: Moritz Backes, Geneva (2009)
 
    Double_t hi = h_.Integral();
-   if (hi == 0.) return -1; 
+   if (hi == 0.) return -1;
 
    // copy histogram and rebin to speed up procedure
    TH2F h( h_ );
    h.RebinX(2);
    h.RebinY(2);
 
-   Double_t corrRatio = 0.;    
+   Double_t corrRatio = 0.;
    Double_t y_mean = h.ProjectionY()->GetMean();
    for (Int_t ix=1; ix<=h.GetNbinsX(); ix++) {
       corrRatio += (h.Integral(ix,ix,1,h.GetNbinsY())/hi)*pow((GetYMean_binX(h,ix)-y_mean),2);
@@ -607,7 +634,7 @@ Double_t TMVA::Tools::GetCorrelationRatio( const TH2F& h_ )
 Double_t TMVA::Tools::GetYMean_binX( const TH2& h, Int_t bin_x )
 {
    // Compute the mean in Y for a given bin X of a 2D histogram
- 
+
    if (h.Integral(bin_x,bin_x,1,h.GetNbinsY()) == 0.) {return 0;}
    Double_t y_bin_mean = 0.;
    TH1* py = h.ProjectionY();
@@ -627,8 +654,8 @@ TH2F* TMVA::Tools::TransposeHist( const TH2F& h )
    if (h.GetNbinsX() != h.GetNbinsY()) {
       Log() << kFATAL << "<TransposeHist> cannot transpose non-quadratic histogram" << Endl;
    }
-   
-   TH2F *transposedHisto = new TH2F( h ); 
+
+   TH2F *transposedHisto = new TH2F( h );
    for (Int_t ix=1; ix <= h.GetNbinsX(); ix++){
       for (Int_t iy=1; iy <= h.GetNbinsY(); iy++){
          transposedHisto->SetBinContent(iy,ix,h.GetBinContent(ix,iy));
@@ -658,8 +685,8 @@ Bool_t TMVA::Tools::CheckForSilentOption( const TString& cs ) const
    // check for "silence" option in configuration option string
    Bool_t isSilent = kFALSE;
 
-   TString s( cs ); 
-   s.ToLower(); 
+   TString s( cs );
+   s.ToLower();
    s.ReplaceAll(" ","");
    if (s.Contains("silent") && !s.Contains("silent=f")) {
       if (!s.Contains("!silent") || s.Contains("silent=t")) isSilent = kTRUE;
@@ -674,8 +701,8 @@ Bool_t TMVA::Tools::CheckForVerboseOption( const TString& cs ) const
    // check if verbosity "V" set in option
    Bool_t isVerbose = kFALSE;
 
-   TString s( cs ); 
-   s.ToLower(); 
+   TString s( cs );
+   s.ToLower();
    s.ReplaceAll(" ","");
    std::vector<TString> v = SplitString( s, ':' );
    for (std::vector<TString>::iterator it = v.begin(); it != v.end(); it++) {
@@ -739,27 +766,27 @@ Int_t TMVA::Tools::GetIndexMinElement( std::vector<Double_t>& v )
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )  
+Bool_t TMVA::Tools::ContainsRegularExpression( const TString& s )
 {
    // check if regular expression
    // helper function to search for "$!%^&()'<>?= " in a string
 
    Bool_t  regular = kFALSE;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
       if (s.Contains( Tools::fRegexp[i] )) { regular = kTRUE; break; }
 
    return regular;
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )  
+TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString& r )
 {
    // replace regular expressions
    // helper function to remove all occurences "$!%^&()'<>?= " from a string
    // and replace all ::,$,*,/,+,- with _M_,_S_,_T_,_D_,_P_,_M_ respectively
 
    TString snew = s;
-   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++) 
+   for (Int_t i = 0; i < Tools::fRegexp.Length(); i++)
       snew.ReplaceAll( Tools::fRegexp[i], r );
 
    snew.ReplaceAll( "::", r );
@@ -784,56 +811,56 @@ TString TMVA::Tools::ReplaceRegularExpressions( const TString& s, const TString&
 }
 
 //_______________________________________________________________________
-const TString& TMVA::Tools::Color( const TString& c ) 
+const TString& TMVA::Tools::Color( const TString& c )
 {
    // human readable color strings
-   static TString gClr_none         = "" ;
-   static TString gClr_white        = "\033[1;37m";  // white
-   static TString gClr_black        = "\033[30m";    // black
-   static TString gClr_blue         = "\033[34m";    // blue
-   static TString gClr_red          = "\033[1;31m" ; // red
-   static TString gClr_yellow       = "\033[1;33m";  // yellow
-   static TString gClr_darkred      = "\033[31m";    // dark red
-   static TString gClr_darkgreen    = "\033[32m";    // dark green
-   static TString gClr_darkyellow   = "\033[33m";    // dark yellow
-                                    
-   static TString gClr_bold         = "\033[1m"    ; // bold 
-   static TString gClr_black_b      = "\033[30m"   ; // bold black
-   static TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
-   static TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
-   static TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
-                                    
-   static TString gClr_blue_bg      = "\033[44m";    // blue background
-   static TString gClr_red_bg       = "\033[1;41m";  // white on red background
-   static TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
-   static TString gClr_whiteongreen = "\033[1;42m";  // white on green background
-   static TString gClr_grey_bg      = "\033[47m";    // grey background
-
-   static TString gClr_reset  = "\033[0m";     // reset
+   static const TString gClr_none         = "" ;
+   static const TString gClr_white        = "\033[1;37m";  // white
+   static const TString gClr_black        = "\033[30m";    // black
+   static const TString gClr_blue         = "\033[34m";    // blue
+   static const TString gClr_red          = "\033[1;31m" ; // red
+   static const TString gClr_yellow       = "\033[1;33m";  // yellow
+   static const TString gClr_darkred      = "\033[31m";    // dark red
+   static const TString gClr_darkgreen    = "\033[32m";    // dark green
+   static const TString gClr_darkyellow   = "\033[33m";    // dark yellow
+
+   static const TString gClr_bold         = "\033[1m"    ; // bold
+   static const TString gClr_black_b      = "\033[30m"   ; // bold black
+   static const TString gClr_lblue_b      = "\033[1;34m" ; // bold light blue
+   static const TString gClr_cyan_b       = "\033[0;36m" ; // bold cyan
+   static const TString gClr_lgreen_b     = "\033[1;32m";  // bold light green
+
+   static const TString gClr_blue_bg      = "\033[44m";    // blue background
+   static const TString gClr_red_bg       = "\033[1;41m";  // white on red background
+   static const TString gClr_whiteonblue  = "\033[1;44m";  // white on blue background
+   static const TString gClr_whiteongreen = "\033[1;42m";  // white on green background
+   static const TString gClr_grey_bg      = "\033[47m";    // grey background
+
+   static const TString gClr_reset  = "\033[0m";     // reset
 
    if (!gConfig().UseColor()) return gClr_none;
 
-   if (c == "white" )         return gClr_white; 
-   if (c == "blue"  )         return gClr_blue; 
-   if (c == "black"  )        return gClr_black; 
+   if (c == "white" )         return gClr_white;
+   if (c == "blue"  )         return gClr_blue;
+   if (c == "black"  )        return gClr_black;
    if (c == "lightblue")      return gClr_cyan_b;
-   if (c == "yellow")         return gClr_yellow; 
-   if (c == "red"   )         return gClr_red; 
-   if (c == "dred"  )         return gClr_darkred; 
-   if (c == "dgreen")         return gClr_darkgreen; 
+   if (c == "yellow")         return gClr_yellow;
+   if (c == "red"   )         return gClr_red;
+   if (c == "dred"  )         return gClr_darkred;
+   if (c == "dgreen")         return gClr_darkgreen;
    if (c == "lgreenb")        return gClr_lgreen_b;
-   if (c == "dyellow")        return gClr_darkyellow; 
+   if (c == "dyellow")        return gClr_darkyellow;
+
+   if (c == "bold")           return gClr_bold;
+   if (c == "bblack")         return gClr_black_b;
 
-   if (c == "bold")           return gClr_bold; 
-   if (c == "bblack")         return gClr_black_b; 
+   if (c == "blue_bgd")       return gClr_blue_bg;
+   if (c == "red_bgd" )       return gClr_red_bg;
 
-   if (c == "blue_bgd")       return gClr_blue_bg; 
-   if (c == "red_bgd" )       return gClr_red_bg; 
- 
-   if (c == "white_on_blue" ) return gClr_whiteonblue; 
-   if (c == "white_on_green") return gClr_whiteongreen; 
+   if (c == "white_on_blue" ) return gClr_whiteonblue;
+   if (c == "white_on_green") return gClr_whiteongreen;
 
-   if (c == "reset") return gClr_reset; 
+   if (c == "reset") return gClr_reset;
 
    std::cout << "Unknown color " << c << std::endl;
    exit(1);
@@ -842,7 +869,7 @@ const TString& TMVA::Tools::Color( const TString& c )
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V, 
+void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const std::vector<TString>& V,
                                    const TString titleVars, const TString titleValues, MsgLogger& logger,
                                    TString format )
 {
@@ -851,7 +878,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    // sanity check
    UInt_t nvar = V.size();
    if ((UInt_t)values.size() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
              << values.size() << " OR " << " != " << nvar << Endl;
    }
 
@@ -872,7 +899,7 @@ void TMVA::Tools::FormattedOutput( const std::vector<Double_t>& values, const st
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL) << titleVars << ":";
    logger << setw(maxV+1) << titleValues << ":";
    logger << Endl;
@@ -899,11 +926,11 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    // sanity check: matrix must be quadratic
    UInt_t nvar = V.size();
    if ((UInt_t)M.GetNcols() != nvar || (UInt_t)M.GetNrows() != nvar) {
-      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: " 
+      logger << kFATAL << "<FormattedOutput> fatal error with dimensions: "
              << M.GetNcols() << " OR " << M.GetNrows() << " != " << nvar << " ==> abort" << Endl;
    }
 
-   // get length of each variable, and maximum length  
+   // get length of each variable, and maximum length
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -911,7 +938,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       vLengths.push_back(TMath::Max( (UInt_t)V[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-   
+
    // count column length
    UInt_t clen = maxL+1;
    for (UInt_t icol=0; icol<nvar; icol++) clen += vLengths[icol]+1;
@@ -920,7 +947,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nvar; icol++) logger << setw(vLengths[icol]+1) << V[icol];
    logger << Endl;
@@ -930,7 +957,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
       logger << setw(maxL) << V[irow] << ":";
       for (UInt_t icol=0; icol<nvar; icol++) {
          logger << setw(vLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }      
+      }
       logger << Endl;
    }
 
@@ -940,17 +967,17 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M, const std::vector<TString>
 }
 
 //_______________________________________________________________________
-void TMVA::Tools::FormattedOutput( const TMatrixD& M, 
-                                   const std::vector<TString>& vert, const std::vector<TString>& horiz, 
+void TMVA::Tools::FormattedOutput( const TMatrixD& M,
+                                   const std::vector<TString>& vert, const std::vector<TString>& horiz,
                                    MsgLogger& logger )
 {
    // formatted output of matrix (with labels)
 
    // sanity check: matrix must be quadratic
-   UInt_t nvvar = vert.size();   
+   UInt_t nvvar = vert.size();
    UInt_t nhvar = horiz.size();
 
-   // get length of each variable, and maximum length  
+   // get length of each variable, and maximum length
    UInt_t minL = 7;
    UInt_t maxL = minL;
    std::vector<UInt_t> vLengths;
@@ -958,7 +985,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       vLengths.push_back(TMath::Max( (UInt_t)vert[ivar].Length(), minL ));
       maxL = TMath::Max( vLengths.back(), maxL );
    }
-   
+
    // count column length
    UInt_t minLh = 7;
    UInt_t maxLh = minLh;
@@ -975,7 +1002,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
    for (UInt_t i=0; i<clen; i++) logger << "-";
    logger << Endl;
 
-   // title bar   
+   // title bar
    logger << setw(maxL+1) << " ";
    for (UInt_t icol=0; icol<nhvar; icol++) logger << setw(hLengths[icol]+1) << horiz[icol];
    logger << Endl;
@@ -985,7 +1012,7 @@ void TMVA::Tools::FormattedOutput( const TMatrixD& M,
       logger << setw(maxL) << vert[irow] << ":";
       for (UInt_t icol=0; icol<nhvar; icol++) {
          logger << setw(hLengths[icol]+1) << Form( "%+1.3f", M(irow,icol) );
-      }      
+      }
       logger << Endl;
    }
 
@@ -1073,7 +1100,7 @@ void TMVA::Tools::AddAttr( void* node, const char* attrname, const char* value )
 }
 
 //_______________________________________________________________________
-void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode ) 
+void* TMVA::Tools::AddChild( void* parent, const char* childname, const char* content, bool isRootNode )
 {
    // add child node
    if( !isRootNode && parent == 0 ) return 0;
@@ -1090,7 +1117,7 @@ void* TMVA::Tools::GetParent( void* child)
 {
    // get parent node
    void* par = xmlengine().GetParent(child);
-   
+
    return par;
 }
 //_______________________________________________________________________
@@ -1161,7 +1188,7 @@ std::vector<TString> TMVA::Tools::SplitString(const TString& theOpt, const char
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromInt( Long_t i ) 
+TString TMVA::Tools::StringFromInt( Long_t i )
 {
    // string tools
    std::stringstream s;
@@ -1170,7 +1197,7 @@ TString TMVA::Tools::StringFromInt( Long_t i )
 }
 
 //_______________________________________________________________________
-TString TMVA::Tools::StringFromDouble( Double_t d ) 
+TString TMVA::Tools::StringFromDouble( Double_t d )
 {
    // string tools
    std::stringstream s;
@@ -1250,7 +1277,7 @@ void TMVA::Tools::TMVAWelcomeMessage()
 void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 {
    // prints the TMVA release number and date
-   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE 
+   logger << "___________TMVA Version " << TMVA_RELEASE << ", " << TMVA_RELEASE_DATE
           << "" << Endl;
 }
 
@@ -1258,10 +1285,10 @@ void TMVA::Tools::TMVAVersionMessage( MsgLogger& logger )
 void TMVA::Tools::ROOTVersionMessage( MsgLogger& logger )
 {
    // prints the ROOT release number and date
-   static const char *months[] = { "Jan","Feb","Mar","Apr","May",
+   static const char * const months[] = { "Jan","Feb","Mar","Apr","May",
                                    "Jun","Jul","Aug","Sep","Oct",
                                    "Nov","Dec" };
-   Int_t   idatqq = gROOT->GetVersionDate();   
+   Int_t   idatqq = gROOT->GetVersionDate();
    Int_t   iday   = idatqq%100;
    Int_t   imonth = (idatqq/100)%100;
    Int_t   iyear  = (idatqq/10000);
@@ -1342,27 +1369,27 @@ void TMVA::Tools::TMVAWelcomeMessage( MsgLogger& logger, EWelcomeMessage msgType
       break;
 
    case kOriginalWelcomeMsgColor:
-      logger << kINFO << "" << Color("red") 
+      logger << kINFO << "" << Color("red")
              << "_______________________________________" << Color("reset") << Endl;
       logger << kINFO << "" << Color("blue")
              << Color("red_bgd") << Color("bwhite") << " // " << Color("reset")
-             << Color("white") << Color("blue_bgd") 
+             << Color("white") << Color("blue_bgd")
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Color("reset") << Endl;
       logger << kINFO << ""<< Color("blue")
              << Color("red_bgd") << Color("white") << "//  " << Color("reset")
-             << Color("white") << Color("blue_bgd") 
+             << Color("white") << Color("blue_bgd")
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Color("reset") << Endl;
       break;
-      
+
    case kOriginalWelcomeMsgBW:
-      logger << kINFO << "" 
+      logger << kINFO << ""
              << "_______________________________________" << Endl;
       logger << kINFO << " // "
              << "|\\  /|| \\  //  /\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\ " << Endl;
-      logger << kINFO << "//  " 
+      logger << kINFO << "//  "
              << "| \\/ ||  \\//  /--\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\ \\" << Endl;
       break;
-      
+
    default:
       logger << kFATAL << "unknown message type: " << msgType << Endl;
    }
@@ -1407,11 +1434,11 @@ void TMVA::Tools::TMVACitation( MsgLogger& logger, ECitation citType )
 
    case kHtmlLink:
       logger << kINFO << "  " << Endl;
-      logger << kINFO << gTools().Color("bold") 
+      logger << kINFO << gTools().Color("bold")
              << "Thank you for using TMVA!" << gTools().Color("reset") << Endl;
-      logger << kINFO << gTools().Color("bold") 
+      logger << kINFO << gTools().Color("bold")
              << "For citation information, please visit: http://tmva.sf.net/citeTMVA.html"
-             << gTools().Color("reset") << Endl; 
+             << gTools().Color("reset") << Endl;
    }
 }
 
@@ -1450,7 +1477,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
    }
 
    UInt_t nvars=0, ntgts=0, nspcts=0;
-   if (transformBase) 
+   if (transformBase)
       transformBase->CountVariableTypes( nvars, ntgts, nspcts );
    else {
       nvars =events.at(0)->GetNVariables ();
@@ -1504,7 +1531,7 @@ TMVA::Tools::CalcCovarianceMatrices( const std::vector<Event*>& events, Int_t ma
             input.push_back (ev->GetValue(ivar));
          }
       }
-       
+
       if (maxCls > 1) {
          v = vec->at(matNum-1);
          m = mat2->at(matNum-1);
@@ -1576,7 +1603,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    int i = 0;
    if (w==NULL)
    {
-      while ( first != last ) 
+      while ( first != last )
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1594,7 +1621,7 @@ Double_t TMVA::Tools::Mean ( Iterator first,  Iterator last,  WeightIterator w)
    }
    else
    {
-      while ( first != last ) 
+      while ( first != last )
       {
          // if ( *w < 0) {
          //    ::Error("TMVA::Tools::Mean","w[%d] = %.4e < 0 ?!",i,*w);
@@ -1642,7 +1669,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble; 
+         sum  += adouble;
          sum2 += adouble*adouble;
          sumw += 1.0;
          ++first;
@@ -1652,7 +1679,7 @@ Double_t TMVA::Tools::RMS(Iterator first, Iterator last, WeightIterator w)
    {
       while ( first != last ) {
          adouble=Double_t(*first);
-         sum  += adouble * (*w); 
+         sum  += adouble * (*w);
          sum2 += adouble*adouble * (*w);
          sumw += (*w);
          ++first;
@@ -1688,7 +1715,7 @@ TH1* TMVA::Tools::GetCumulativeDist( TH1* h)
 
    Float_t partialSum = 0;
    Float_t inverseSum = 0.;
-   
+
    Float_t val;
    for (Int_t ibinEnd=1, ibin=cumulativeDist->GetNbinsX(); ibin >=ibinEnd ; ibin--){
       val = cumulativeDist->GetBinContent(ibin);
diff --git a/tmva/src/Types.cxx b/tmva/src/Types.cxx
index 6d8d060b38bde..88701c8f410f5 100644
--- a/tmva/src/Types.cxx
+++ b/tmva/src/Types.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$   
+// @(#)root/tmva $Id$
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      U. of Victoria, Canada                                                    * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      U. of Victoria, Canada                                                    *
+ *      MPI-K Heidelberg, Germany                                                 *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
  * modification, are permitted according to the terms listed in LICENSE           *
@@ -27,11 +27,19 @@
 
 #include <map>
 #include <iostream>
+#if __cplusplus > 199711L
+#include <mutex>
+#endif
 
 #include "TMVA/Types.h"
 #include "TMVA/MsgLogger.h"
 
+#if __cplusplus > 199711L
+std::atomic<TMVA::Types*> TMVA::Types::fgTypesPtr{0};
+static std::mutex gTypesMutex;
+#else
 TMVA::Types* TMVA::Types::fgTypesPtr = 0;
+#endif
 
 //_______________________________________________________________________
 TMVA::Types::Types()
@@ -40,33 +48,52 @@ TMVA::Types::Types()
    // constructor
 }
 
-TMVA::Types::~Types() 
+TMVA::Types::~Types()
 {
    // destructor
    delete fLogger;
 }
 
 //_______________________________________________________________________
-TMVA::Types& TMVA::Types::Instance() 
-{ 
-   // the the single instance of "Types" if existin already, or create it  (Signleton) 
-   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types()); 
+TMVA::Types& TMVA::Types::Instance()
+{
+   // the the single instance of "Types" if existin already, or create it  (Signleton)
+#if __cplusplus > 199711L
+  if(!fgTypesPtr) {
+    Types* tmp = new Types();
+    Types* expected = 0;
+    if(!fgTypesPtr.compare_exchange_strong(expected,tmp)) {
+      //Another thread already did it
+      delete tmp;
+    }
+  }
+  return *fgTypesPtr;
+#else
+   return fgTypesPtr ? *fgTypesPtr : *(fgTypesPtr = new Types());
+#endif
 }
 //_______________________________________________________________________
-void   TMVA::Types::DestroyInstance() 
-{ 
+void   TMVA::Types::DestroyInstance()
+{
    // "destructor" of the single instance
-   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; } 
+#if __cplusplus > 199711L
+   if (fgTypesPtr != 0) { delete fgTypesPtr.load(); fgTypesPtr = 0; }
+#else
+   if (fgTypesPtr != 0) { delete fgTypesPtr; fgTypesPtr = 0; }
+#endif
 }
 
 
 //_______________________________________________________________________
-Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname ) 
+Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodname )
 {
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( methodname );
    if (it != fStr2type.end()) {
-      Log() << kFATAL 
-            << "Cannot add method " << methodname 
+      Log() << kFATAL
+            << "Cannot add method " << methodname
             << " to the name->type map because it exists already" << Endl;
       return kFALSE;
    }
@@ -76,8 +103,11 @@ Bool_t TMVA::Types::AddTypeMapping( Types::EMVA method, const TString& methodnam
 }
 
 //_______________________________________________________________________
-TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const 
-{ 
+TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
+{
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    // returns the method type (enum) for a given method (string)
    std::map<TString, EMVA>::const_iterator it = fStr2type.find( method );
    if (it == fStr2type.end()) {
@@ -88,8 +118,11 @@ TMVA::Types::EMVA TMVA::Types::GetMethodType( const TString& method ) const
 }
 
 //_______________________________________________________________________
-TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const 
+TString TMVA::Types::GetMethodName( TMVA::Types::EMVA method ) const
 {
+#if __cplusplus > 199711L
+   std::lock_guard<std::mutex> guard(gTypesMutex);
+#endif
    std::map<TString, EMVA>::const_iterator it = fStr2type.begin();
    for (; it!=fStr2type.end(); it++) if (it->second == method) return it->first;
    Log() << kFATAL << "Unknown method index in map: " << method << Endl;

From 2a57913ede8b0cafeaa7d769ce340710ca419ef5 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 6 Mar 2015 10:01:24 +0100
Subject: [PATCH 166/200] Revert "Revert "Stress the MT features of the Reader
 class with a new unit test""

Re-activate the TMVA mt test.

This reverts commit 13811582640c3f4acb718d4841f554820e0f43be.
---
 test/stressTMVA.cxx | 132 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 3 deletions(-)

diff --git a/test/stressTMVA.cxx b/test/stressTMVA.cxx
index cdb7e397f6ba4..ea488b6f2fcbc 100644
--- a/test/stressTMVA.cxx
+++ b/test/stressTMVA.cxx
@@ -60,6 +60,7 @@ Regression_BDTG2 [4/4]...........................................OK
 *  CPUTIME   =  90.2   *  Root5.27/07   20100929/1318
 ******************************************************************
 */
+#include "TThread.h"
 // including file tmvaut/UnitTest.h
 #ifndef UNITTEST_H
 #define UNITTEST_H
@@ -70,6 +71,7 @@ Regression_BDTG2 [4/4]...........................................OK
 #include <string>
 #include <iostream>
 #include <cassert>
+#include <atomic>
 
 // The following have underscores because
 // they are macros. For consistency,
@@ -104,8 +106,8 @@ namespace UnitTesting
       bool floatCompare(float x1, float x2);
    private:
       std::ostream* osptr;
-      long nPass;
-      long nFail;
+      std::atomic<long> nPass;
+      std::atomic<long> nFail;
       mutable std::string fName;
       std::string fFileName;
       // Disallowed:
@@ -207,7 +209,7 @@ long UnitTest::report() const
 {
    if (osptr)
       {
-         std::string counts(Form(" [%li/%li]", nPass, nPass+nFail));
+         std::string counts(Form(" [%li/%li]", nPass.load(), nPass+nFail));
 
          *osptr << name() << counts;
 
@@ -1292,6 +1294,128 @@ void utReader::run()
    reader[2]->EvaluateMVA( "LD method");
    test_(1>0);
 }
+#ifndef UTREADERMT_H
+#define UTREADERMT_H
+
+// Author: D. Piparo, 2015
+// TMVA unit tests
+//
+// this class acts as interface to several reader applications in MT mode
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <vector>
+#include <thread>
+
+#include "TTree.h"
+#include "TString.h"
+
+#include "TMVA/Reader.h"
+#include "TMVA/Types.h"
+
+
+
+namespace UnitTesting
+{
+  class utReaderMT : public UnitTest
+  {
+  public:
+    utReaderMT(const char* theOption="");
+    virtual ~utReaderMT();
+
+    virtual void run();
+
+  protected:
+
+  private:
+     // disallow copy constructor and assignment
+     utReaderMT(const utReaderMT&);
+     utReaderMT& operator=(const utReaderMT&);
+  };
+} // namespace UnitTesting
+#endif //
+
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+#include "TTree.h"
+#include "TString.h"
+
+#include "TMVA/Reader.h"
+#include "TMVA/Types.h"
+
+
+
+using namespace std;
+using namespace UnitTesting;
+using namespace TMVA;
+
+utReaderMT::utReaderMT(const char* /*theOption*/)
+   : UnitTest(string("Reader"))
+{
+
+}
+utReaderMT::~utReaderMT(){ }
+
+void utReaderMT::run()
+{
+   auto runSingleReader = [&] () {
+      float xtest,xtest2;
+      Reader* reader2 = new Reader();
+      Reader* reader3 = new Reader();
+      reader2->AddVariable("test", &xtest);
+      reader2->AddVariable("test2", &xtest2);
+      reader3->AddVariable("test", &xtest);
+
+      delete reader2;
+      delete reader3;
+      test_(1>0);
+      const int nTest=3;
+      int ievt;
+      vector<float> testvar(10);
+      std::vector< TMVA::Reader* > reader(nTest);
+      for (int iTest=0;iTest<nTest;iTest++){
+         reader[iTest] = new TMVA::Reader( "!Color:Silent" );
+         if (iTest==0){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest_LD.weights.xml") ;
+         }
+         if (iTest==1){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3Var_LD.weights.xml") ;
+         }
+         if (iTest==2){
+            reader[iTest]->AddVariable( "var0" ,&testvar[0]);
+            reader[iTest]->AddVariable( "var1" ,&testvar[1]);
+            reader[iTest]->AddVariable( "var2" ,&testvar[2]);
+            reader[iTest]->AddVariable( "ivar0" ,&testvar[3]);
+            reader[iTest]->AddVariable( "ivar1" ,&testvar[4]);
+            reader[iTest]->AddSpectator( "ievt" ,&ievt);
+            reader[iTest]->BookMVA( "LD method", "weights/TMVATest3VarF2VarI_LD.weights.xml") ;
+         }
+      }
+      reader[0]->EvaluateMVA( "LD method");
+      reader[1]->EvaluateMVA( "LD method");
+      reader[2]->EvaluateMVA( "LD method");
+      test_(1>0);
+   };
+   for (int j=0;j<5;++j){ // challenge non reproducibility repeating the loop
+      vector<thread> threads;
+      for (int i=0;i<10;++i) threads.emplace_back(runSingleReader);
+      for (auto&& t : threads) t.join();
+   }
+
+}
+
 // including file tmvaut/utFactory.h
 #ifndef UTFACTORY_H
 #define UTFACTORY_H
@@ -2883,6 +3007,7 @@ int main(int argc, char **argv)
    TMVA_test.addTest(new utDataSet);
    TMVA_test.addTest(new utFactory);
    TMVA_test.addTest(new utReader);
+   TMVA_test.addTest(new utReaderMT);
 
    addClassificationTests(TMVA_test, full);
    addRegressionTests(TMVA_test, full);
@@ -2890,6 +3015,7 @@ int main(int argc, char **argv)
    addComplexClassificationTests(TMVA_test, full);
 
    // run all
+   TThread::Initialize();
    TMVA_test.run();
 
 #ifdef COUTDEBUG

From c1c48a0f3400aa65698b4a28327717e183a4406a Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 6 Mar 2015 11:33:28 +0100
Subject: [PATCH 167/200] Correct name of the mt Reader test into ReaderMT

---
 test/stressTMVA.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/stressTMVA.cxx b/test/stressTMVA.cxx
index ea488b6f2fcbc..0612ef8dd4e99 100644
--- a/test/stressTMVA.cxx
+++ b/test/stressTMVA.cxx
@@ -1355,7 +1355,7 @@ using namespace UnitTesting;
 using namespace TMVA;
 
 utReaderMT::utReaderMT(const char* /*theOption*/)
-   : UnitTest(string("Reader"))
+   : UnitTest(string("ReaderMT"))
 {
 
 }

From cda90f7b054ac525e16d241aad347be55c0122e5 Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Fri, 6 Mar 2015 11:36:49 +0100
Subject: [PATCH 168/200] Adapt the TMVA patch to work on osx

the static thread_local class data members are indeed not supported
on that platform.
---
 tmva/inc/TMVA/BDTEventWrapper.h |  40 +++----
 tmva/inc/TMVA/MethodBase.h      |  32 +++---
 tmva/inc/TMVA/MethodPDERS.h     |  10 +-
 tmva/inc/TMVA/ModulekNN.h       |  10 +-
 tmva/inc/TMVA/PDF.h             |   9 +-
 tmva/src/BDTEventWrapper.cxx    |  18 +--
 tmva/src/BinaryTree.cxx         |  10 +-
 tmva/src/DecisionTreeNode.cxx   |   2 +-
 tmva/src/Interval.cxx           |  36 +++---
 tmva/src/LogInterval.cxx        |   2 +-
 tmva/src/MethodBase.cxx         | 196 ++++++++++++++++----------------
 tmva/src/MethodMLP.cxx          |  46 ++++----
 tmva/src/MethodPDERS.cxx        |  67 +++++------
 tmva/src/MethodTMlpANN.cxx      |  26 ++---
 tmva/src/ModulekNN.cxx          | 154 ++++++++++++-------------
 tmva/src/Option.cxx             |  22 ++--
 tmva/src/PDF.cxx                |  12 +-
 tmva/src/TNeuron.cxx            |  10 +-
 tmva/src/TSynapse.cxx           |   2 +-
 19 files changed, 333 insertions(+), 371 deletions(-)

diff --git a/tmva/inc/TMVA/BDTEventWrapper.h b/tmva/inc/TMVA/BDTEventWrapper.h
index cc3d0ae17814e..9757596892723 100644
--- a/tmva/inc/TMVA/BDTEventWrapper.h
+++ b/tmva/inc/TMVA/BDTEventWrapper.h
@@ -5,9 +5,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *  
- *                                                                                *  
- *                                                                                *  
+ * Description:                                                                   *
+ *                                                                                *
+ *                                                                                *
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
@@ -27,62 +27,62 @@
 #endif
 
 namespace TMVA {
-  
+
    class BDTEventWrapper{
 
    public:
 
       BDTEventWrapper( const Event* );
       ~BDTEventWrapper();
-    
+
       // Require '<' operator to use std::sort algorithms on collection of Events
       Bool_t operator <( const BDTEventWrapper& other ) const;
-    
+
       // Set the accumulated weight, for sorted signal/background events
       /**
        * @param fType - true for signal, false for background
        * @param weight - the total weight
        */
       void SetCumulativeWeight( Bool_t type, Double_t weight );
-    
+
       // Get the accumulated weight
       /**
        * @param fType - true for signal, false for background
        * @return the cumulative weight for sorted signal/background events
        */
       Double_t GetCumulativeWeight( Bool_t type ) const;
-    
+
       // Set the index of the variable to compare on
       /**
        * @param iVar - index of the variable in fEvent to use
        */
-      inline static void SetVarIndex( Int_t iVar ) { if (iVar >= 0) fVarIndex = iVar; }
-    
+      inline static void SetVarIndex( Int_t iVar ) { if (iVar >= 0) GetVarIndex() = iVar; }
+
       // Return the value of variable fVarIndex for this event
       /**
        * @return value of variable fVarIndex for this event
        */
-      inline Double_t GetVal() const { return fEvent->GetValue(fVarIndex); }
+      inline Double_t GetVal() const { return fEvent->GetValue(GetVarIndex()); }
       const Event* operator*() const { return fEvent; }
-    
+
    private:
 
-#if __cplusplus > 199711L
-      static thread_local Int_t fVarIndex;  // index of the variable to sort on
-#else
-      static Int_t fVarIndex;  // index of the variable to sort on
-#endif
+      // This is a workaround for OSx where static thread_local data members are
+      // not supported. The C++ solution would indeed be the following:
+      //static_ thread_local Int_t fVarIndex;  // index of the variable to sort on
+      static Int_t& GetVarIndex(){thread_local Int_t fVarIndex(0); return fVarIndex;}; // index of the variable to sort on
+
       const Event* fEvent;     // pointer to the event
-    
+
       Double_t     fBkgWeight; // cumulative background weight for splitting
       Double_t     fSigWeight; // same for the signal weights
    };
 }
 
-inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const 
+inline Bool_t TMVA::BDTEventWrapper::operator<( const BDTEventWrapper& other ) const
 {
    return GetVal() < other.GetVal();
 }
 
-#endif 
+#endif
 
diff --git a/tmva/inc/TMVA/MethodBase.h b/tmva/inc/TMVA/MethodBase.h
index 8a1c2d28610b9..55a4492350826 100644
--- a/tmva/inc/TMVA/MethodBase.h
+++ b/tmva/inc/TMVA/MethodBase.h
@@ -202,7 +202,7 @@ namespace TMVA {
       }
 
       // probability of classifier response (mvaval) to be signal (requires "CreateMvaPdf" option set)
-      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different) 
+      virtual Double_t GetProba( const Event *ev); // the simple one, automatically calcualtes the mvaVal and uses the SAME sig/bkg ratio as given in the training sample (typically 50/50 .. (NormMode=EqualNumEvents) but can be different)
       virtual Double_t GetProba( Double_t mvaVal, Double_t ap_sig );
 
       // Rarity of classifier response (signal or background (default) is uniform in [0,1])
@@ -274,7 +274,7 @@ namespace TMVA {
 
       // variables (and private menber functions) for the Evaluation:
       // get the effiency. It fills a histogram for efficiency/vs/bkg
-      // and returns the one value fo the efficiency demanded for 
+      // and returns the one value fo the efficiency demanded for
       // in the TString argument. (Watch the string format)
       virtual Double_t GetEfficiency( const TString&, Types::ETreeType, Double_t& err );
       virtual Double_t GetTrainingEfficiency(const TString& );
@@ -283,7 +283,7 @@ namespace TMVA {
       virtual Double_t GetSignificance() const;
       virtual Double_t GetROCIntegral(TH1D *histS, TH1D *histB) const;
       virtual Double_t GetROCIntegral(PDF *pdfS=0, PDF *pdfB=0) const;
-      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents, 
+      virtual Double_t GetMaximumSignificance( Double_t SignalEvents, Double_t BackgroundEvents,
                                                Double_t& optimal_significance_value  ) const;
       virtual Double_t GetSeparation( TH1*, TH1* ) const;
       virtual Double_t GetSeparation( PDF* pdfS = 0, PDF* pdfB = 0 ) const;
@@ -366,7 +366,7 @@ namespace TMVA {
       mutable const Event*   fTmpEvent; //! temporary event when testing on a different DataSet than the own one
 
       // event reference and update
-      // NOTE: these Event accessors make sure that you get the events transformed according to the 
+      // NOTE: these Event accessors make sure that you get the events transformed according to the
       //        particular clasifiers transformation chosen
       UInt_t           GetNEvents      () const { return Data()->GetNEvents(); }
       const Event*     GetEvent        () const;
@@ -628,12 +628,10 @@ namespace TMVA {
 
    private:
 
-      // this carrier
-#if __cplusplus > 199711L
-      static thread_local MethodBase* fgThisBase;         // this pointer
-#else
-      static MethodBase* fgThisBase;         // this pointer
-#endif
+      // This is a workaround for OSx where static thread_local data members are
+      // not supported. The C++ solution would indeed be the following:
+//       static_ thread_local MethodBase* fgThisBase;         // this pointer
+      static MethodBase*& GetThisBaseThreadLocal() {thread_local MethodBase* fgThisBase(nullptr); return fgThisBase; };
 
       // ===== depreciated options, kept for backward compatibility  =====
    private:
@@ -641,7 +639,7 @@ namespace TMVA {
       Bool_t           fNormalise;                   // normalise input variables
       Bool_t           fUseDecorr;                   // synonymous for decorrelation
       TString          fVariableTransformTypeString; // labels variable transform type
-      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files 
+      Bool_t           fTxtWeightsOnly;              // if TRUE, write weights only to text files
       Int_t            fNbinsMVAPdf;                 // number of bins used in histogram that creates PDF
       Int_t            fNsmoothMVAPdf;               // number of times a histogram is smoothed before creating the PDF
 
@@ -662,12 +660,12 @@ namespace TMVA {
 
 
 //_______________________________________________________________________
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( const TMVA::Event* ev ) const
 {
    return GetTransformationHandler().Transform(ev);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent() const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
 {
    if(fTmpEvent)
       return GetTransformationHandler().Transform(fTmpEvent);
@@ -675,25 +673,25 @@ inline const TMVA::Event* TMVA::MethodBase::GetEvent() const
       return GetTransformationHandler().Transform(Data()->GetEvent());
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetEvent( Long64_t ievt, Types::ETreeType type ) const
 {
    assert(fTmpEvent==0);
    return GetTransformationHandler().Transform(Data()->GetEvent(ievt, type));
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetTrainingEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTraining);
 }
 
-inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const 
+inline const TMVA::Event* TMVA::MethodBase::GetTestingEvent( Long64_t ievt ) const
 {
    assert(fTmpEvent==0);
    return GetEvent(ievt, Types::kTesting);
diff --git a/tmva/inc/TMVA/MethodPDERS.h b/tmva/inc/TMVA/MethodPDERS.h
index 9d1a4f7bd1e61..323e345515c5c 100644
--- a/tmva/inc/TMVA/MethodPDERS.h
+++ b/tmva/inc/TMVA/MethodPDERS.h
@@ -219,12 +219,10 @@ namespace TMVA {
       Float_t GetError         ( Float_t countS, Float_t countB,
                                  Float_t sumW2S, Float_t sumW2B ) const;
 
-      // this carrier
-#if __cplusplus > 199711L
-      static thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
-#else
-      static MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
-#endif
+      // This is a workaround for OSx where static thread_local data members are
+      // not supported. The C++ solution would indeed be the following:
+//      static_ thread_local MethodPDERS* fgThisPDERS; // this pointer (required by root finder)
+      static MethodPDERS*& GetMethodPDERSThreadLocal() {thread_local MethodPDERS* fgThisPDERS(nullptr); return fgThisPDERS;};
       void UpdateThis();
 
       void Init( void );
diff --git a/tmva/inc/TMVA/ModulekNN.h b/tmva/inc/TMVA/ModulekNN.h
index 569ee5e80b46c..0d5398c1531a2 100644
--- a/tmva/inc/TMVA/ModulekNN.h
+++ b/tmva/inc/TMVA/ModulekNN.h
@@ -148,11 +148,11 @@ namespace TMVA {
 
       private:
 
-#if __cplusplus > 199711L
-         static thread_local TRandom3 fgRndm;
-#else
-         static TRandom3 fgRndm;
-#endif
+        // This is a workaround for OSx where static thread_local data members are
+        // not supported. The C++ solution would indeed be the following:
+//         static_ thread_local TRandom3 fgRndm;
+         static TRandom3& GetRndmThreadLocal() {thread_local TRandom3 fgRndm(1); return fgRndm;};
+
          UInt_t fDimn;
 
          Node<Event> *fTree;
diff --git a/tmva/inc/TMVA/PDF.h b/tmva/inc/TMVA/PDF.h
index e6387c99b496d..7a25dc0d9f7a7 100644
--- a/tmva/inc/TMVA/PDF.h
+++ b/tmva/inc/TMVA/PDF.h
@@ -205,11 +205,10 @@ namespace TMVA {
       MsgLogger&               Log() const { return *fLogger; }    
 
       // static pointer to this object
-#if __cplusplus > 199711L
-      static thread_local PDF* fgThisPDF;             // this PDF pointer 
-#else
-      static PDF*              fgThisPDF;             // this PDF pointer 
-#endif
+      // This is a workaround for OSx where static thread_local data members are
+      // not supported. The C++ solution would indeed be the following:
+//      static_ thread_local PDF* fgThisPDF;             // this PDF pointer 
+      static PDF*& GetThisPdfThreadLocal(){thread_local PDF *fgThisPDF(nullptr); return fgThisPDF; };
       static PDF*              ThisPDF( void ); 
 
       // external auxiliary functions 
diff --git a/tmva/src/BDTEventWrapper.cxx b/tmva/src/BDTEventWrapper.cxx
index 0820339c01c41..81d2cae0e61ee 100644
--- a/tmva/src/BDTEventWrapper.cxx
+++ b/tmva/src/BDTEventWrapper.cxx
@@ -4,9 +4,9 @@
  * Class  : BDTEventWrapper                                                       *
  * Web    : http://tmva.sourceforge.net                                           *
  *                                                                                *
- * Description:                                                                   *  
- *                                                                                *  
- *                                                                                *  
+ * Description:                                                                   *
+ *                                                                                *
+ *                                                                                *
  * Author: Doug Schouten (dschoute@sfu.ca)                                        *
  *                                                                                *
  *                                                                                *
@@ -26,12 +26,6 @@
 
 using namespace TMVA;
 
-#if __cplusplus > 199711L
-thread_local Int_t BDTEventWrapper::fVarIndex = 0;
-#else
-Int_t BDTEventWrapper::fVarIndex = 0;
-#endif
-
 BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
    // constuctor
 
@@ -39,7 +33,7 @@ BDTEventWrapper::BDTEventWrapper(const Event* e) : fEvent(e) {
   fSigWeight = 0.0;
 }
 
-BDTEventWrapper::~BDTEventWrapper() { 
+BDTEventWrapper::~BDTEventWrapper() {
    // destructor
 }
 
@@ -49,14 +43,14 @@ void BDTEventWrapper::SetCumulativeWeight(Bool_t type, Double_t weight) {
     * @param fType - true for signal, false for background
     * @param weight - the total weight
     */
-   
+
    if(type) fSigWeight = weight;
    else fBkgWeight = weight;
 }
 
 Double_t BDTEventWrapper::GetCumulativeWeight(Bool_t type) const {
    // Get the accumulated weight
-   
+
    if(type) return fSigWeight;
    return fBkgWeight;
 }
diff --git a/tmva/src/BinaryTree.cxx b/tmva/src/BinaryTree.cxx
index dca177c92dbd2..9ed32023b04ce 100644
--- a/tmva/src/BinaryTree.cxx
+++ b/tmva/src/BinaryTree.cxx
@@ -175,7 +175,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
       // find parent node
       while( parent!=0 && parent->GetDepth() != currentNode->GetDepth()-1) parent=parent->GetParent();
-      
+
       if (parent!=0) { // link new node to parent
          currentNode->SetParent(parent);
          if (currentNode->GetPos()=='l') parent->SetLeft(currentNode);
@@ -190,7 +190,7 @@ void TMVA::BinaryTree::Read(std::istream & istr, UInt_t tmva_Version_Code )
 
 //_______________________________________________________________________
 std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
-{ 
+{
    // read the tree from an std::istream
    tree.Read(istr);
    return istr;
@@ -199,7 +199,7 @@ std::istream& TMVA::operator>> (std::istream& istr, TMVA::BinaryTree& tree)
 void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 {
    // descend a tree to find all its leaf nodes, fill max depth reached in the
-   // tree at the same time. 
+   // tree at the same time.
 
    if (n == NULL){ //default, start at the tree top, then descend recursively
       n = (Node*) this->GetRoot();
@@ -207,7 +207,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
          Log() << kFATAL << "SetTotalTreeDepth: started with undefined ROOT node" <<Endl;
          return ;
       }
-   } 
+   }
    if (this->GetLeftDaughter(n) != NULL){
       this->SetTotalTreeDepth( this->GetLeftDaughter(n) );
    }
@@ -222,7 +222,7 @@ void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::BinaryTree::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("BinaryTree");
+  thread_local MsgLogger logger("BinaryTree");
 #else
   static MsgLogger logger("BinaryTree");
 #endif
diff --git a/tmva/src/DecisionTreeNode.cxx b/tmva/src/DecisionTreeNode.cxx
index 37425a83b94f7..249e85235b1ee 100644
--- a/tmva/src/DecisionTreeNode.cxx
+++ b/tmva/src/DecisionTreeNode.cxx
@@ -509,7 +509,7 @@ void TMVA::DecisionTreeNode::ReadContent( std::stringstream& /*s*/ )
 //_______________________________________________________________________
 TMVA::MsgLogger& TMVA::DecisionTreeNode::Log() {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
+  thread_local MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #else
   static MsgLogger logger("DecisionTreeNode");    // static because there is a huge number of nodes...
 #endif
diff --git a/tmva/src/Interval.cxx b/tmva/src/Interval.cxx
index d89b023679f49..1c7bd0066dc73 100644
--- a/tmva/src/Interval.cxx
+++ b/tmva/src/Interval.cxx
@@ -54,14 +54,14 @@
 </ul>
 <pre>
 
-    Example:   Interval(.5,1.,6) 
+    Example:   Interval(.5,1.,6)
 
-             [ min                           max ]                       
+             [ min                           max ]
          ------------------------------------------------------------
                 |     |     |     |     |     |
-               .5    .6    .7    .8    .9    1.0            
- 
-         bin    0     1     2     3     4     5  
+               .5    .6    .7    .8    .9    1.0
+
+         bin    0     1     2     3     4     5
 
 
 </pre>
@@ -76,7 +76,7 @@ End_Html */
 ClassImp(TMVA::Interval)
 
 //_______________________________________________________________________
-TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) : 
+TMVA::Interval::Interval( Double_t min, Double_t max, Int_t nbins ) :
    fMin(min),
    fMax(max),
    fNbins(nbins)
@@ -112,9 +112,9 @@ TMVA::Interval::~Interval()
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetElement( Int_t bin ) const
 {
-   // calculates the value of the "number" bin in a discrete interval. 
+   // calculates the value of the "number" bin in a discrete interval.
    // Parameters:
-   //        Double_t position 
+   //        Double_t position
    //
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
@@ -130,7 +130,7 @@ Double_t TMVA::Interval::GetElement( Int_t bin ) const
 //_______________________________________________________________________
 Double_t TMVA::Interval::GetStepSize( Int_t iBin )  const
 {
-   // retuns the step size between the numbers of a "discrete Interval" 
+   // retuns the step size between the numbers of a "discrete Interval"
    if (fNbins <= 0) {
       Log() << kFATAL << "GetElement only defined for discrete value Intervals" << Endl;
    }
@@ -148,25 +148,25 @@ Double_t TMVA::Interval::GetRndm( TRandom3& rnd )  const
    return rnd.Rndm()*(fMax - fMin) + fMin;
 }
 
-Double_t TMVA::Interval::GetWidth() const 
-{ 
-   return fMax - fMin; 
+Double_t TMVA::Interval::GetWidth() const
+{
+   return fMax - fMin;
 }
-Double_t TMVA::Interval::GetMean()  const 
-{ 
-   return (fMax + fMin)/2; 
+Double_t TMVA::Interval::GetMean()  const
+{
+   return (fMax + fMin)/2;
 }
 
-void TMVA::Interval::Print(std::ostream &os) const 
+void TMVA::Interval::Print(std::ostream &os) const
 {
    for (Int_t i=0; i<GetNbins(); i++){
       os << "| " << GetElement(i)<<" |" ;
-   }  
+   }
 }
 
 TMVA::MsgLogger& TMVA::Interval::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Interval");   // message logger
+  thread_local MsgLogger logger("Interval");   // message logger
 #else
   static MsgLogger logger("Interval");   // message logger
 #endif
diff --git a/tmva/src/LogInterval.cxx b/tmva/src/LogInterval.cxx
index 922ae5ace5991..a00c8d2f96e7d 100644
--- a/tmva/src/LogInterval.cxx
+++ b/tmva/src/LogInterval.cxx
@@ -149,7 +149,7 @@ Double_t TMVA::LogInterval::GetMean()  const
 
 TMVA::MsgLogger& TMVA::LogInterval::Log() const {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("LogInterval");   // message logger
+  thread_local MsgLogger logger("LogInterval");   // message logger
 #else
   static MsgLogger logger("LogInterval");   // message logger
 #endif
diff --git a/tmva/src/MethodBase.cxx b/tmva/src/MethodBase.cxx
index 71b7af726cd1a..02ad1d1ff51b6 100644
--- a/tmva/src/MethodBase.cxx
+++ b/tmva/src/MethodBase.cxx
@@ -440,7 +440,7 @@ void TMVA::MethodBase::ProcessBaseOptions()
       SetOptions( fMVAPdfS->GetOptions() );
    }
 
-   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString, 
+   TMVA::MethodBase::CreateVariableTransforms( fVarTransformString,
                                                DataInfo(),
                                                GetTransformationHandler(),
                                                Log() );
@@ -469,8 +469,8 @@ void TMVA::MethodBase::ProcessBaseOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn, 
-                                                 TMVA::DataSetInfo& dataInfo, 
+void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionIn,
+                                                 TMVA::DataSetInfo& dataInfo,
                                                  TMVA::TransformationHandler& transformationHandler,
                                                  TMVA::MsgLogger& log )
 {
@@ -572,7 +572,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
       if (transformation) {
          ClassInfo* clsInfo = dataInfo.GetClassInfo(idxCls);
          if (clsInfo )
-            log << kINFO << "Create Transformation \"" << trName << "\" with reference class " 
+            log << kINFO << "Create Transformation \"" << trName << "\" with reference class "
                 << clsInfo->GetName() << "=("<< idxCls <<")"<<Endl;
          else
             log << kINFO << "Create Transformation \"" << trName << "\" with events from all classes." << Endl;
@@ -588,7 +588,7 @@ void TMVA::MethodBase::CreateVariableTransforms( const TString& trafoDefinitionI
 void TMVA::MethodBase::DeclareCompatibilityOptions()
 {
    // options that are used ONLY for the READER to ensure backward compatibility
-   //   they are hence without any effect (the reader is only reading the training 
+   //   they are hence without any effect (the reader is only reading the training
    //   options that HAD been used at the training of the .xml weightfile at hand
 
    DeclareOptionRef( fNormalise=kFALSE, "Normalise", "Normalise input variables" ); // don't change the default !!!
@@ -622,8 +622,8 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
    // individually (as long as we don't have it automatized via the
    // configuraion string
 
-   Log() << kWARNING << "Parameter optimization is not yet implemented for method " 
-         << GetName() << Endl; 
+   Log() << kWARNING << "Parameter optimization is not yet implemented for method "
+         << GetName() << Endl;
    Log() << kWARNING << "Currently we need to set hardcoded which parameter is tuned in which ranges"<<Endl;
 
    std::map<TString,Double_t> tunedParameters;
@@ -636,7 +636,7 @@ std::map<TString,Double_t>  TMVA::MethodBase::OptimizeTuningParameters(TString /
 void TMVA::MethodBase::SetTuneParameters(std::map<TString,Double_t> /* tuneParameters */)
 {
    // set the tuning parameters accoding to the argument
-   // This is just a dummy .. have a look at the MethodBDT how you could 
+   // This is just a dummy .. have a look at the MethodBDT how you could
    // perhaps implment the same thing for the other Classifiers..
 }
 
@@ -653,7 +653,7 @@ void TMVA::MethodBase::TrainMethod()
    BaseDir()->cd();
 
    // once calculate all the transformation (e.g. the sequence of Decorr:Gauss:Decorr)
-   //    needed for this classifier 
+   //    needed for this classifier
    GetTransformationHandler().CalcTransformations(Data()->GetEventCollection());
 
    // call training of derived MVA
@@ -681,9 +681,9 @@ void TMVA::MethodBase::TrainMethod()
          CreateMVAPdfs();
          AddClassifierOutputProb(Types::kTraining);
       }
-      
+
    } else {
-      
+
       Log() << "regression on training sample" << Endl;
       AddRegressionOutput( Types::kTraining );
 
@@ -707,7 +707,7 @@ void TMVA::MethodBase::TrainMethod()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const 
+void TMVA::MethodBase::GetRegressionDeviation(UInt_t tgtNum, Types::ETreeType type, Double_t& stddev, Double_t& stddev90Percent ) const
 {
    if (!DoRegression()) Log() << kFATAL << "Trying to use GetRegressionDeviation() with a classification job" << Endl;
    Log() << kINFO << "Create results for " << (type==Types::kTraining?"training":"testing") << Endl;
@@ -820,16 +820,16 @@ Double_t TMVA::MethodBase::GetMvaValue( const Event* const ev, Double_t* err, Do
 }
 
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike() { 
+Bool_t TMVA::MethodBase::IsSignalLike() {
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event would be selected as signal or background
-   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
+   return GetMvaValue()*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
 }
 //_______________________________________________________________________
-Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) { 
+Bool_t TMVA::MethodBase::IsSignalLike(Double_t mvaVal) {
    // uses a pre-set cut on the MVA output (SetSignalReferenceCut and SetSignalReferenceCutOrientation)
    // for a quick determination if an event with this mva output value would tbe selected as signal or background
-   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE; 
+   return mvaVal*GetSignalReferenceCutOrientation() > GetSignalReferenceCut()*GetSignalReferenceCutOrientation() ? kTRUE : kFALSE;
 }
 
 //_______________________________________________________________________
@@ -854,7 +854,7 @@ void TMVA::MethodBase::AddClassifierOutput( Types::ETreeType type )
    for (Int_t ievt=0; ievt<nEvents; ievt++) {
       Data()->SetCurrentEvent(ievt);
       clRes->SetValue( GetMvaValue(), ievt );
-      
+
       // print progress
       Int_t modulo = Int_t(nEvents/100);
       if (modulo <= 0 ) modulo = 1;
@@ -877,7 +877,7 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 
    Data()->SetCurrentType(type);
 
-   ResultsClassification* mvaProb = 
+   ResultsClassification* mvaProb =
       (ResultsClassification*)Data()->GetResults(TString("prob_")+GetMethodName(), type, Types::kClassification );
 
    Long64_t nEvents = Data()->GetNEvents();
@@ -907,15 +907,15 @@ void TMVA::MethodBase::AddClassifierOutputProb( Types::ETreeType type )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT, 
-                                       Double_t& dev,  Double_t& devT, 
-                                       Double_t& rms,  Double_t& rmsT, 
+void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
+                                       Double_t& dev,  Double_t& devT,
+                                       Double_t& rms,  Double_t& rmsT,
                                        Double_t& mInf, Double_t& mInfT,
-                                       Double_t& corr, 
+                                       Double_t& corr,
                                        Types::ETreeType type )
 {
-   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample 
-   //                    
+   // calculate <sum-of-deviation-squared> of regression output versus "true" value from test sample
+   //
    //   bias = average deviation
    //   dev  = average absolute deviation
    //   rms  = rms of deviation
@@ -933,7 +933,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    Float_t* wV = new Float_t[nevt];
    Float_t  xmin = 1e30, xmax = -1e30;
    for (Long64_t ievt=0; ievt<nevt; ievt++) {
-      
+
       const Event* ev = Data()->GetEvent(ievt); // NOTE: need untransformed event here !
       Float_t t = ev->GetTarget(0);
       Float_t w = ev->GetWeight();
@@ -948,7 +948,7 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
       rV[ievt] = r;
       tV[ievt] = t;
       wV[ievt] = w;
-      
+
       // compute deviation-squared
       sumw += w;
       bias += w * d;
@@ -968,8 +968,8 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    rms  = TMath::Sqrt(rms - bias*bias);
 
    // correlation
-   m1   /= sumw; 
-   m2   /= sumw; 
+   m1   /= sumw;
+   m2   /= sumw;
    corr  = s12/sumw - m1*m2;
    corr /= TMath::Sqrt( (s1/sumw - m1*m1) * (s2/sumw - m2*m2) );
 
@@ -989,11 +989,11 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
          sumw  += wV[ievt];
          biasT += wV[ievt] * d;
          devT  += wV[ievt] * TMath::Abs(d);
-         rmsT  += wV[ievt] * d * d;       
+         rmsT  += wV[ievt] * d * d;
          histT->Fill( rV[ievt], tV[ievt], wV[ievt] );
          ic++;
       }
-   }   
+   }
    biasT /= sumw;
    devT  /= sumw;
    rmsT  /= sumw;
@@ -1008,14 +1008,14 @@ void TMVA::MethodBase::TestRegression( Double_t& bias, Double_t& biasT,
    delete [] tV;
    delete [] wV;
 
-   Data()->SetCurrentType(savedType);   
+   Data()->SetCurrentType(savedType);
 }
 
 
 //_______________________________________________________________________
 void TMVA::MethodBase::TestMulticlass()
 {
-   // test multiclass classification 
+   // test multiclass classification
 
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in TestMulticlass, exiting."<<Endl;
@@ -1034,7 +1034,7 @@ void TMVA::MethodBase::TestClassification()
 
    ResultsClassification* mvaRes = dynamic_cast<ResultsClassification*>
       ( Data()->GetResults(GetMethodName(),Types::kTesting, Types::kClassification) );
-   
+
    // sanity checks: tree must exist, and theVar must be in tree
    if (0==mvaRes && !(GetMethodTypeName().Contains("Cuts"))) {
       Log() << "mvaRes " << mvaRes << " GetMethodTypeName " << GetMethodTypeName()
@@ -1042,24 +1042,24 @@ void TMVA::MethodBase::TestClassification()
       Log() << kFATAL << "<TestInit> Test variable " << GetTestvarName()
             << " not found in tree" << Endl;
    }
-   
+
    // basic statistics operations are made in base class
    gTools().ComputeStat( GetEventCollection(Types::kTesting), mvaRes->GetValueVector(),
                          fMeanS, fMeanB, fRmsS, fRmsB, fXmin, fXmax, fSignalClass );
-   
+
    // choose reasonable histogram ranges, by removing outliers
    Double_t nrms = 10;
    fXmin = TMath::Max( TMath::Min( fMeanS - nrms*fRmsS, fMeanB - nrms*fRmsB ), fXmin );
    fXmax = TMath::Min( TMath::Max( fMeanS + nrms*fRmsS, fMeanB + nrms*fRmsB ), fXmax );
-   
+
    // determine cut orientation
    fCutOrientation = (fMeanS > fMeanB) ? kPositive : kNegative;
 
    // fill 2 types of histograms for the various analyses
    // this one is for actual plotting
-   
+
    Double_t sxmax = fXmax+0.00001;
-   
+
    // classifier response distributions for training sample
    // MVA plots used for graphics representation (signal)
    TH1* mva_s = new TH1D( GetTestvarName() + "_S",GetTestvarName() + "_S", fNbinsMVAoutput, fXmin, sxmax );
@@ -1090,7 +1090,7 @@ void TMVA::MethodBase::TestClassification()
       rarity_s->Sumw2();
       rarity_b->Sumw2();
    }
-   
+
    // MVA plots used for efficiency calculations (large number of bins)
    TH1* mva_eff_s = new TH1D( GetTestvarName() + "_S_high", GetTestvarName() + "_S_high", fNbinsH, fXmin, sxmax );
    TH1* mva_eff_b = new TH1D( GetTestvarName() + "_B_high", GetTestvarName() + "_B_high", fNbinsH, fXmin, sxmax );
@@ -1098,26 +1098,26 @@ void TMVA::MethodBase::TestClassification()
    mvaRes->Store(mva_eff_b, "MVA_HIGHBIN_B");
    mva_eff_s->Sumw2();
    mva_eff_b->Sumw2();
-   
+
    // fill the histograms
    ResultsClassification* mvaProb = dynamic_cast<ResultsClassification*>
       (Data()->GetResults( TString("prob_")+GetMethodName(), Types::kTesting, Types::kMaxAnalysisType ) );
-   
+
    Log() << kINFO << "Loop over test events and fill histograms with classifier response..." << Endl;
    if (mvaProb) Log() << kINFO << "Also filling probability and rarity histograms (on request)..." << Endl;
    for (Long64_t ievt=0; ievt<GetNEvents(); ievt++) {
-      
+
       const Event* ev = GetEvent(ievt);
       Float_t v = (*mvaRes)[ievt][0];
       Float_t w = ev->GetWeight();
-      
+
       if (DataInfo().IsSignal(ev)) {
          mva_s ->Fill( v, w );
          if (mvaProb) {
             proba_s->Fill( (*mvaProb)[ievt][0], w );
             rarity_s->Fill( GetRarity( v ), w );
          }
-         
+
          mva_eff_s ->Fill( v, w );
       }
       else {
@@ -1129,7 +1129,7 @@ void TMVA::MethodBase::TestClassification()
          mva_eff_b ->Fill( v, w );
       }
    }
-   
+
    // uncomment those (and several others if you want unnormalized output
    gTools().NormHist( mva_s  );
    gTools().NormHist( mva_b  );
@@ -1139,7 +1139,7 @@ void TMVA::MethodBase::TestClassification()
    gTools().NormHist( rarity_b );
    gTools().NormHist( mva_eff_s  );
    gTools().NormHist( mva_eff_b  );
-   
+
    // create PDFs from histograms, using default splines, and no additional smoothing
    if (fSplS) { delete fSplS; fSplS = 0; }
    if (fSplB) { delete fSplB; fSplB = 0; }
@@ -1188,7 +1188,7 @@ void TMVA::MethodBase::WriteStateToStream( std::ostream& tf ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const 
+void TMVA::MethodBase::AddInfoItem( void* gi, const TString& name, const TString& value) const
 {
    // xml writing
    void* it = gTools().AddChild(gi,"Info");
@@ -1247,7 +1247,7 @@ void TMVA::MethodBase::WriteStateToXML( void* parent ) const
 
    // write class info if in multiclass mode
    AddClassesXMLTo(parent);
-   
+
    // write target info if in regression mode
    if (DoRegression()) AddTargetsXMLTo(parent);
 
@@ -1357,7 +1357,7 @@ void TMVA::MethodBase::ReadStateFromXMLString( const char* xmlstr ) {
    ReadStateFromXML(rootnode);
    gTools().xmlengine().FreeDoc(doc);
 #else
-   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = " 
+   Log() << kFATAL << "Method MethodBase::ReadStateFromXMLString( const char* xmlstr = "
          << xmlstr << " ) is not available for ROOT versions prior to 5.26/00." << Endl;
 #endif
 
@@ -1638,9 +1638,9 @@ void TMVA::MethodBase::ReadVarsFromStream( std::istream& istr )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
 {
-   // write variable info to XML 
+   // write variable info to XML
    void* vars = gTools().AddChild(parent, "Variables");
    gTools().AddAttr( vars, "NVar", gTools().StringFromInt(DataInfo().GetNVariables()) );
 
@@ -1653,9 +1653,9 @@ void TMVA::MethodBase::AddVarsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
 {
-   // write spectator info to XML 
+   // write spectator info to XML
    void* specs = gTools().AddChild(parent, "Spectators");
 
    UInt_t writeIdx=0;
@@ -1675,14 +1675,14 @@ void TMVA::MethodBase::AddSpectatorsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
 {
-   // write class info to XML 
+   // write class info to XML
    UInt_t nClasses=DataInfo().GetNClasses();
-   
+
    void* classes = gTools().AddChild(parent, "Classes");
    gTools().AddAttr( classes, "NClass", nClasses );
-   
+
    for (UInt_t iCls=0; iCls<nClasses; ++iCls) {
       ClassInfo *classInfo=DataInfo().GetClassInfo (iCls);
       TString  className  =classInfo->GetName();
@@ -1694,9 +1694,9 @@ void TMVA::MethodBase::AddClassesXMLTo( void* parent ) const
    }
 }
 //_______________________________________________________________________
-void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const 
+void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
 {
-   // write target info to XML 
+   // write target info to XML
    void* targets = gTools().AddChild(parent, "Targets");
    gTools().AddAttr( targets, "NTrgt", gTools().StringFromInt(DataInfo().GetNTargets()) );
 
@@ -1709,7 +1709,7 @@ void TMVA::MethodBase::AddTargetsXMLTo( void* parent ) const
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadVariablesFromXML( void* varnode ) 
+void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
 {
    // read variable info from XML
    UInt_t readNVar;
@@ -1729,11 +1729,11 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
       gTools().ReadAttr( ch, "VarIndex", varIdx);
       existingVarInfo = DataInfo().GetVariableInfos()[varIdx];
       readVarInfo.ReadFromXML(ch);
-      
+
       if (existingVarInfo.GetExpression() == readVarInfo.GetExpression()) {
          readVarInfo.SetExternalLink(existingVarInfo.GetExternalLink());
          existingVarInfo = readVarInfo;
-      } 
+      }
       else {
          Log() << kINFO << "ERROR in <ReadVariablesFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the variables found in the input file is"  << Endl;
@@ -1748,7 +1748,7 @@ void TMVA::MethodBase::ReadVariablesFromXML( void* varnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode ) 
+void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
 {
    // read spectator info from XML
    UInt_t readNSpec;
@@ -1768,11 +1768,11 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
       gTools().ReadAttr( ch, "SpecIndex", specIdx);
       existingSpecInfo = DataInfo().GetSpectatorInfos()[specIdx];
       readSpecInfo.ReadFromXML(ch);
-      
+
       if (existingSpecInfo.GetExpression() == readSpecInfo.GetExpression()) {
          readSpecInfo.SetExternalLink(existingSpecInfo.GetExternalLink());
          existingSpecInfo = readSpecInfo;
-      } 
+      }
       else {
          Log() << kINFO << "ERROR in <ReadSpectatorsFromXML>" << Endl;
          Log() << kINFO << "The definition (or the order) of the spectators found in the input file is"  << Endl;
@@ -1787,7 +1787,7 @@ void TMVA::MethodBase::ReadSpectatorsFromXML( void* specnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadClassesFromXML( void* clsnode ) 
+void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
 {
    // read number of classes from XML
    UInt_t readNCls;
@@ -1828,7 +1828,7 @@ void TMVA::MethodBase::ReadClassesFromXML( void* clsnode )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode ) 
+void TMVA::MethodBase::ReadTargetsFromXML( void* tarnode )
 {
    // read target info from XML
    UInt_t readNTar;
@@ -1935,7 +1935,7 @@ TString TMVA::MethodBase::GetWeightFileName() const
    // directory/jobname_methodname_suffix.extension.{root/txt}
    TString suffix = "";
    TString wFileDir(GetWeightFileDir());
-   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/") 
+   return ( wFileDir + (wFileDir[wFileDir.Length()-1]=='/' ? "" : "/")
             + GetJobName() + "_" + GetMethodName() +
             suffix + "." + gConfig().GetIONames().fWeightFileExtension + ".xml" );
 }
@@ -1962,7 +1962,7 @@ void TMVA::MethodBase::WriteEvaluationHistosToFile(Types::ETreeType treetype)
    Results* results = Data()->GetResults( GetMethodName(), treetype, Types::kMaxAnalysisType );
    if (!results)
       Log() << kFATAL << "<WriteEvaluationHistosToFile> Unknown result: "
-            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting") 
+            << GetMethodName() << (treetype==Types::kTraining?"/kTraining":"/kTesting")
             << "/kMaxAnalysisType" << Endl;
    results->GetStorage()->Write();
    if (treetype==Types::kTesting) {
@@ -2013,8 +2013,8 @@ Bool_t TMVA::MethodBase::GetLine(std::istream& fin, char* buf )
       else if (analysisType == "multiclass"     || analysisType == "Multiclass")     SetAnalysisType( Types::kMulticlass );
       else Log() << kFATAL << "Analysis type " << analysisType << " from weight-file not known!" << std::endl;
 
-      Log() << kINFO << "Method was trained for " 
-            << (GetAnalysisType() == Types::kRegression ? "Regression" : 
+      Log() << kINFO << "Method was trained for "
+            << (GetAnalysisType() == Types::kRegression ? "Regression" :
                 (GetAnalysisType() == Types::kMulticlass ? "Multiclass" : "Classification")) << Endl;
    }
 
@@ -2094,7 +2094,7 @@ Double_t TMVA::MethodBase::GetProba(const Event *ev){
    }
    Double_t sigFraction = DataInfo().GetTrainingSumSignalWeights() / (DataInfo().GetTrainingSumSignalWeights() + DataInfo().GetTrainingSumBackgrWeights() );
    Double_t mvaVal = GetMvaValue(ev);
-   
+
    return GetProba(mvaVal,sigFraction);
 
 }
@@ -2172,7 +2172,7 @@ Double_t TMVA::MethodBase::GetEfficiency( const TString& theString, Types::ETree
    Double_t xmax = effhist->GetXaxis()->GetXmax();
 
 #if __cplusplus > 199711L
-   static thread_local Double_t nevtS;
+   thread_local Double_t nevtS;
 #else
    static Double_t nevtS;
 #endif
@@ -2479,7 +2479,7 @@ Double_t TMVA::MethodBase::GetTrainingEfficiency(const TString& theString)
       // note that there is a bin shift when going from a TH1D object to a TGraph :-(
       if (Use_Splines_for_Eff_) {
          if (fSplTrainRefS) delete fSplTrainRefS;
-         if (fSplTrainRefB) delete fSplTrainRefB;         
+         if (fSplTrainRefB) delete fSplTrainRefB;
          fSplTrainRefS  = new TSpline1( "spline2_signal",     new TGraph( mva_eff_tr_s ) );
          fSplTrainRefB  = new TSpline1( "spline2_background", new TGraph( mva_eff_tr_b ) );
 
@@ -2548,8 +2548,8 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassEfficiency(std::vector<std::
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTesting, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassEfficiency, exiting."<<Endl;
 
-   purity.push_back(resMulticlass->GetAchievablePur()); 
-   return resMulticlass->GetAchievableEff(); 
+   purity.push_back(resMulticlass->GetAchievablePur());
+   return resMulticlass->GetAchievableEff();
 }
 
 //_______________________________________________________________________
@@ -2559,14 +2559,14 @@ std::vector<Float_t> TMVA::MethodBase::GetMulticlassTrainingEfficiency(std::vect
    Data()->SetCurrentType(Types::kTraining);
    ResultsMulticlass* resMulticlass = dynamic_cast<ResultsMulticlass*>(Data()->GetResults(GetMethodName(), Types::kTraining, Types::kMulticlass));
    if (!resMulticlass) Log() << kFATAL<< "unable to create pointer in GetMulticlassTrainingEfficiency, exiting."<<Endl;
-   
+
    Log() << kINFO << "Determine optimal multiclass cuts for training data..." << Endl;
    for (UInt_t icls = 0; icls<DataInfo().GetNClasses(); ++icls) {
       resMulticlass->GetBestMultiClassCuts(icls);
    }
-    
-   purity.push_back(resMulticlass->GetAchievablePur()); 
-   return resMulticlass->GetAchievableEff(); 
+
+   purity.push_back(resMulticlass->GetAchievablePur());
+   return resMulticlass->GetAchievableEff();
 }
 
 
@@ -2637,10 +2637,10 @@ Double_t TMVA::MethodBase::GetROCIntegral(TH1D *histS, TH1D *histB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   } 
+   }
    return integral*step;
 }
-   
+
 
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
@@ -2667,7 +2667,7 @@ Double_t TMVA::MethodBase::GetROCIntegral(PDF *pdfS, PDF *pdfB) const
    for (UInt_t i=0; i<nsteps; i++) {
       integral += (1-pdfB->GetIntegral(cut,xmax)) * pdfS->GetVal(cut);
       cut+=step;
-   } 
+   }
    return integral*step;
 }
 
@@ -2996,7 +2996,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "                 varIt != inputValues.end(); varIt++, ivar++) {" << std::endl;
    fout << "               iV.push_back(NormVariable( *varIt, fVmin[ivar], fVmax[ivar] ));" << std::endl;
    fout << "            }" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            Transform( iV, -1 );" << std::endl;
@@ -3004,7 +3004,7 @@ void TMVA::MethodBase::MakeClass( const TString& theClassFileName ) const
    fout << "            retval = GetMvaValue__( iV );" << std::endl;
    fout << "         }" << std::endl;
    fout << "         else {" << std::endl;
-   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 && 
+   if (GetTransformationHandler().GetTransformationList().GetSize()!=0 &&
        GetMethodType() != Types::kLikelihood &&
        GetMethodType() != Types::kHMatrix) {
       fout << "            std::vector<double> iV;" << std::endl;
@@ -3089,12 +3089,6 @@ void TMVA::MethodBase::PrintHelpMessage() const
 
 // ----------------------- r o o t   f i n d i n g ----------------------------
 
-#if __cplusplus > 199711L
-thread_local TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
-#else
-TMVA::MethodBase* TMVA::MethodBase::fgThisBase = 0;
-#endif
-
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::IGetEffForRoot( Double_t theCut )
 {
@@ -3128,18 +3122,18 @@ Double_t TMVA::MethodBase::GetEffForRoot( Double_t theCut )
 }
 
 //_______________________________________________________________________
-const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type) 
+const std::vector<TMVA::Event*>& TMVA::MethodBase::GetEventCollection( Types::ETreeType type)
 {
    // returns the event collection (i.e. the dataset) TRANSFORMED using the
    //   classifiers specific Variable Transformation (e.g. Decorr or Decorr:Gauss:Decorr)
 
-   // if there's no variable transformation for this classifier, just hand back the 
+   // if there's no variable transformation for this classifier, just hand back the
    //  event collection of the data set
    if (GetTransformationHandler().GetTransformationList().GetEntries() <= 0) {
       return (Data()->GetEventCollection(type));
-   } 
+   }
 
-   // otherwise, transform ALL the events and hand back the vector of the pointers to the 
+   // otherwise, transform ALL the events and hand back the vector of the pointers to the
    // transformed events. If the pointer is already != 0, i.e. the whole thing has been
    // done before, I don't need to do it again, but just "hand over" the pointer to those events.
    Int_t idx = Data()->TreeIndex(type);  //index indicating Training,Testing,...  events/datasets
@@ -3171,19 +3165,19 @@ TString TMVA::MethodBase::GetTrainingROOTVersionString() const
 
    return TString(Form("%i.%02i/%02i",a,b,c));
 }
- 
+
 //_______________________________________________________________________
 TMVA::MethodBase* TMVA::MethodBase::GetThisBase()
 {
    // return a pointer the base class of this method
-   return fgThisBase; 
+   return GetThisBaseThreadLocal();
 }
 
 //_______________________________________________________________________
-void TMVA::MethodBase::ResetThisBase() 
-{ 
+void TMVA::MethodBase::ResetThisBase()
+{
    // reset required for RootFinder
-   fgThisBase = this; 
+   GetThisBaseThreadLocal() = this;
 }
 //_______________________________________________________________________
 Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
@@ -3198,7 +3192,7 @@ Double_t TMVA::MethodBase::GetKSTrainingVsTest(Char_t SorB, TString opt){
      TH1D *mva_b_tr = dynamic_cast<TH1D*> (mvaRes->GetHist("MVA_TRAIN_B"));
 
      if ( !mva_s || !mva_b || !mva_s_tr || !mva_b_tr) return -1;
- 
+
      if (SorB == 's' || SorB == 'S')
        return mva_s->KolmogorovTest( mva_s_tr, opt.Data() );
      else
diff --git a/tmva/src/MethodMLP.cxx b/tmva/src/MethodMLP.cxx
index 9e4f58143e1b5..5af868b409c2c 100644
--- a/tmva/src/MethodMLP.cxx
+++ b/tmva/src/MethodMLP.cxx
@@ -85,10 +85,10 @@ TMVA::MethodMLP::MethodMLP( const TString& jobName,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -107,10 +107,10 @@ TMVA::MethodMLP::MethodMLP( DataSetInfo& theData,
      fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
      fSamplingTraining(false), fSamplingTesting(false),
      fLastAlpha(0.0), fTau(0.),
-     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),     
+     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
      fBPMode(kSequential), fBpModeS("None"),
      fBatchSize(0), fTestRate(0), fEpochMon(false),
-     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0), 
+     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
      fGA_SC_rate(0), fGA_SC_factor(0.0),
      fDeviationsFromTargets(0),
      fWeightRange     (1.0)
@@ -221,13 +221,13 @@ void TMVA::MethodMLP::ProcessOptions()
    // process user options
    MethodANNBase::ProcessOptions();
 
-   
+
    if (IgnoreEventsWithNegWeightsInTraining()) {
-      Log() << kINFO 
+      Log() << kINFO
             << "Will ignore negative events in training!"
             << Endl;
    }
-   
+
 
    if      (fTrainMethodS == "BP"  ) fTrainingMethod = kBP;
    else if (fTrainMethodS == "BFGS") fTrainingMethod = kBFGS;
@@ -301,8 +301,8 @@ Double_t TMVA::MethodMLP::CalculateEstimator( Types::ETreeType treeType, Int_t i
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event* ev = GetEvent(i);
-      
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (saveType == Types::kTraining)){
          continue;
       }
@@ -419,7 +419,7 @@ void TMVA::MethodMLP::Train(Int_t nEpochs)
 
    Int_t nEvents=GetNEvents();
    Int_t nSynapses=fSynapses->GetEntriesFast();
-   if (nSynapses>nEvents) 
+   if (nSynapses>nEvents)
       Log()<<kWARNING<<"ANN too complicated: #events="<<nEvents<<"\t#synapses="<<nSynapses<<Endl;
 
 #ifdef MethodMLP_UseMinuit__
@@ -661,7 +661,7 @@ void TMVA::MethodMLP::ComputeDEDw()
    for (Int_t i=0;i<nEvents;i++) {
 
       const Event* ev = GetEvent(i);
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          --nPosEvents;
          continue;
@@ -810,7 +810,7 @@ Bool_t TMVA::MethodMLP::LineSearch(TMatrixD &Dir, std::vector<Double_t> &buffer,
 
    SetDirWeights( Origin, Dir, alpha2 );
    Double_t err2 = GetError();
-   //Double_t err2 = err1; 
+   //Double_t err2 = err1;
    Double_t err3 = err2;
    Bool_t bingo = kFALSE;
 
@@ -918,7 +918,7 @@ Double_t TMVA::MethodMLP::GetError()
    for (Int_t i=0;i<nEvents;i++) {
       const Event* ev = GetEvent(i);
 
-       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+       if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
@@ -1089,11 +1089,11 @@ void TMVA::MethodMLP::TrainOneEpoch()
    for (Int_t i = 0; i < nEvents; i++) {
 
       const Event * ev = GetEvent(index[i]);
-      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining() 
+      if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
           &&  (Data()->GetCurrentType() == Types::kTraining)){
          continue;
       }
-      
+
       TrainOneEvent(index[i]);
 
       // do adjustments if in batch mode
@@ -1146,7 +1146,7 @@ void TMVA::MethodMLP::DecaySynapseWeights(Bool_t lateEpoch)
    TSynapse* synapse;
    Int_t numSynapses = fSynapses->GetEntriesFast();
    for (Int_t i = 0; i < numSynapses; i++) {
-      synapse = (TSynapse*)fSynapses->At(i);      
+      synapse = (TSynapse*)fSynapses->At(i);
       if (lateEpoch) synapse->DecayLearningRate(TMath::Sqrt(fDecayRate)); // In order to lower the learning rate even more, we need to apply sqrt instead of square.
       else           synapse->DecayLearningRate(fDecayRate);
    }
@@ -1160,13 +1160,13 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    GetEvent(ievt);
 
    // as soon as we know how to get event weights, get that here
-   
+
    // note: the normalization of event weights will affect the choice
    // of learning rate, one will have to experiment to get the right value.
    // in general, if the "average" event weight is 1, the learning rate
    // should be good if set around 0.02 (a good value if all event weights are 1)
    Double_t eventWeight = 1.0;
-   
+
    // get the desired output of this event
    Double_t desired;
    if (type == 0) desired = fOutput->GetMin();  // background //zjh
@@ -1175,7 +1175,7 @@ void TMVA::MethodMLP::TrainOneEventFast(Int_t ievt, Float_t*& branchVar, Int_t&
    // force the value for each input neuron
    Double_t x;
    TNeuron* neuron;
-   
+
    for (UInt_t j = 0; j < GetNvar(); j++) {
       x = branchVar[j];
       if (IsNormalised()) x = gTools().NormVariable( x, GetXmin( j ), GetXmax( j ) );
@@ -1260,7 +1260,7 @@ void TMVA::MethodMLP::CalculateNeuronDeltas()
    for (Int_t i = numLayers-1; i >= 0; i--) {
       curLayer = (TObjArray*)fNetwork->At(i);
       numNeurons = curLayer->GetEntriesFast();
-  
+
       for (Int_t j = 0; j < numNeurons; j++) {
          neuron = (TNeuron*) curLayer->At(j);
          neuron->CalculateDelta();
@@ -1498,7 +1498,7 @@ Double_t TMVA::MethodMLP::GetMvaValue( Double_t* errLower, Double_t* errUpper )
      variance=0;
    }
    variance=sqrt(variance);
- 
+
    //upper
    MvaUpper=fOutput->Eval(median+variance);
    if(errUpper)
@@ -1584,8 +1584,8 @@ void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t*
 }
 
 #if __cplusplus > 199711L
-static thread_local Int_t  nc   = 0;
-static thread_local double minf = 1000000;
+thread_local Int_t  nc   = 0;
+thread_local double minf = 1000000;
 #else
 static Int_t  nc   = 0;
 static double minf = 1000000;
diff --git a/tmva/src/MethodPDERS.cxx b/tmva/src/MethodPDERS.cxx
index 96d03cc58b61f..bb535c21091f3 100644
--- a/tmva/src/MethodPDERS.cxx
+++ b/tmva/src/MethodPDERS.cxx
@@ -87,11 +87,6 @@ namespace TMVA {
    const Bool_t MethodPDERS_UseFindRoot = kFALSE;
 };
 
-#if __cplusplus > 199711L
-thread_local TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
-#else
-TMVA::MethodPDERS* TMVA::MethodPDERS::fgThisPDERS = NULL;
-#endif
 
 REGISTER_METHOD(PDERS)
 
@@ -189,7 +184,7 @@ void TMVA::MethodPDERS::Init( void )
    fInitialScale    = 0.99;
    fGaussSigma      = 0.1;
    fNormTree        = kFALSE;
-    
+
    fkNNMin      = Int_t(fNEventsMin);
    fkNNMax      = Int_t(fNEventsMax);
 
@@ -211,12 +206,12 @@ TMVA::MethodPDERS::~MethodPDERS( void )
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::DeclareOptions() 
+void TMVA::MethodPDERS::DeclareOptions()
 {
-   // define the options (their key words) that can be set in the option string 
+   // define the options (their key words) that can be set in the option string
    // know options:
    // VolumeRangeMode   <string>  Method to determine volume range
-   //    available values are:        MinMax 
+   //    available values are:        MinMax
    //                                 Unscaled
    //                                 RMS
    //                                 kNN
@@ -239,10 +234,10 @@ void TMVA::MethodPDERS::DeclareOptions()
    //                                 Trim
    //
    // DeltaFrac         <float>   Ratio of #EventsMin/#EventsMax for MinMax and RMS volume range
-   // NEventsMin        <int>     Minimum number of events for adaptive volume range             
+   // NEventsMin        <int>     Minimum number of events for adaptive volume range
    // NEventsMax        <int>     Maximum number of events for adaptive volume range
    // MaxVIterations    <int>     Maximum number of iterations for adaptive volume range
-   // InitialScale      <float>   Initial scale for adaptive volume range           
+   // InitialScale      <float>   Initial scale for adaptive volume range
    // GaussSigma        <float>   Width with respect to the volume size of Gaussian kernel estimator
    DeclareOptionRef(fVolumeRange="Adaptive", "VolumeRangeMode", "Method to determine volume size");
    AddPreDefVal(TString("Unscaled"));
@@ -277,13 +272,13 @@ void TMVA::MethodPDERS::DeclareOptions()
 }
 
 //_______________________________________________________________________
-void TMVA::MethodPDERS::ProcessOptions() 
+void TMVA::MethodPDERS::ProcessOptions()
 {
    // process the options specified by the user
-   
+
    if (IgnoreEventsWithNegWeightsInTraining()) {
       Log() << kFATAL << "Mechanism to ignore events with negative weights in training not yet available for method: "
-            << GetMethodTypeName() 
+            << GetMethodTypeName()
             << " --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
             << Endl;
    }
@@ -342,13 +337,13 @@ void TMVA::MethodPDERS::Train( void )
    // trainingTree in the weight file, and to rebuild the binary tree in the
    // test phase from scratch
 
-   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; " 
+   if (IsNormalised()) Log() << kFATAL << "\"Normalise\" option cannot be used with PDERS; "
                                << "please remove the option from the configuration string, or "
                                << "use \"!Normalise\""
                                << Endl;
 
    CreateBinarySearchTree( Types::kTraining );
-    
+
    CalcAverages();
    SetVolumeElement();
 
@@ -425,7 +420,7 @@ void TMVA::MethodPDERS::CalcAverages()
       fAverageRMS.clear();
       fBinaryTree->CalcStatistics();
 
-      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) { 
+      for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
          if (!DoRegression()){ //why there are separate rms for signal and background?
             Float_t rmsS = fBinaryTree->RMS(Types::kSignal, ivar);
             Float_t rmsB = fBinaryTree->RMS(Types::kBackground, ivar);
@@ -436,7 +431,7 @@ void TMVA::MethodPDERS::CalcAverages()
          }
       }
    }
-}   
+}
 
 //_______________________________________________________________________
 void TMVA::MethodPDERS::CreateBinarySearchTree( Types::ETreeType type )
@@ -474,7 +469,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    // init relative scales
    fkNNMin      = Int_t(fNEventsMin);
-   fkNNMax      = Int_t(fNEventsMax);   
+   fkNNMax      = Int_t(fNEventsMax);
 
    if (fDelta) delete fDelta;
    if (fShift) delete fShift;
@@ -483,7 +478,7 @@ void TMVA::MethodPDERS::SetVolumeElement( void ) {
 
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       switch (fVRangeMode) {
-         
+
       case kRMS:
       case kkNN:
       case kAdaptive:
@@ -778,7 +773,7 @@ Double_t TMVA::MethodPDERS::CRScalc( const Event& e )
    }
 
    Volume *volume = new Volume( lb, ub );
-   
+
    GetSample( e, events, volume );
    Double_t count = CKernelEstimate( e, events, *volume );
    delete volume;
@@ -948,22 +943,22 @@ Double_t TMVA::MethodPDERS::ApplyKernelFunction (Double_t normalized_distance)
 
    return 0;
 }
-      
+
 //_______________________________________________________________________
-Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf) 
+Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 {
-   // Calculating the normalization factor only once (might need a reset at some point. 
+   // Calculating the normalization factor only once (might need a reset at some point.
    // Can the method be restarted with different params?)
 
-   // Caching jammed to disable function. 
+   // Caching jammed to disable function.
    // It's not really useful afterall, badly implemented and untested :-)
 #if __cplusplus > 199711L
-   static thread_local Double_t ret = 1.0; 
+   thread_local Double_t ret = 1.0;
 #else
-   static Double_t ret = 1.0; 
+   static Double_t ret = 1.0;
 #endif
-   
-   if (ret != 0.0) return ret*pdf; 
+
+   if (ret != 0.0) return ret*pdf;
 
    // We first normalize by the volume of the hypersphere.
    switch (fKernelEstimator) {
@@ -1005,7 +1000,7 @@ Double_t TMVA::MethodPDERS::KernelNormalization (Double_t pdf)
 //_______________________________________________________________________
 Double_t TMVA::MethodPDERS::GetNormalizedDistance ( const Event &base_event,
                                                     const BinarySearchTreeNode &sample_event,
-                                                    Double_t *dim_normalization) 
+                                                    Double_t *dim_normalization)
 {
    // We use Euclidian metric here. Might not be best or most efficient.
    Double_t ret=0;
@@ -1155,16 +1150,16 @@ void TMVA::MethodPDERS::ReadWeightsFromStream( TFile& /*rf*/ )
 }
 
 //_______________________________________________________________________
-TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void ) 
-{ 
+TMVA::MethodPDERS* TMVA::MethodPDERS::ThisPDERS( void )
+{
    // static pointer to this object
-   return fgThisPDERS; 
+   return GetMethodPDERSThreadLocal();
 }
 //_______________________________________________________________________
-void TMVA::MethodPDERS::UpdateThis( void ) 
+void TMVA::MethodPDERS::UpdateThis( void )
 {
    // update static this pointer
-   fgThisPDERS = this; 
+   GetMethodPDERSThreadLocal() = this;
 }
 
 //_______________________________________________________________________
@@ -1180,7 +1175,7 @@ void TMVA::MethodPDERS::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line: 
+   // typical length of text line:
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/MethodTMlpANN.cxx b/tmva/src/MethodTMlpANN.cxx
index e6ee4baca6918..828fe1ba7a070 100644
--- a/tmva/src/MethodTMlpANN.cxx
+++ b/tmva/src/MethodTMlpANN.cxx
@@ -129,7 +129,7 @@ void TMVA::MethodTMlpANN::Init( void )
 //_______________________________________________________________________
 TMVA::MethodTMlpANN::~MethodTMlpANN( void )
 {
-   // destructor 
+   // destructor
    if (fMLP) delete fMLP;
 }
 
@@ -224,7 +224,7 @@ Double_t TMVA::MethodTMlpANN::GetMvaValue( Double_t* err, Double_t* errUpper )
    // calculate the value of the neural net for the current event
    const Event* ev = GetEvent();
 #if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
+   thread_local Double_t* d = new Double_t[Data()->GetNVariables()];
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()];
 #endif
@@ -258,17 +258,17 @@ void TMVA::MethodTMlpANN::Train( void )
    Int_t type;
    Float_t weight;
    const Long_t basketsize = 128000;
-   Float_t* vArr = new Float_t[GetNvar()]; 
+   Float_t* vArr = new Float_t[GetNvar()];
 
    TTree *localTrainingTree = new TTree( "TMLPtrain", "Local training tree for TMlpANN" );
    localTrainingTree->Branch( "type",       &type,        "type/I",        basketsize );
    localTrainingTree->Branch( "weight",     &weight,      "weight/F",      basketsize );
-   
+
    for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
       const char* myVar = GetInternalVarName(ivar).Data();
       localTrainingTree->Branch( myVar, &vArr[ivar], Form("Var%02i/F", ivar), basketsize );
    }
-   
+
    for (UInt_t ievt=0; ievt<Data()->GetNEvents(); ievt++) {
       const Event *ev = GetEvent(ievt);
       for (UInt_t i=0; i<GetNvar(); i++) {
@@ -399,15 +399,15 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
          }
       }
       if (strcmp(gTools().GetName(ch),"neurons")==0) {
-         fout << "#neurons weights" << std::endl;         
+         fout << "#neurons weights" << std::endl;
          while (content >> temp1) {
             fout << temp1 << std::endl;
          }
       }
       if (strcmp(gTools().GetName(ch),"synapses")==0) {
-         fout << "#synapses weights" ;         
+         fout << "#synapses weights" ;
          while (content >> temp1) {
-            fout << std::endl << temp1 ;                
+            fout << std::endl << temp1 ;
          }
       }
       ch = gTools().GetNextChild(ch);
@@ -417,8 +417,8 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    // Here we create a dummy tree necessary to create a minimal NN
    // to be used for testing, evaluation and application
 #if __cplusplus > 199711L
-   static thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
-   static thread_local Int_t type;
+   thread_local Double_t* d = new Double_t[Data()->GetNVariables()] ;
+   thread_local Int_t type;
 #else
    static Double_t* d = new Double_t[Data()->GetNVariables()] ;
    static Int_t type;
@@ -436,7 +436,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromXML( void* wghtnode )
    fMLP = new TMultiLayerPerceptron( fMLPBuildOptions.Data(), dummyTree );
    fMLP->LoadWeights( fname );
 }
- 
+
 //_______________________________________________________________________
 void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
 {
@@ -450,7 +450,7 @@ void  TMVA::MethodTMlpANN::ReadWeightsFromStream( std::istream& istr )
    // the MLP is already build
    Log() << kINFO << "Load TMLP weights into " << fMLP << Endl;
 
-   Double_t* d = new Double_t[Data()->GetNVariables()] ; 
+   Double_t* d = new Double_t[Data()->GetNVariables()] ;
    Int_t type;
    gROOT->cd();
    TTree * dummyTree = new TTree("dummy","Empty dummy tree", 1);
@@ -499,7 +499,7 @@ void TMVA::MethodTMlpANN::GetHelpMessage() const
 {
    // get help message text
    //
-   // typical length of text line: 
+   // typical length of text line:
    //         "|--------------------------------------------------------------|"
    Log() << Endl;
    Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
diff --git a/tmva/src/ModulekNN.cxx b/tmva/src/ModulekNN.cxx
index 2160b5dfee708..2b9cf31ca9a1f 100644
--- a/tmva/src/ModulekNN.cxx
+++ b/tmva/src/ModulekNN.cxx
@@ -1,5 +1,5 @@
 // @(#)root/tmva $Id$
-// Author: Rustem Ospanov 
+// Author: Rustem Ospanov
 
 /**********************************************************************************
  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
@@ -14,8 +14,8 @@
  *      Rustem Ospanov <rustem@fnal.gov> - U. of Texas at Austin, USA             *
  *                                                                                *
  * Copyright (c) 2007:                                                            *
- *      CERN, Switzerland                                                         * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      MPI-K Heidelberg, Germany                                                 *
  *      U. of Texas at Austin, USA                                                *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -36,9 +36,9 @@
 
 // TMVA
 #include "TMVA/MsgLogger.h"
- 
+
 //-------------------------------------------------------------------------------------------
-TMVA::kNN::Event::Event() 
+TMVA::kNN::Event::Event()
    :fVar(),
     fWeight(-1.0),
     fType(-1)
@@ -81,12 +81,12 @@ TMVA::kNN::VarType TMVA::kNN::Event::GetDist(const Event &other) const
       std::cerr << "Distance: two events have different dimensions" << std::endl;
       return -1.0;
    }
-   
+
    VarType sum = 0.0;
    for (UInt_t ivar = 0; ivar < nvar; ++ivar) {
       sum += GetDist(other.GetVar(ivar), ivar);
    }
-   
+
    return sum;
 }
 
@@ -149,16 +149,6 @@ std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& ev
    return os;
 }
 
-
-
-
-
-#if __cplusplus > 199711L
-thread_local TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
-#else
-TRandom3 TMVA::kNN::ModulekNN::fgRndm(1);
-#endif
-
 //-------------------------------------------------------------------------------------------
 TMVA::kNN::ModulekNN::ModulekNN()
    :fDimn(0),
@@ -197,11 +187,11 @@ void TMVA::kNN::ModulekNN::Clear()
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::Add(const Event &event)
-{   
+{
    // add an event to tree
    if (fTree) {
       Log() << kFATAL << "<Add> Cannot add event: tree is already built" << Endl;
-      return;      
+      return;
    }
 
    if (fDimn < 1) {
@@ -234,7 +224,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    if (fTree) {
       Log() << kFATAL << "ModulekNN::Fill - tree has already been created" << Endl;
       return kFALSE;
-   }   
+   }
 
    // If trim option is set then find class with lowest number of events
    // and set that as maximum number of events for all other classes.
@@ -245,14 +235,14 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
             min = it->second;
          }
       }
-      
+
       Log() << kINFO << "<Fill> Will trim all event types to " << min << " events" << Endl;
-      
+
       fCount.clear();
       fVar.clear();
-      
+
       EventVec evec;
-      
+
       for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
          std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
          if (cit == fCount.end()) {
@@ -273,7 +263,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
       }
 
       Log() << kINFO << "<Fill> Erased " << fEvent.size() - evec.size() << " events" << Endl;
-      
+
       fEvent = evec;
    }
 
@@ -287,7 +277,7 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
 
    if (option.find("metric") != std::string::npos && ifrac > 0) {
       ComputeMetric(ifrac);
-      
+
       // sort again each variable for all events - needs this before Optimize()
       // rescaling has changed variable values
       for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
@@ -300,15 +290,15 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
    // all child nodes. If odepth = 0 then split variable 0
    // at the median (in half) and return it as root node
    fTree = Optimize(odepth);
-   
+
    if (!fTree) {
       Log() << kFATAL << "ModulekNN::Fill() - failed to create tree" << Endl;
-      return kFALSE;      
-   }      
-   
+      return kFALSE;
+   }
+
    for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
       fTree->Add(*event, 0);
-      
+
       std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
       if (cit == fCount.end()) {
          fCount[event->GetType()] = 1;
@@ -317,20 +307,20 @@ Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, con
          ++(cit->second);
       }
    }
-   
+
    for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
-      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8) 
+      Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8)
               << it->second << " events" << Endl;
    }
-   
+
    return kTRUE;
 }
 
 //-------------------------------------------------------------------------------------------
 Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::string &option) const
-{  
+{
    // find in tree
-   // if tree has been filled then search for nfind closest events 
+   // if tree has been filled then search for nfind closest events
    // if metic (fVarScale map) is computed then rescale event variables
    // using previsouly computed width of variable distribution
 
@@ -356,7 +346,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    // latest event for k-nearest neighbor search
    fkNNEvent = event;
    fkNNList.clear();
-   
+
    if(option.find("weight") != std::string::npos)
    {
       // recursive kd-tree search for nfind-nearest neighbors
@@ -368,7 +358,7 @@ Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::st
    {
       // recursive kd-tree search for nfind-nearest neighbors
       // count nodes and do not use event weight
-      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);      
+      kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);
    }
 
    return kTRUE;
@@ -381,9 +371,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
    if (fCount.empty() || !fTree) {
       return kFALSE;
    }
-   
+
 #if __cplusplus > 199711L
-   static thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
+   thread_local std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
 #else
    static std::map<Short_t, UInt_t>::const_iterator cit = fCount.end();
 #endif
@@ -401,9 +391,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          if (vit == fVar.end()) {
             return kFALSE;
          }
-         
+
          const std::vector<Double_t> &vvec = vit->second;
-         
+
          if (vvec.empty()) {
             return kFALSE;
          }
@@ -412,9 +402,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
          const VarType min = vvec.front();
          const VarType max = vvec.back();
          const VarType width = max - min;
-         
+
          if (width < 0.0 || width > 0.0) {
-            dvec.push_back(min + width*fgRndm.Rndm());
+            dvec.push_back(min + width*GetRndmThreadLocal().Rndm());
          }
          else {
             return kFALSE;
@@ -422,9 +412,9 @@ Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option)
       }
 
       const Event event(dvec, 1.0, etype);
-      
+
       Find(event, nfind);
-      
+
       return kTRUE;
    }
 
@@ -459,8 +449,8 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
 
    if (double(fDimn*size) < TMath::Power(2.0, double(odepth))) {
       Log() << kWARNING << "<Optimize> Optimization depth exceeds number of events" << Endl;
-      return 0;      
-   }   
+      return 0;
+   }
 
    Log() << kINFO << "Optimizing tree for " << fDimn << " variables with " << size << " values" << Endl;
 
@@ -473,14 +463,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
    }
 
    const Event pevent(VarVec(fDimn, (it->second)[size/2]), -1.0, -1);
-   
+
    Node<Event> *tree = new Node<Event>(0, pevent, 0);
-   
+
    pvec.push_back(tree);
 
-   for (UInt_t depth = 1; depth < odepth; ++depth) {            
+   for (UInt_t depth = 1; depth < odepth; ++depth) {
       const UInt_t mod = depth % fDimn;
-      
+
       VarMap::const_iterator vit = fVar.find(mod);
       if (vit == fVar.end()) {
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
@@ -492,26 +482,26 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
          Log() << kFATAL << "Missing " << mod << " variable" << Endl;
          return 0;
       }
-      
+
       UInt_t ichild = 1;
       for (std::vector<Node<Event> *>::iterator pit = pvec.begin(); pit != pvec.end(); ++pit) {
          Node<Event> *parent = *pit;
-         
+
          const VarType lmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
 
          const VarType rmedian = dvec[size*ichild/(2*pvec.size() + 1)];
          ++ichild;
-      
+
          const Event levent(VarVec(fDimn, lmedian), -1.0, -1);
          const Event revent(VarVec(fDimn, rmedian), -1.0, -1);
-         
+
          Node<Event> *lchild = new Node<Event>(parent, levent, mod);
          Node<Event> *rchild = new Node<Event>(parent, revent, mod);
-         
+
          parent->SetNodeL(lchild);
          parent->SetNodeR(rchild);
-         
+
          cvec.push_back(lchild);
          cvec.push_back(rchild);
       }
@@ -519,14 +509,14 @@ TMVA::kNN::Node<TMVA::kNN::Event>* TMVA::kNN::ModulekNN::Optimize(const UInt_t o
       pvec = cvec;
       cvec.clear();
    }
-   
+
    return tree;
 }
 
 //-------------------------------------------------------------------------------------------
 void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
 {
-   // compute scale factor for each variable (dimension) so that 
+   // compute scale factor for each variable (dimension) so that
    // distance is computed uniformely along each dimension
    // compute width of interval that includes (100 - 2*ifrac)% of events
    // below, assume that in fVar each vector of values is sorted
@@ -537,37 +527,37 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
    if (ifrac > 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - fraction can not exceed 100%" << Endl;
       return;
-   }   
+   }
    if (!fVarScale.empty()) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - metric is already computed" << Endl;
       return;
    }
    if (fEvent.size() < 100) {
       Log() << kFATAL << "ModulekNN::ComputeMetric - number of events is too small" << Endl;
-      return;      
+      return;
    }
 
    const UInt_t lfrac = (100 - ifrac)/2;
    const UInt_t rfrac = 100 - (100 - ifrac)/2;
 
-   Log() << kINFO << "Computing scale factor for 1d distributions: " 
-           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;   
+   Log() << kINFO << "Computing scale factor for 1d distributions: "
+           << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;
 
    fVarScale.clear();
-   
+
    for (VarMap::const_iterator vit = fVar.begin(); vit != fVar.end(); ++vit) {
       const std::vector<Double_t> &dvec = vit->second;
-      
+
       std::vector<Double_t>::const_iterator beg_it = dvec.end();
       std::vector<Double_t>::const_iterator end_it = dvec.end();
-      
+
       Int_t dist = 0;
       for (std::vector<Double_t>::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit, ++dist) {
-         
+
          if ((100*dist)/dvec.size() == lfrac && beg_it == dvec.end()) {
             beg_it = dit;
          }
-         
+
          if ((100*dist)/dvec.size() == rfrac && end_it == dvec.end()) {
             end_it = dit;
          }
@@ -576,35 +566,35 @@ void TMVA::kNN::ModulekNN::ComputeMetric(const UInt_t ifrac)
       if (beg_it == dvec.end() || end_it == dvec.end()) {
          beg_it = dvec.begin();
          end_it = dvec.end();
-         
+
          assert(beg_it != end_it && "Empty vector");
-         
+
          --end_it;
       }
 
       const Double_t lpos = *beg_it;
       const Double_t rpos = *end_it;
-      
+
       if (!(lpos < rpos)) {
          Log() << kFATAL << "ModulekNN::ComputeMetric() - min value is greater than max value" << Endl;
          continue;
       }
-      
+
       // Rustem: please find a solution that does not use distance (it does not exist on solaris)
-      //       Log() << kINFO << "Variable " << vit->first 
+      //       Log() << kINFO << "Variable " << vit->first
       //               << " included " << distance(beg_it, end_it) + 1
       //               << " events: width = " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos - lpos
-      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos 
+      //               << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos
       //               << ", " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos << ")" << Endl;
-      
+
       fVarScale[vit->first] = rpos - lpos;
    }
 
    fVar.clear();
 
-   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {      
+   for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {
       fEvent[ievent] = Scale(fEvent[ievent]);
-      
+
       for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
          fVar[ivar].push_back(fEvent[ievent].GetVar(ivar));
       }
@@ -616,7 +606,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
 {
    // scale each event variable so that rms of variables is approximately 1.0
    // this allows comparisons of variables with distinct scales and units
-   
+
    if (fVarScale.empty()) {
       return event;
    }
@@ -634,7 +624,7 @@ const TMVA::kNN::Event TMVA::kNN::ModulekNN::Scale(const Event &event) const
          Log() << kFATAL << "ModulekNN::Scale() - failed to find scale for " << ivar << Endl;
          continue;
       }
-      
+
       if (fit->second > 0.0) {
          vvec[ivar] = event.GetVar(ivar)/fit->second;
       }
@@ -668,7 +658,7 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
    os << "Printing " << fkNNList.size() << " nearest neighbors" << std::endl;
    for (List::const_iterator it = fkNNList.begin(); it != fkNNList.end(); ++it) {
       os << ++count << ": " << it->second << ": " << it->first->GetEvent() << std::endl;
-      
+
       const Event &event = it->first->GetEvent();
       for (UShort_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
          if (min.find(ivar) == min.end()) {
@@ -693,6 +683,6 @@ void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
          Log() << kINFO << "(var, min, max) = (" << i << "," << min[i] << ", " << max[i] << ")" << Endl;
       }
    }
-   
+
    os << "----------------------------------------------------------------------" << std::endl;
 }
diff --git a/tmva/src/Option.cxx b/tmva/src/Option.cxx
index 8f6bbf3d68e40..85cdfab59ce4e 100644
--- a/tmva/src/Option.cxx
+++ b/tmva/src/Option.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tmva $Id$   
+// @(#)root/tmva $Id$
 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss
 
 /**********************************************************************************
@@ -16,9 +16,9 @@
  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
  *                                                                                *
  * Copyright (c) 2005:                                                            *
- *      CERN, Switzerland                                                         * 
- *      U. of Victoria, Canada                                                    * 
- *      MPI-K Heidelberg, Germany                                                 * 
+ *      CERN, Switzerland                                                         *
+ *      U. of Victoria, Canada                                                    *
+ *      MPI-K Heidelberg, Germany                                                 *
  *      LAPP, Annecy, France                                                      *
  *                                                                                *
  * Redistribution and use in source and binary forms, with or without             *
@@ -29,11 +29,11 @@
 #include "TMVA/Option.h"
 
 //______________________________________________________________________
-TMVA::OptionBase::OptionBase( const TString& name, const TString& desc ) 
-   : TObject(), 
-     fName        ( name ), 
-     fNameAllLower( name ), 
-     fDescription ( desc ), 
+TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
+   : TObject(),
+     fName        ( name ),
+     fNameAllLower( name ),
+     fDescription ( desc ),
      fIsSet       ( kFALSE )
 {
    // constructor
@@ -41,7 +41,7 @@ TMVA::OptionBase::OptionBase( const TString& name, const TString& desc )
 }
 
 //______________________________________________________________________
-Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t ) 
+Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
 {
    // set value for option
    fIsSet = kTRUE;
@@ -52,7 +52,7 @@ Bool_t TMVA::OptionBase::SetValue( const TString& vs, Int_t )
 TMVA::MsgLogger& TMVA::OptionBase::Log()
 {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("Option",kDEBUG);  // message logger
+  thread_local MsgLogger logger("Option",kDEBUG);  // message logger
 #else
   static MsgLogger logger("Option",kDEBUG);  // message logger
 #endif
diff --git a/tmva/src/PDF.cxx b/tmva/src/PDF.cxx
index 875ca43f4b04b..ab46157d653ad 100644
--- a/tmva/src/PDF.cxx
+++ b/tmva/src/PDF.cxx
@@ -49,11 +49,6 @@
 const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
 const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
 const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
-#if __cplusplus > 199711L
-thread_local TMVA::PDF* TMVA::PDF::fgThisPDF  = 0;
-#else
-TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;
-#endif
 
 ClassImp(TMVA::PDF)
 
@@ -91,7 +86,7 @@ TMVA::PDF::PDF( const TString& name, Bool_t norm )
 {
    // default constructor needed for ROOT I/O
    fLogger   = new MsgLogger(this);
-   fgThisPDF = this;
+   GetThisPdfThreadLocal() = this;
 }
 
 //_______________________________________________________________________
@@ -248,8 +243,7 @@ TMVA::PDF::~PDF()
 //_______________________________________________________________________
 void TMVA::PDF::BuildPDF( const TH1* hist )
 {
-   fgThisPDF = this;
-
+   GetThisPdfThreadLocal() = this;
    // sanity check
    if (hist == NULL) Log() << kFATAL << "Called without valid histogram pointer!" << Endl;
 
@@ -1116,5 +1110,5 @@ std::istream& TMVA::operator>> ( std::istream& istr, PDF& pdf )
 TMVA::PDF*  TMVA::PDF::ThisPDF( void )
 {
    // return global "this" pointer of PDF
-   return fgThisPDF;
+   return GetThisPdfThreadLocal();
 }
diff --git a/tmva/src/TNeuron.cxx b/tmva/src/TNeuron.cxx
index 1099a9caa3ff1..5905a39fb4d88 100644
--- a/tmva/src/TNeuron.cxx
+++ b/tmva/src/TNeuron.cxx
@@ -151,7 +151,7 @@ void TMVA::TNeuron::CalculateDelta()
 void TMVA::TNeuron::SetInputCalculator(TNeuronInput* calculator)
 {
    // set input calculator
-   if (fInputCalculator != NULL) delete fInputCalculator; 
+   if (fInputCalculator != NULL) delete fInputCalculator;
    fInputCalculator = calculator;
 }
 
@@ -294,7 +294,7 @@ void TMVA::TNeuron::InitSynapseDeltas()
 }
 
 //______________________________________________________________________________
-void TMVA::TNeuron::PrintLinks(TObjArray* links) const 
+void TMVA::TNeuron::PrintLinks(TObjArray* links) const
 {
    // print an array of TSynapses, for debugging
 
@@ -308,7 +308,7 @@ void TMVA::TNeuron::PrintLinks(TObjArray* links) const
    Int_t numLinks = links->GetEntriesFast();
    for  (Int_t i = 0; i < numLinks; i++) {
       synapse = (TSynapse*)links->At(i);
-      Log() << kDEBUG <<  
+      Log() << kDEBUG <<
          "\t\t\tweighta: " << synapse->GetWeight()
            << "\t\tw-value: " << synapse->GetWeightedValue()
            << "\t\tw-delta: " << synapse->GetWeightedDelta()
@@ -333,10 +333,10 @@ void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
 }
 
 //______________________________________________________________________________
-TMVA::MsgLogger& TMVA::TNeuron::Log() const 
+TMVA::MsgLogger& TMVA::TNeuron::Log() const
 {
   #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
+  thread_local MsgLogger logger("TNeuron",kDEBUG);    //! message logger, static to save resources
 #else
   static MsgLogger logger("TNeuron",kDEBUG);                 //! message logger, static to save resources
 #endif
diff --git a/tmva/src/TSynapse.cxx b/tmva/src/TSynapse.cxx
index ab03d79f8b173..6e84557f836e2 100644
--- a/tmva/src/TSynapse.cxx
+++ b/tmva/src/TSynapse.cxx
@@ -110,7 +110,7 @@ void TMVA::TSynapse::CalculateDelta()
 TMVA::MsgLogger& TMVA::TSynapse::Log() const
 {
 #if __cplusplus > 199711L
-  static thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
+  thread_local MsgLogger logger("TSynapse");  //! message logger, static to save resources
 #else
   static MsgLogger logger("TSynapse");               //! message logger, static to save resources
 #endif

From ec6456e83565231c0a5a593e449984ce664eed7e Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Fri, 6 Mar 2015 18:33:42 +0100
Subject: [PATCH 169/200] - The code is now shown next to the picture - The
 output directories are defined in the Makefile - The .sh script are not
 needed anymore

---
 documentation/doxygen/Doxyfile         |  6 ++--
 documentation/doxygen/Makefile         | 12 ++++----
 documentation/doxygen/filter.cxx       | 38 ++++++++++++++++++-------
 documentation/doxygen/makeallimages.sh | 39 --------------------------
 documentation/doxygen/makedocdir.sh    | 10 -------
 documentation/doxygen/makeimage.C      |  5 ++--
 documentation/doxygen/makeimgdir.sh    |  9 ------
 documentation/doxygen/makemacrodir.sh  |  9 ------
 documentation/doxygen/makeoneimage.sh  |  3 --
 9 files changed, 41 insertions(+), 90 deletions(-)
 delete mode 100755 documentation/doxygen/makeallimages.sh
 delete mode 100755 documentation/doxygen/makedocdir.sh
 delete mode 100755 documentation/doxygen/makeimgdir.sh
 delete mode 100755 documentation/doxygen/makemacrodir.sh
 delete mode 100755 documentation/doxygen/makeoneimage.sh

diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile
index 8a3c0b3d3f652..f72e1d54a85e0 100644
--- a/documentation/doxygen/Doxyfile
+++ b/documentation/doxygen/Doxyfile
@@ -58,7 +58,7 @@ PROJECT_LOGO           = ./rootlogo.gif
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = /tmp/doxygen/rootdoc
+OUTPUT_DIRECTORY       = $(DOXYGEN_OUTPUT_DIRECTORY)
 
 # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and
@@ -863,7 +863,7 @@ EXCLUDE_SYMBOLS        =
 # that contain example code fragments that are included (see the \include
 # command).
 
-EXAMPLE_PATH           = /tmp/doxygen/rootdoc/macros
+EXAMPLE_PATH           = $(DOXYGEN_EXAMPLE_PATH)
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -1981,7 +1981,7 @@ EXPAND_ONLY_PREDEF     = NO
 # The default value is: YES.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-SEARCH_INCLUDES        = YES
+SEARCH_INCLUDES        = NO
 
 # The INCLUDE_PATH tag can be used to specify one or more directories that
 # contain include files that are not input files but should be processed by the
diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index 2f1df66910941..ded6d29b33edb 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -1,8 +1,8 @@
 
 .PHONY: filter doxygen clean
 
-docdir="$(shell . ./makedocdir.sh)"
-export OUTPUT_DIRECTORY=$(docdir)
+export DOXYGEN_OUTPUT_DIRECTORY=/tmp/doxygen/rootdoc
+export DOXYGEN_EXAMPLE_PATH=$(DOXYGEN_OUTPUT_DIRECTORY)/macros
 
 all: filter doxygen
 
@@ -10,10 +10,12 @@ filter:
 	`root-config --cxx` -o filter filter.cxx `root-config --libs --glibs --cflags`
 
 doxygen:
+	if [ ! -d $(DOXYGEN_OUTPUT_DIRECTORY) ]; then mkdir $(DOXYGEN_OUTPUT_DIRECTORY); fi
+	if [ ! -d $(DOXYGEN_EXAMPLE_PATH) ]; then mkdir $(DOXYGEN_EXAMPLE_PATH); fi
 	doxygen
+	rm c1*
+	rm stdout.dat
 
 clean:
-	rm -r $(docdir)
+	rm -r $(DOXYGEN_OUTPUT_DIRECTORY)
 	rm filter
-	rm c1*
-	rm stdout.dat
diff --git a/documentation/doxygen/filter.cxx b/documentation/doxygen/filter.cxx
index dfaf0ece04874..79765d55b42ca 100644
--- a/documentation/doxygen/filter.cxx
+++ b/documentation/doxygen/filter.cxx
@@ -70,6 +70,7 @@ TString gFileName;
 TString gLineString;
 TString gClassName;
 TString gImageName;
+TString gMacroName;
 TString gCwd;
 Bool_t  gHeader;
 Bool_t  gSource;
@@ -115,6 +116,7 @@ int main(int argc, char *argv[])
 
          printf("%s",gLineString.Data());
       }
+      return 0;
    }
 
    // Source file.
@@ -148,20 +150,27 @@ int main(int argc, char *argv[])
          }
 
          if (gLineString.Index("Begin_Macro") >= 0) {
-            gLineString = "<pre lang=\"cpp\">\n";
+            gLineString = "";
             gInMacro++;
          }
 
          if (gLineString.Index("End_Macro") >= 0) {
-            gLineString.ReplaceAll("End_Macro","</pre>\n");
+            gLineString.ReplaceAll("End_Macro","");
             gInMacro = 0;
          }
 
          printf("%s",gLineString.Data());
       }
+      return 0;
    }
 
-   return 1;
+   // Output anything not header nor source
+   while (fgets(gLine,255,f)) {
+      gLineString = gLine;
+      printf("%s",gLineString.Data());
+   }
+
+   return 0;
 }
 
 
@@ -229,26 +238,35 @@ void ExecuteMacro()
 {
    // Execute the macro in gLineString and produce the corresponding picture
 
+   // Retrieve the output directory
+   TString OutDir = gSystem->Getenv("DOXYGEN_OUTPUT_DIRECTORY");
+   OutDir.ReplaceAll("\"","");
+
    // Name of the next Image to be generated
    gImageName = TString::Format("%s_%3.3d.png", gClassName.Data()
                                               , gImageID++);
 
-   // Build the ROOT command to be executed.
+   // Retrieve the macro to be executed.
    if (gLineString.Index("../../..") >= 0) {
-      gLineString.ReplaceAll("../../..","root -l -b -q \"makeimage.C(\\\"../..");
+      gLineString.ReplaceAll("../../..","../..");
    } else {
-      gLineString.Prepend(TString::Format("root -l -b -q \"makeimage.C(\\\"%s/../doc/macros/",gCwd.Data()));
+      gLineString.Prepend(TString::Format("%s/../doc/macros/",gCwd.Data()));
    }
+   Int_t i1 = gLineString.Last('/')+1;
+   Int_t i2 = gLineString.Last('C');
+   gMacroName = gLineString(i1,i2-i1+1);
+
+   // Build the ROOT command to be executed.
+   gLineString.Prepend(TString::Format("root -l -b -q \"makeimage.C(\\\""));
    Int_t l = gLineString.Length();
-   TString OutDir = gSystem->Getenv("OUTPUT_DIRECTORY");
-   OutDir.ReplaceAll("\"","");
-   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s/html/%s\\\")\"",
+   gLineString.Replace(l-2,1,TString::Format("C\\\",\\\"%s/html/\\\",\\\"%s\\\")\"",
                                              OutDir.Data(),
                                              gImageName.Data()));
 
    ExecuteCommand(gLineString);
 
-   gLineString = TString::Format("\\image html %s\n",gImageName.Data());
+   gLineString = TString::Format("\\include %s\n\\image html %s\n", gMacroName.Data(),
+                                                                    gImageName.Data());
 }
 
 
diff --git a/documentation/doxygen/makeallimages.sh b/documentation/doxygen/makeallimages.sh
deleted file mode 100755
index 7a3210c1bd0fd..0000000000000
--- a/documentation/doxygen/makeallimages.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-./makeoneimage.sh ellipse       ../../tutorials/graphics     $1 $2
-./makeoneimage.sh piechart      ../../tutorials/graphics     $1 $2
-./makeoneimage.sh arrow         ../../tutorials/graphics     $1 $2
-./makeoneimage.sh crown         ../../tutorials/graphics     $1 $2
-./makeoneimage.sh feynman       ../../tutorials/graphics     $1 $2
-./makeoneimage.sh diamond       ../../tutorials/graphics     $1 $2
-./makeoneimage.sh gaxis         ../../tutorials/graphics     $1 $2
-./makeoneimage.sh gaxis2        ../../tutorials/graphics     $1 $2
-./makeoneimage.sh latex         ../../tutorials/graphics     $1 $2
-./makeoneimage.sh latex2        ../../tutorials/graphics     $1 $2
-./makeoneimage.sh latex3        ../../tutorials/graphics     $1 $2
-./makeoneimage.sh tmathtext     ../../tutorials/graphics     $1 $2
-./makeoneimage.sh tmathtext2    ../../tutorials/graphics     $1 $2
-./makeoneimage.sh pavetext      ../../tutorials/graphics     $1 $2
-./makeoneimage.sh timeonaxis    ../../tutorials/graphs       $1 $2
-./makeoneimage.sh timeonaxis2   ../../tutorials/graphs       $1 $2
-./makeoneimage.sh graphpolar2   ../../tutorials/graphs       $1 $2
-./makeoneimage.sh graphpolar3   ../../tutorials/graphs       $1 $2
-./makeoneimage.sh polyline      ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh legend1       ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh legend2       ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh legend3       ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh greekletters  ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh mathsymbols   ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh subsupscript  ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh subsupscript2 ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh fractions     ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh splitline     ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh roots         ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh accents       ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh slash         ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh bars          ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh style         ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh alignment     ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh kerning       ../../graf2d/graf/doc/macros $1 $2
-./makeoneimage.sh itbold        ../../graf2d/graf/doc/macros $1 $2
-
-# Clean up local directory
-rm c1.gif *.ps *.eps *.jpg *.png
diff --git a/documentation/doxygen/makedocdir.sh b/documentation/doxygen/makedocdir.sh
deleted file mode 100755
index c3c6ea6c3caad..0000000000000
--- a/documentation/doxygen/makedocdir.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-# Make the ouput directory for the doxygen output
-
-outdir=`grep "^OUTPUT_DIRECTORY" Doxyfile | sed -e "s/^.*= //"`
-
-if [ ! -d "$outdir" ]
-then
-   mkdir -p $outdir
-fi
-
-echo $outdir
diff --git a/documentation/doxygen/makeimage.C b/documentation/doxygen/makeimage.C
index 44d389e0c775c..59b15c9b5c36a 100644
--- a/documentation/doxygen/makeimage.C
+++ b/documentation/doxygen/makeimage.C
@@ -1,13 +1,14 @@
 // Generates the ImageName output of the macro MacroName
 
-void makeimage(const char *MacroName, const char *ImageName)
+void makeimage(const char *MacroName, const char *OutDir, const char *ImageName)
 {
    gROOT->ProcessLine(Form(".x %s",MacroName));
+   gSystem->Exec(TString::Format("cp %s %s../macros", MacroName, OutDir));
 
    TIter iCanvas(gROOT->GetListOfCanvases());
    TVirtualPad* pad = 0;
 
    while ((pad = (TVirtualPad*) iCanvas())) {
-      pad->SaveAs(ImageName);
+      pad->SaveAs(TString::Format("%s%s",OutDir,ImageName));
    }
 }
diff --git a/documentation/doxygen/makeimgdir.sh b/documentation/doxygen/makeimgdir.sh
deleted file mode 100755
index 89cd587b8eb0d..0000000000000
--- a/documentation/doxygen/makeimgdir.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-# Make the ouput directory for the images
-imgdir=`grep "^IMAGE_PATH" Doxyfile | sed -e "s/^.*= //"`
-
-if [ ! -d "$imgdir" ]
-then
-   mkdir -p $imgdir
-fi
-
-echo $imgdir
diff --git a/documentation/doxygen/makemacrodir.sh b/documentation/doxygen/makemacrodir.sh
deleted file mode 100755
index 214a987646163..0000000000000
--- a/documentation/doxygen/makemacrodir.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-# Make the ouput directory for the macros
-outdir=`grep "^EXAMPLE_PATH" Doxyfile | sed -e "s/^.*= //"`
-
-if [ ! -d "$outdir" ]
-then
-   mkdir -p $outdir
-fi
-
-echo $outdir
diff --git a/documentation/doxygen/makeoneimage.sh b/documentation/doxygen/makeoneimage.sh
deleted file mode 100755
index 4aae56d2e5718..0000000000000
--- a/documentation/doxygen/makeoneimage.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-root -b -l -q "makepng.C(\"$1\",\"$2\")"
-mv $1.png $3
-cp $2/$1.C $4

From 5d2d1e467c309009af120ba1bd9324fde8ed4e58 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Fri, 6 Mar 2015 18:38:03 +0100
Subject: [PATCH 170/200] - Not needed

---
 documentation/doxygen/makepng.C | 13 -------------
 1 file changed, 13 deletions(-)
 delete mode 100644 documentation/doxygen/makepng.C

diff --git a/documentation/doxygen/makepng.C b/documentation/doxygen/makepng.C
deleted file mode 100644
index 88bce6bb3e5f9..0000000000000
--- a/documentation/doxygen/makepng.C
+++ /dev/null
@@ -1,13 +0,0 @@
-// Generates the png output of the macro "macroname" located in "dirname"
-
-void makepng(const char *macroname, const char *dirname)
-{
-   gROOT->ProcessLine(Form(".x %s/%s.C",dirname,macroname));
-
-   TIter iCanvas(gROOT->GetListOfCanvases());
-   TVirtualPad* pad = 0;
-
-   while ((pad = (TVirtualPad*) iCanvas())) {
-      pad->SaveAs(TString::Format("%s.png", macroname));
-   }
-}

From 6ae53d36d2ffa581bb4ae389988d69141ca87eff Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Fri, 6 Mar 2015 20:09:45 +0100
Subject: [PATCH 171/200] Fix stringify. Indentation. Version quote for
 standalone cling.

---
 interpreter/cling/Makefile                        | 2 +-
 interpreter/cling/lib/Interpreter/Interpreter.cpp | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/interpreter/cling/Makefile b/interpreter/cling/Makefile
index ce3c948b27041..0f544bed9c97e 100644
--- a/interpreter/cling/Makefile
+++ b/interpreter/cling/Makefile
@@ -60,7 +60,7 @@ CXX.Flags += -fno-strict-aliasing
 
 # Determine cling's version:
 CLING_VERSION=$(shell cat $(PROJ_SRC_DIR)/$(CLING_LEVEL)/VERSION)
-CPP.Flags += -DCLING_VERSION='"$(CLING_VERSION) "'
+CPP.Flags += -DCLING_VERSION='$(CLING_VERSION)'
 
 ###
 # Cling Top Level specific stuff.
diff --git a/interpreter/cling/lib/Interpreter/Interpreter.cpp b/interpreter/cling/lib/Interpreter/Interpreter.cpp
index 222c11c8cc654..7e8004d18e1a0 100644
--- a/interpreter/cling/lib/Interpreter/Interpreter.cpp
+++ b/interpreter/cling/lib/Interpreter/Interpreter.cpp
@@ -47,7 +47,8 @@
 #include <string>
 #include <vector>
 
-#define stringify(s) #s
+#define stringify(s) stringifyx(s)
+#define stringifyx(s) #s
 
 using namespace clang;
 
@@ -221,7 +222,7 @@ namespace cling {
          I != E; ++I)
       m_IncrParser->commitTransaction(*I);
     // Disable suggestions for ROOT
-       bool showSuggestions = !llvm::StringRef(stringify(CLING_VERSION)).startswith("ROOT");
+    bool showSuggestions = !llvm::StringRef(stringify(CLING_VERSION)).startswith("ROOT");
     std::unique_ptr<InterpreterCallbacks>
        AutoLoadCB(new AutoloadCallback(this, showSuggestions));
     setCallbacks(std::move(AutoLoadCB));
@@ -241,7 +242,7 @@ namespace cling {
   }
 
   const char* Interpreter::getVersion() const {
-     return stringify(CLING_VERSION);
+    return stringify(CLING_VERSION);
   }
 
   void Interpreter::handleFrontendOptions() {

From 1e1ca12ef0d64365374cedf5375795463d0154a5 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Fri, 6 Mar 2015 20:24:48 +0100
Subject: [PATCH 172/200] No -pthread for Mac clang wich warns otherwise.

---
 core/utils/Module.mk | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/core/utils/Module.mk b/core/utils/Module.mk
index 72351142936b4..6d0aa0d4868bb 100644
--- a/core/utils/Module.mk
+++ b/core/utils/Module.mk
@@ -7,6 +7,10 @@
 
 MODNAME := utils
 
+ifneq ($(GCC_MAJOR),)
+LDPTHREAD := -pthread
+endif
+
 ifneq ($(HOST),)
 
 .PHONY: all-$(MODNAME) clean-$(MODNAME) distclean-$(MODNAME)
@@ -28,7 +32,7 @@ ROOTCLINGEXEEXTRAO = $(COREO) $(COREDO) $(IOO) $(IODO) $(THREADO) $(THREADDO) $(
 $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 	   $(CLINGMETAUTILSO) $(SNPRINTFO) $(CLINGO) $(ROOTCLINGEXEEXTRAO) \
            $(PCREDEP) $(CORELIBDEP)
-	$(LD) $(LDFLAGS) -pthread -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
 	   $(ROOTCLINGTCLINGO) $(CLINGMETAUTILSO) \
 	   $(SNPRINTFO)  $(CLINGO) $(ROOTCLINGEXEEXTRAO) $(CLINGLIBEXTRA) \
 	   $(RPATH) $(CILIBS) $(CORELIBEXTRA) $(PCRELDFLAGS) $(PCRELIB) \
@@ -36,7 +40,7 @@ $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 
 $(ROOTCLINGTMPEXE): $(CINTTMPO) $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) $(CLINGO)
-	$(LD) $(LDFLAGS) -pthread -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) \
 	   $(CINTTMPLIBS) $(CLINGO) $(CLINGLIBEXTRA) $(CILIBS)
 

From e67cf91e643d98ed2c704e8cab135fa84bacf2ee Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Mon, 23 Feb 2015 20:11:56 +0100
Subject: [PATCH 173/200] Make TClass::fStreamerImpl thread safe

The exact streamer implementation to use for a TClass is determined
late and therefore two threads could be doing the same work at the
same time.
---
 core/meta/inc/TClass.h   | 21 ++++++++--------
 core/meta/src/TClass.cxx | 54 +++++++++++++++++++++-------------------
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index cfe806e27916d..588711afffc5c 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -241,8 +241,8 @@ friend class TProtoClass;
    TVirtualRefProxy  *fRefProxy;        //!Pointer to reference proxy if this class represents a reference
    ROOT::TSchemaRuleSet *fSchemaRules;  //! Schema evolution rules
 
-   typedef void (TClass::*StreamerImpl_t)(void *obj, TBuffer &b, const TClass *onfile_class) const;
-   mutable StreamerImpl_t fStreamerImpl;//! Pointer to the function implementing the right streaming behavior for the class represented by this object.
+   typedef void (*StreamerImpl_t)(const TClass* ths, void *obj, TBuffer &b, const TClass *onfile_class);
+   mutable std::atomic<StreamerImpl_t> fStreamerImpl;//! Pointer to the function implementing the right streaming behavior for the class represented by this object.
 
    TListOfFunctions  *GetMethodList();
    TMethod           *GetClassMethod(Long_t faddr);
@@ -267,13 +267,13 @@ friend class TProtoClass;
    void SetStreamerImpl();
 
    // Various implementation for TClass::Stramer
-   void StreamerExternal(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerTObject(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerTObjectInitialized(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerTObjectEmulated(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerInstrumented(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerStreamerInfo(void *object, TBuffer &b, const TClass *onfile_class) const;
-   void StreamerDefault(void *object, TBuffer &b, const TClass *onfile_class) const;
+   static void StreamerExternal(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObject(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObjectInitialized(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObjectEmulated(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerInstrumented(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerStreamerInfo(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerDefault(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
 
    static IdMap_t    *GetIdMap();       //Map from typeid to TClass pointer
    static DeclIdMap_t *GetDeclIdMap();  //Map from DeclId_t to TClass pointer
@@ -532,7 +532,8 @@ friend class TProtoClass;
    inline void        Streamer(void *obj, TBuffer &b, const TClass *onfile_class = 0) const
    {
       // Inline for performance, skipping one function call.
-      (this->*fStreamerImpl)(obj,b,onfile_class);
+      auto t = fStreamerImpl.load();
+      t(this,obj,b,onfile_class);
    }
 
    ClassDef(TClass,0)  //Dictionary containing class information
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index dcd7e1c90e3fc..d679c992c4ebf 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -6048,64 +6048,64 @@ Int_t TClass::WriteBuffer(TBuffer &b, void *pointer, const char * /*info*/)
 }
 
 //______________________________________________________________________________
-void TClass::StreamerExternal(void *object, TBuffer &b, const TClass *onfile_class) const
+void TClass::StreamerExternal(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class) 
 {
    //There is special streamer for the class
 
    //      case kExternal:
    //      case kExternal|kEmulatedStreamer:
 
-   TClassStreamer *streamer = gThreadTsd ? GetStreamer() : fStreamer;
+   TClassStreamer *streamer = gThreadTsd ? ths->GetStreamer() : ths->fStreamer;
    streamer->Stream(b,object,onfile_class);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObject(void *object, TBuffer &b, const TClass * /* onfile_class */) const
+void TClass::StreamerTObject(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of TObjects
 
    // case kTObject:
 
-   if (!fIsOffsetStreamerSet) {
-      CalculateStreamerOffset();
+   if (!ths->fIsOffsetStreamerSet) {
+      ths->CalculateStreamerOffset();
    }
-   TObject *tobj = (TObject*)((Long_t)object + fOffsetStreamer);
+   TObject *tobj = (TObject*)((Long_t)object + ths->fOffsetStreamer);
    tobj->Streamer(b);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObjectInitialized(void *object, TBuffer &b, const TClass * /* onfile_class */) const
+void TClass::StreamerTObjectInitialized(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of TObjects when fIsOffsetStreamerSet is known to have been set.
 
-   TObject *tobj = (TObject*)((Long_t)object + fOffsetStreamer);
+   TObject *tobj = (TObject*)((Long_t)object + ths->fOffsetStreamer);
    tobj->Streamer(b);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObjectEmulated(void *object, TBuffer &b, const TClass *onfile_class) const
+void TClass::StreamerTObjectEmulated(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Case of TObjects when we do not have the library defining the class.
 
    // case kTObject|kEmulatedStreamer :
    if (b.IsReading()) {
-      b.ReadClassEmulated(this, object, onfile_class);
+      b.ReadClassEmulated(ths, object, onfile_class);
    } else {
-      b.WriteClassBuffer(this, object);
+      b.WriteClassBuffer(ths, object);
    }
 }
 
 //______________________________________________________________________________
-void TClass::StreamerInstrumented(void *object, TBuffer &b, const TClass * /* onfile_class */) const
+void TClass::StreamerInstrumented(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of instrumented class with a library
 
    // case kInstrumented:
-   fStreamerFunc(b,object);
+   ths->fStreamerFunc(b,object);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerStreamerInfo(void *object, TBuffer &b, const TClass *onfile_class) const
+void TClass::StreamerStreamerInfo(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Case of where we should directly use the StreamerInfo.
    //    case kForeign:
@@ -6114,29 +6114,32 @@ void TClass::StreamerStreamerInfo(void *object, TBuffer &b, const TClass *onfile
    //    case kEmulatedStreamer:
 
    if (b.IsReading()) {
-      b.ReadClassBuffer(this, object, onfile_class);
+      b.ReadClassBuffer(ths, object, onfile_class);
       //ReadBuffer (b, object);
    } else {
       //WriteBuffer(b, object);
-      b.WriteClassBuffer(this, object);
+      b.WriteClassBuffer(ths, object);
    }
 }
 
 //______________________________________________________________________________
-void TClass::StreamerDefault(void *object, TBuffer &b, const TClass *onfile_class) const
+void TClass::StreamerDefault(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Default streaming in cases where either we have no way to know what to do
    // or if Property() has not yet been called.
 
-   if (fProperty==(-1)) {
-      Property();
-      if (fStreamerImpl == &TClass::StreamerDefault) {
-         Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", fStreamerType);
-      } else {
-         (this->*fStreamerImpl)(object,b,onfile_class);
-      }
+   if (ths->fProperty==(-1)) {
+      ths->Property();
+   }
+
+   // We could get here because after this thread started StreamerDefault
+   // *and* before check fProperty, another thread might have call Property
+   // and this fProperty when we read it, is not -1 and fStreamerImpl is
+   // supposed to be set properly (no longer pointing to the default).
+   if (ths->fStreamerImpl == &TClass::StreamerDefault) {
+     ths->Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", ths->fStreamerType);
    } else {
-      Fatal("StreamerDefault", "fStreamerType not properly initialized (%d)", fStreamerType);
+     (*ths->fStreamerImpl)(ths,object,b,onfile_class);
    }
 }
 
@@ -6174,6 +6177,7 @@ void TClass::SetStreamerFunc(ClassStreamerFunc_t strm)
 {
    // Set a wrapper/accessor function around this class custom streamer.
 
+   R__LOCKGUARD(gInterpreterMutex);
    if (fProperty != -1 &&
        ( (fStreamerFunc == 0 && strm != 0) || (fStreamerFunc != 0 && strm == 0) ) )
    {

From 0bf5c81a632abb6b46add2d0ab0073d276f759cc Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 18:37:46 -0600
Subject: [PATCH 174/200] Coding conventions

---
 core/meta/inc/TClass.h   | 18 ++++++++--------
 core/meta/src/TClass.cxx | 44 ++++++++++++++++++++--------------------
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index 588711afffc5c..be382430f9fbd 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -241,8 +241,8 @@ friend class TProtoClass;
    TVirtualRefProxy  *fRefProxy;        //!Pointer to reference proxy if this class represents a reference
    ROOT::TSchemaRuleSet *fSchemaRules;  //! Schema evolution rules
 
-   typedef void (*StreamerImpl_t)(const TClass* ths, void *obj, TBuffer &b, const TClass *onfile_class);
-   mutable std::atomic<StreamerImpl_t> fStreamerImpl;//! Pointer to the function implementing the right streaming behavior for the class represented by this object.
+   typedef void (*StreamerImpl_t)(const TClass* pThis, void *obj, TBuffer &b, const TClass *onfile_class);
+   mutable std::atomic<StreamerImpl_t> fStreamerImpl;  //! Pointer to the function implementing the right streaming behavior for the class represented by this object.
 
    TListOfFunctions  *GetMethodList();
    TMethod           *GetClassMethod(Long_t faddr);
@@ -267,13 +267,13 @@ friend class TProtoClass;
    void SetStreamerImpl();
 
    // Various implementation for TClass::Stramer
-   static void StreamerExternal(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerTObject(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerTObjectInitialized(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerTObjectEmulated(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerInstrumented(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerStreamerInfo(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
-   static void StreamerDefault(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerExternal(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObject(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObjectInitialized(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerTObjectEmulated(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerStreamerInfo(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
+   static void StreamerDefault(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class);
 
    static IdMap_t    *GetIdMap();       //Map from typeid to TClass pointer
    static DeclIdMap_t *GetDeclIdMap();  //Map from DeclId_t to TClass pointer
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index d679c992c4ebf..16a0fecd8ac53 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -6048,64 +6048,64 @@ Int_t TClass::WriteBuffer(TBuffer &b, void *pointer, const char * /*info*/)
 }
 
 //______________________________________________________________________________
-void TClass::StreamerExternal(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class) 
+void TClass::StreamerExternal(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
 {
    //There is special streamer for the class
 
    //      case kExternal:
    //      case kExternal|kEmulatedStreamer:
 
-   TClassStreamer *streamer = gThreadTsd ? ths->GetStreamer() : ths->fStreamer;
+   TClassStreamer *streamer = gThreadTsd ? pThis->GetStreamer() : pThis->fStreamer;
    streamer->Stream(b,object,onfile_class);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObject(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
+void TClass::StreamerTObject(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of TObjects
 
    // case kTObject:
 
-   if (!ths->fIsOffsetStreamerSet) {
-      ths->CalculateStreamerOffset();
+   if (!pThis->fIsOffsetStreamerSet) {
+      pThis->CalculateStreamerOffset();
    }
-   TObject *tobj = (TObject*)((Long_t)object + ths->fOffsetStreamer);
+   TObject *tobj = (TObject*)((Long_t)object + pThis->fOffsetStreamer);
    tobj->Streamer(b);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObjectInitialized(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
+void TClass::StreamerTObjectInitialized(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of TObjects when fIsOffsetStreamerSet is known to have been set.
 
-   TObject *tobj = (TObject*)((Long_t)object + ths->fOffsetStreamer);
+   TObject *tobj = (TObject*)((Long_t)object + pThis->fOffsetStreamer);
    tobj->Streamer(b);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerTObjectEmulated(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
+void TClass::StreamerTObjectEmulated(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Case of TObjects when we do not have the library defining the class.
 
    // case kTObject|kEmulatedStreamer :
    if (b.IsReading()) {
-      b.ReadClassEmulated(ths, object, onfile_class);
+      b.ReadClassEmulated(pThis, object, onfile_class);
    } else {
-      b.WriteClassBuffer(ths, object);
+      b.WriteClassBuffer(pThis, object);
    }
 }
 
 //______________________________________________________________________________
-void TClass::StreamerInstrumented(const TClass* ths, void *object, TBuffer &b, const TClass * /* onfile_class */)
+void TClass::StreamerInstrumented(const TClass* pThis, void *object, TBuffer &b, const TClass * /* onfile_class */)
 {
    // Case of instrumented class with a library
 
    // case kInstrumented:
-   ths->fStreamerFunc(b,object);
+   pThis->fStreamerFunc(b,object);
 }
 
 //______________________________________________________________________________
-void TClass::StreamerStreamerInfo(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
+void TClass::StreamerStreamerInfo(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Case of where we should directly use the StreamerInfo.
    //    case kForeign:
@@ -6114,32 +6114,32 @@ void TClass::StreamerStreamerInfo(const TClass* ths, void *object, TBuffer &b, c
    //    case kEmulatedStreamer:
 
    if (b.IsReading()) {
-      b.ReadClassBuffer(ths, object, onfile_class);
+      b.ReadClassBuffer(pThis, object, onfile_class);
       //ReadBuffer (b, object);
    } else {
       //WriteBuffer(b, object);
-      b.WriteClassBuffer(ths, object);
+      b.WriteClassBuffer(pThis, object);
    }
 }
 
 //______________________________________________________________________________
-void TClass::StreamerDefault(const TClass* ths, void *object, TBuffer &b, const TClass *onfile_class)
+void TClass::StreamerDefault(const TClass* pThis, void *object, TBuffer &b, const TClass *onfile_class)
 {
    // Default streaming in cases where either we have no way to know what to do
    // or if Property() has not yet been called.
 
-   if (ths->fProperty==(-1)) {
-      ths->Property();
+   if (pThis->fProperty==(-1)) {
+      pThis->Property();
    }
 
    // We could get here because after this thread started StreamerDefault
    // *and* before check fProperty, another thread might have call Property
    // and this fProperty when we read it, is not -1 and fStreamerImpl is
    // supposed to be set properly (no longer pointing to the default).
-   if (ths->fStreamerImpl == &TClass::StreamerDefault) {
-     ths->Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", ths->fStreamerType);
+   if (pThis->fStreamerImpl == &TClass::StreamerDefault) {
+      pThis->Fatal("StreamerDefault", "fStreamerImpl not properly initialized (%d)", pThis->fStreamerType);
    } else {
-     (*ths->fStreamerImpl)(ths,object,b,onfile_class);
+      (*pThis->fStreamerImpl)(pThis,object,b,onfile_class);
    }
 }
 

From 6b55a5d460478c5d0c00ddaf6f2758dd02d4ecc8 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Sun, 1 Mar 2015 18:33:09 +0100
Subject: [PATCH 175/200] Convert statics to thread_local for function return
 values

statics were being used to manage memory for buffers which were
holding return values from functions. When multiple threads are
being used this causes interference. Changing to thread_local
avoids the problem.
---
 core/meta/src/TCling.cxx              | 21 ++++++++++++++-------
 core/meta/src/TClingMethodArgInfo.cxx |  6 +++---
 core/meta/src/TClingMethodInfo.cxx    |  6 +++---
 core/meta/src/TClingTypeInfo.cxx      |  6 +++---
 core/meta/src/TClingTypedefInfo.cxx   |  4 ++--
 core/meta/src/TDataType.cxx           |  2 +-
 6 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index aa4238c387fe7..b2d895fb2d9ad 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -171,6 +171,13 @@ extern "C" {
 #define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
 #define dlopen(library_name, flags) ::LoadLibraryEx(library_name, NULL, DONT_RESOLVE_DLL_REFERENCES)
 #define dlclose(library) ::FreeLibrary((HMODULE)library)
+char *dlerror() {
+   thread_local char Msg[1000];
+   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
+                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), Msg,
+                 sizeof(Msg), NULL);
+   return Msg;
+}
 #define thread_local static __declspec(thread)
 #endif
 #endif
@@ -1151,7 +1158,7 @@ static const char *FindLibraryName(void (*func)())
    }
 
    HMODULE hMod = (HMODULE) mbi.AllocationBase;
-   static char moduleName[MAX_PATH];
+   thread_local char moduleName[MAX_PATH];
 
    if (!GetModuleFileNameA (hMod, moduleName, sizeof (moduleName)))
    {
@@ -1381,7 +1388,7 @@ void TCling::RegisterModule(const char* modulename,
    // The value of 'triggerFunc' is used to find the shared library location.
 
    // rootcling also uses TCling for generating the dictionary ROOT files.
-   static bool fromRootCling = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
+   static const bool fromRootCling = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
    // We need the dictionary initialization but we don't want to inject the
    // declarations into the interpreter, except for those we really need for
    // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
@@ -1949,7 +1956,7 @@ void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
       return;
    }
 
-   static TClassRef clRefString("std::string");
+   static const TClassRef clRefString("std::string");
    if (clRefString == cl) {
       // We stream std::string without going through members..
       return;
@@ -5855,7 +5862,7 @@ Bool_t TCling::LoadText(const char* text) const
 const char* TCling::MapCppName(const char* name) const
 {
    // Interface to cling function
-   static std::string buffer;
+   thread_local std::string buffer;
    ROOT::TMetaUtils::GetCppName(buffer,name);
    return buffer.c_str();
 }
@@ -6538,7 +6545,7 @@ const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
 const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
 {
    TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
-   static std::string output;
+   thread_local std::string output;
    TClinginfo->FullName(output,*fNormalizedCtxt);
    return output.c_str();
 }
@@ -6653,7 +6660,7 @@ Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
 const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
 {
    TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
-   static std::string output;
+   thread_local std::string output;
    TClinginfo->FullName(output,*fNormalizedCtxt);
    return output.c_str();
 }
@@ -7131,7 +7138,7 @@ TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
 const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
 {
    TClingMethodInfo* info = (TClingMethodInfo*) minfo;
-   static TString mangled_name;
+   thread_local  TString mangled_name;
    mangled_name = info->GetMangledName();
    return mangled_name;
 }
diff --git a/core/meta/src/TClingMethodArgInfo.cxx b/core/meta/src/TClingMethodArgInfo.cxx
index facf0b7c225c8..fca49305439a6 100644
--- a/core/meta/src/TClingMethodArgInfo.cxx
+++ b/core/meta/src/TClingMethodArgInfo.cxx
@@ -128,7 +128,7 @@ const char *TClingMethodArgInfo::DefaultValue() const
    }
    clang::ASTContext &context = pvd->getASTContext();
    clang::PrintingPolicy policy(context.getPrintingPolicy());
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
    llvm::raw_string_ostream out(buf);
    if (!expr) {
@@ -165,7 +165,7 @@ const char *TClingMethodArgInfo::Name() const
    }
    const clang::FunctionDecl *fd = fMethodInfo->GetMethodDecl();
    const clang::ParmVarDecl *pvd = fd->getParamDecl(fIdx);
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
    clang::PrintingPolicy policy(pvd->getASTContext().getPrintingPolicy());
    llvm::raw_string_ostream stream(buf);
@@ -176,7 +176,7 @@ const char *TClingMethodArgInfo::Name() const
 
 const TClingTypeInfo *TClingMethodArgInfo::Type() const
 {
-   static TClingTypeInfo ti(fInterp);
+   thread_local TClingTypeInfo ti(fInterp);
    if (!IsValid()) {
       return &ti;
    }
diff --git a/core/meta/src/TClingMethodInfo.cxx b/core/meta/src/TClingMethodInfo.cxx
index e84487cb89ca9..9a164f86a8fe5 100644
--- a/core/meta/src/TClingMethodInfo.cxx
+++ b/core/meta/src/TClingMethodInfo.cxx
@@ -443,7 +443,7 @@ long TClingMethodInfo::ExtraProperty() const
 
 TClingTypeInfo *TClingMethodInfo::Type() const
 {
-   static TClingTypeInfo ti(fInterp);
+   thread_local TClingTypeInfo ti(fInterp);
    if (!IsValid()) {
       ti.Init(clang::QualType());
       return &ti;
@@ -489,7 +489,7 @@ const char *TClingMethodInfo::GetPrototype(const ROOT::TMetaUtils::TNormalizedCt
    if (!IsValid()) {
       return 0;
    }
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
    buf += Type()->Name();
    buf += ' ';
@@ -542,7 +542,7 @@ const char *TClingMethodInfo::Name(const ROOT::TMetaUtils::TNormalizedCtxt &norm
    if (!IsValid()) {
       return 0;
    }
-   static std::string buf;
+   thread_local std::string buf;
    ((TCling*)gCling)->GetFunctionName(GetMethodDecl(),buf);
    return buf.c_str();
 }
diff --git a/core/meta/src/TClingTypeInfo.cxx b/core/meta/src/TClingTypeInfo.cxx
index aef704fc43ada..83104f8f4de65 100644
--- a/core/meta/src/TClingTypeInfo.cxx
+++ b/core/meta/src/TClingTypeInfo.cxx
@@ -103,7 +103,7 @@ const char *TClingTypeInfo::Name() const
       return "";
    }
    // Note: This *must* be static because we are returning a pointer inside it!
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
 
    ROOT::TMetaUtils::GetFullyQualifiedTypeName(buf,fQualType,*fInterp);
@@ -276,7 +276,7 @@ const char *TClingTypeInfo::StemName() const
       break;
    }
    // Note: This *must* be static because we are returning a pointer inside it.
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
    clang::PrintingPolicy Policy(fInterp->getCI()->getASTContext().
                                 getPrintingPolicy());
@@ -294,7 +294,7 @@ const char *TClingTypeInfo::TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &no
       return 0;
    }
    // Note: This *must* be static because we are returning a pointer inside it.
-   static std::string buf;
+   thread_local std::string buf;
    buf.clear();
 
    ROOT::TMetaUtils::GetNormalizedName(buf,fQualType, *fInterp, normCtxt);
diff --git a/core/meta/src/TClingTypedefInfo.cxx b/core/meta/src/TClingTypedefInfo.cxx
index 202b7c855a847..0ed276bfd114c 100644
--- a/core/meta/src/TClingTypedefInfo.cxx
+++ b/core/meta/src/TClingTypedefInfo.cxx
@@ -271,7 +271,7 @@ const char *TClingTypedefInfo::TrueName(const ROOT::TMetaUtils::TNormalizedCtxt
       return "(unknown)";
    }
    // Note: This must be static because we return a pointer to the internals.
-   static std::string truename;
+   thread_local std::string truename;
    truename.clear();
    const clang::TypedefNameDecl *td = llvm::dyn_cast<clang::TypedefNameDecl>(fDecl);
    clang::QualType underlyingType = td->getUnderlyingType();
@@ -292,7 +292,7 @@ const char *TClingTypedefInfo::Name() const
       return "(unknown)";
    }
    // Note: This must be static because we return a pointer to the internals.
-   static std::string fullname;
+   thread_local std::string fullname;
    fullname.clear();
    const clang::TypedefNameDecl *td = llvm::dyn_cast<clang::TypedefNameDecl>(fDecl);
    const clang::ASTContext &ctxt = fDecl->getASTContext();
diff --git a/core/meta/src/TDataType.cxx b/core/meta/src/TDataType.cxx
index bc417e0da30f9..b634f8381ce06 100644
--- a/core/meta/src/TDataType.cxx
+++ b/core/meta/src/TDataType.cxx
@@ -232,7 +232,7 @@ const char *TDataType::AsString(void *buf) const
    // Return string containing value in buffer formatted according to
    // the basic data type. The result needs to be used or copied immediately.
 
-   static TString line(81);
+   thread_local TString line(81);
    const char *name;
 
    if (fInfo) {

From 0710687308c4376363d723bb725cbbc57e6861d3 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Sun, 1 Mar 2015 18:35:29 +0100
Subject: [PATCH 176/200] Make list of enums from TClass thread safe

The list of enums from TClass are not handled immutably. If the list
already is filled then we return that one. If the list is not filled
and we are told not to load it then we return an empty list. Else
we create a new list and fill it, cache that value and then return it.
In this way once the list is handed out to a caller it is not changed.
---
 core/meta/inc/TClass.h        |  2 +-
 core/meta/src/TClass.cxx      | 31 ++++++++++++++++++++++---------
 core/meta/src/TProtoClass.cxx |  9 ++++++---
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index be382430f9fbd..eaa457f8eaf84 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -185,7 +185,7 @@ friend class TProtoClass;
    TList             *fRealData;        //linked list for persistent members including base classes
    TList             *fBase;            //linked list for base classes
    TListOfDataMembers*fData;            //linked list for data members
-   TListOfEnums      *fEnums;           //linked list for the enums
+   std::atomic<TListOfEnums*> fEnums;       //linked list for the enums
    TListOfFunctionTemplates *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
    std::atomic<TListOfFunctions*> fMethod;          //linked list for methods
    TViewPubDataMembers*fAllPubData;      //all public data members (including from base classes)
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 16a0fecd8ac53..8191304777bf0 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -1550,8 +1550,8 @@ TClass::~TClass()
    delete fData;   fData = 0;
 
    if (fEnums)
-      fEnums->Delete();
-   delete fEnums; fEnums = 0;
+      (*fEnums).Delete();
+   delete fEnums.load(); fEnums = 0;
 
    if (fFuncTemplate)
       fFuncTemplate->Delete();
@@ -3327,12 +3327,25 @@ TList *TClass::GetListOfBases()
 TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
 {
    // Return list containing the TEnums of a class.
+   auto temp = fEnums.load();
+   if(temp) {
+      return temp;
+   }
 
-   R__LOCKGUARD(gInterpreterMutex);
+   if(not load) {
+      //no one is supposed to modify the returned results
+      static TList s_list;
+      return &s_list;
+   }
 
-   if (!fEnums) fEnums = new TListOfEnums(this);
-   if (load) fEnums->Load();
-   return fEnums;
+   R__LOCKGUARD(gInterpreterMutex);
+   if(fEnums) {
+      return fEnums.load();
+   }
+   temp = new TListOfEnums(this);
+   temp->Load();
+   fEnums = temp;
+   return temp;
 }
 
 //______________________________________________________________________________
@@ -3754,8 +3767,8 @@ void TClass::ResetCaches()
    // Not owning lists, don't call Delete(), but unload
    if (fData)
       fData->Unload();
-   if (fEnums)
-      fEnums->Unload();
+   if (fEnums.load())
+      (*fEnums).Unload();
    if (fMethod.load())
       (*fMethod).Unload();
 
@@ -5637,7 +5650,7 @@ void TClass::SetUnloaded()
       fData->Unload();
    }
    if (fEnums) {
-      fEnums->Unload();
+      (*fEnums).Unload();
    }
 
    if (fState <= kForwardDeclared && fStreamerInfo->GetEntries() != 0) {
diff --git a/core/meta/src/TProtoClass.cxx b/core/meta/src/TProtoClass.cxx
index 258ab39b22fef..a964574d3d031 100644
--- a/core/meta/src/TProtoClass.cxx
+++ b/core/meta/src/TProtoClass.cxx
@@ -258,9 +258,12 @@ Bool_t TProtoClass::FillTClass(TClass* cl) {
 
    // We need to fill enums one by one to initialise the internal map which is
    // transient
-   cl->fEnums = new TListOfEnums();
-   for (TObject* enumAsTObj : *fEnums){
-      cl->fEnums->Add((TEnum*) enumAsTObj);
+   {
+      auto temp = new TListOfEnums();
+      for (TObject* enumAsTObj : *fEnums){
+         temp->Add((TEnum*) enumAsTObj);
+      }
+      cl->fEnums = temp;
    }
   
    cl->fSizeof = fSizeof;

From 93fcd2321194cb80aa38359cf8433e5c0e4f328b Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Mon, 2 Mar 2015 23:25:43 +0100
Subject: [PATCH 177/200] Thread-safe interaction with all enum lists

This extends the previous work on enum thread-safety to encompass
all the ways the enums can be scoped.
---
 core/base/src/TROOT.cxx                |   5 +-
 core/meta/inc/LinkDef.h                |   2 +
 core/meta/inc/TListOfEnums.h           |  63 ++---
 core/meta/inc/TListOfEnumsWithLock.h   | 103 ++++++++
 core/meta/src/TClass.cxx               |  20 +-
 core/meta/src/TListOfEnums.cxx         |  20 +-
 core/meta/src/TListOfEnumsWithLock.cxx | 326 +++++++++++++++++++++++++
 7 files changed, 488 insertions(+), 51 deletions(-)
 create mode 100644 core/meta/inc/TListOfEnumsWithLock.h
 create mode 100644 core/meta/src/TListOfEnumsWithLock.cxx

diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index ed29862869abf..e17b6cf54fcbc 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -124,7 +124,7 @@ char *dlerror() {
 #include "TInterpreter.h"
 #include "TListOfTypes.h"
 #include "TListOfDataMembers.h"
-#include "TListOfEnums.h"
+#include "TListOfEnumsWithLock.h"
 #include "TListOfFunctions.h"
 #include "TListOfFunctionTemplates.h"
 #include "TFunctionTemplate.h"
@@ -1380,8 +1380,9 @@ TObject *TROOT::GetGeometry(const char *name) const
 //______________________________________________________________________________
 TCollection *TROOT::GetListOfEnums()
 {
+   R__LOCKGUARD2(gROOTMutex);
    if(!fEnums) {
-      fEnums = new TListOfEnums(0);
+      fEnums = new TListOfEnumsWithLock(0);
    }
    return fEnums;
 }
diff --git a/core/meta/inc/LinkDef.h b/core/meta/inc/LinkDef.h
index 24189698605e2..3025936a54ae0 100644
--- a/core/meta/inc/LinkDef.h
+++ b/core/meta/inc/LinkDef.h
@@ -70,6 +70,8 @@
 #pragma link C++ class TListOfFunctionTemplates+;
 #pragma link C++ class TListOfDataMembers-;
 #pragma link C++ class TListOfEnums+;
+#pragma link C++ class TListOfEnumsWithLock+;
+#pragma link C++ class TListOfEnumsWithLockIter;
 //for new protoclasses
 #pragma link C++ class std::vector<TDataMember * >+;
 #pragma link C++ class std::vector<TProtoClass::TProtoRealData >+;
diff --git a/core/meta/inc/TListOfEnums.h b/core/meta/inc/TListOfEnums.h
index b0e94a829cbc3..156ce01e959b3 100644
--- a/core/meta/inc/TListOfEnums.h
+++ b/core/meta/inc/TListOfEnums.h
@@ -36,6 +36,10 @@ class TEnum;
 class TListOfEnums : public THashList
 {
 private:
+   friend class TCling;
+   friend class TClass;
+   friend class TProtoClass;
+
    TClass    *fClass; //! Context of this list.  Not owned.
 
    TExMap    *fIds;      //! Map from DeclId_t to TEnum*
@@ -43,46 +47,49 @@ class TListOfEnums : public THashList
    Bool_t     fIsLoaded; //! Mark whether Load was executed.
    ULong64_t  fLastLoadMarker; //! Represent interpreter state when we last did a full load.
 
-   TListOfEnums(const TListOfEnums&);              // not implemented
-   TListOfEnums& operator=(const TListOfEnums&);   // not implemented
+   TListOfEnums(const TListOfEnums&) = delete;
+   TListOfEnums& operator=(const TListOfEnums&) = delete;
 
    void       MapObject(TObject *obj);
    void       UnmapObject(TObject *obj);
 
+   void Load();
+   void Unload();
+   void Unload(TEnum *e);
+   void       SetClass(TClass* cl) { fClass = cl; }
+
 public:
    typedef TDictionary::DeclId_t DeclId_t;
 
-   TListOfEnums(TClass *cl = 0);
-   ~TListOfEnums();
-
-   virtual void Clear(Option_t *option);
-   virtual void Delete(Option_t *option="");
+protected:
+   TClass* GetClass() const {return fClass;}
+   TExMap* GetIds() { return fIds;}
+   TEnum* FindUnloaded(const char* name) { return (TEnum*)fUnloaded->FindObject(name);}
+   TEnum *Get(DeclId_t id, const char *name);
 
-   using THashList::FindObject;
-   virtual TObject   *FindObject(const char *name) const;
+public:
+   TListOfEnums(TClass *cl = 0);
+   ~TListOfEnums() override;
 
    TEnum     *Find(DeclId_t id) const;
-   TEnum     *Get(DeclId_t id, const char *name);
 
-   Bool_t     IsLoaded() const { return fIsLoaded; }
-   void       AddFirst(TObject *obj);
-   void       AddFirst(TObject *obj, Option_t *opt);
-   void       AddLast(TObject *obj);
-   void       AddLast(TObject *obj, Option_t *opt);
-   void       AddAt(TObject *obj, Int_t idx);
-   void       AddAfter(const TObject *after, TObject *obj);
-   void       AddAfter(TObjLink *after, TObject *obj);
-   void       AddBefore(const TObject *before, TObject *obj);
-   void       AddBefore(TObjLink *before, TObject *obj);
-
-   void       RecursiveRemove(TObject *obj);
-   TObject   *Remove(TObject *obj);
-   TObject   *Remove(TObjLink *lnk);
+   void Clear(Option_t *option) override;
+   void Delete(Option_t *option="") override;
 
-   void Load();
-   void Unload();
-   void Unload(TEnum *e);
-   void       SetClass(TClass* cl) { fClass = cl; }
+   Bool_t     IsLoaded() const { return fIsLoaded; }
+   void       AddFirst(TObject *obj) override;
+   void       AddFirst(TObject *obj, Option_t *opt) override;
+   void       AddLast(TObject *obj) override;
+   void       AddLast(TObject *obj, Option_t *opt) override;
+   void       AddAt(TObject *obj, Int_t idx) override;
+   void       AddAfter(const TObject *after, TObject *obj) override;
+   void       AddAfter(TObjLink *after, TObject *obj) override;
+   void       AddBefore(const TObject *before, TObject *obj) override;
+   void       AddBefore(TObjLink *before, TObject *obj) override;
+
+   void       RecursiveRemove(TObject *obj) override;
+   TObject   *Remove(TObject *obj) override;
+   TObject   *Remove(TObjLink *lnk) override;
 
    ClassDef(TListOfEnums,2);  // List of TDataMembers for a class
 };
diff --git a/core/meta/inc/TListOfEnumsWithLock.h b/core/meta/inc/TListOfEnumsWithLock.h
new file mode 100644
index 0000000000000..458a3ebd441ca
--- /dev/null
+++ b/core/meta/inc/TListOfEnumsWithLock.h
@@ -0,0 +1,103 @@
+// @(#)root/cont
+// Author: Bianca-Cristina Cristescu February 2014
+
+/*************************************************************************
+ * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+#ifndef ROOT_TListOfEnumsWithLock
+#define ROOT_TListOfEnumsWithLock
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfEnumsWithLock                                                         //
+//                                                                      //
+// A collection of TEnum objects designed for fast access given a       //
+// DeclId_t and for keep track of TEnum that were described             //
+// unloaded enum.                                                       //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef ROOT_TListOfEnums
+#include "TListOfEnums.h"
+#endif
+
+class TExMap;
+class TEnum;
+
+class TListOfEnumsWithLock : public TListOfEnums
+{
+private:
+   typedef TDictionary::DeclId_t DeclId_t;
+
+   TListOfEnumsWithLock(const TListOfEnumsWithLock&) = delete;
+   TListOfEnumsWithLock& operator=(const TListOfEnumsWithLock&) = delete;
+
+public:
+
+   TListOfEnumsWithLock(TClass *cl = 0);
+   ~TListOfEnumsWithLock() override;
+
+   void Clear(Option_t *option) override;
+   void Delete(Option_t *option="") override;
+
+   TObject   *FindObject(const TObject* obj) const override;
+   TObject   *FindObject(const char *name) const override;
+   TIterator *MakeIterator(Bool_t dir = kIterForward) const override;
+
+   TObject  *At(Int_t idx) const override;
+   TObject  *After(const TObject *obj) const override;
+   TObject  *Before(const TObject *obj) const override;
+   TObject  *First() const override;
+   TObjLink *FirstLink() const override;
+   TObject **GetObjectRef(const TObject *obj) const override;
+   TObject  *Last() const override;
+   TObjLink *LastLink() const override;
+
+   Int_t     GetLast() const override;
+   Int_t     IndexOf(const TObject *obj) const override;
+
+   Int_t      GetSize() const override;
+
+   void       AddFirst(TObject *obj) override;
+   void       AddFirst(TObject *obj, Option_t *opt) override;
+   void       AddLast(TObject *obj) override;
+   void       AddLast(TObject *obj, Option_t *opt) override;
+   void       AddAt(TObject *obj, Int_t idx) override;
+   void       AddAfter(const TObject *after, TObject *obj) override;
+   void       AddAfter(TObjLink *after, TObject *obj) override;
+   void       AddBefore(const TObject *before, TObject *obj) override;
+   void       AddBefore(TObjLink *before, TObject *obj) override;
+
+   void       RecursiveRemove(TObject *obj) override;
+   TObject   *Remove(TObject *obj) override;
+   TObject   *Remove(TObjLink *lnk) override;
+
+   ClassDef(TListOfEnumsWithLock,2);  // List of TDataMembers for a class
+};
+
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfEnumsWithLockIter                                             //
+//                                                                      //
+// Iterator of TListOfEnumsWithLock.                                    //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+class TListOfEnumsWithLockIter : public TListIter
+{
+ public:
+   TListOfEnumsWithLockIter(const TListOfEnumsWithLock *l, Bool_t dir = kIterForward);
+
+   using TListIter::operator=;
+
+   TObject           *Next();
+
+   ClassDef(TListOfEnumsWithLockIter,0)
+};
+
+#endif // ROOT_TListOfEnumsWithLock
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 8191304777bf0..f87957c26c9e1 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -83,6 +83,7 @@
 #include "TListOfFunctions.h"
 #include "TListOfFunctionTemplates.h"
 #include "TListOfEnums.h"
+#include "TListOfEnumsWithLock.h"
 #include "TViewPubDataMembers.h"
 #include "TViewPubFunctions.h"
 
@@ -3333,8 +3334,17 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    }
 
    if(not load) {
+     if(! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
+         R__LOCKGUARD(gInterpreterMutex);
+         if(fEnums) {
+            return fEnums.load();
+         }
+         //namespaces can have enums added to them
+         fEnums = new TListOfEnumsWithLock(this);
+         return fEnums;
+      }
       //no one is supposed to modify the returned results
-      static TList s_list;
+      static TListOfEnums s_list;
       return &s_list;
    }
 
@@ -3342,7 +3352,13 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    if(fEnums) {
       return fEnums.load();
    }
-   temp = new TListOfEnums(this);
+   if( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
+      // For this case, the list will be immutable
+      temp = new TListOfEnums(this);
+   } else {
+      //namespaces can have enums added to them
+      temp = new TListOfEnumsWithLock(this);
+   }
    temp->Load();
    fEnums = temp;
    return temp;
diff --git a/core/meta/src/TListOfEnums.cxx b/core/meta/src/TListOfEnums.cxx
index 0cfdc2d5a603b..92ea5c21075cb 100644
--- a/core/meta/src/TListOfEnums.cxx
+++ b/core/meta/src/TListOfEnums.cxx
@@ -176,25 +176,6 @@ void TListOfEnums::Delete(Option_t *option /* ="" */)
    fIsLoaded = kFALSE;
 }
 
-//______________________________________________________________________________
-TObject *TListOfEnums::FindObject(const char *name) const
-{
-   // Specialize FindObject to do search for the
-   // a enum just by name or create it if its not already in the list
-
-   TObject *result = THashList::FindObject(name);
-   if (!result) {
-
-      R__LOCKGUARD(gInterpreterMutex);
-
-      TInterpreter::DeclId_t decl;
-      if (fClass) decl = gInterpreter->GetEnum(fClass, name);
-      else        decl = gInterpreter->GetEnum(0, name);
-      if (decl) result = const_cast<TListOfEnums *>(this)->Get(decl, name);
-   }
-   return result;
-}
-
 //______________________________________________________________________________
 TEnum *TListOfEnums::Find(DeclId_t id) const
 {
@@ -268,6 +249,7 @@ TEnum *TListOfEnums::Get(DeclId_t id, const char *name)
    return e;
 }
 
+
 //______________________________________________________________________________
 void TListOfEnums::UnmapObject(TObject *obj)
 {
diff --git a/core/meta/src/TListOfEnumsWithLock.cxx b/core/meta/src/TListOfEnumsWithLock.cxx
new file mode 100644
index 0000000000000..e3fa9ea1586a0
--- /dev/null
+++ b/core/meta/src/TListOfEnumsWithLock.cxx
@@ -0,0 +1,326 @@
+// @(#)root/cont
+// Author: Bianca-Cristina Cristescu February 2014
+
+/*************************************************************************
+ * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfEnumsWithLock                                                         //
+//                                                                      //
+// A collection of TEnum objects designed for fast access given a       //
+// DeclId_t and for keep track of TEnum that were described             //
+// unloaded enum.                                                       //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#include <forward_list>
+
+#include "TListOfEnumsWithLock.h"
+#include "TClass.h"
+#include "TExMap.h"
+#include "TEnum.h"
+#include "TGlobal.h"
+#include "TInterpreter.h"
+#include "TVirtualMutex.h"
+
+constexpr unsigned int listSize=3;
+
+ClassImp(TListOfEnumsWithLock)
+
+//______________________________________________________________________________
+TListOfEnumsWithLock::TListOfEnumsWithLock(TClass *cl /*=0*/) :
+   TListOfEnums(cl)
+{
+}
+
+//______________________________________________________________________________
+TListOfEnumsWithLock::~TListOfEnumsWithLock()
+{
+   // Destructor.
+
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddFirst(TObject *obj)
+{
+   // Add object at the beginning of the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddFirst(obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddFirst(TObject *obj, Option_t *opt)
+{
+   // Add object at the beginning of the list and also store option.
+   // Storing an option is useful when one wants to change the behaviour
+   // of an object a little without having to create a complete new
+   // copy of the object. This feature is used, for example, by the Draw()
+   // method. It allows the same object to be drawn in different ways.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddFirst(obj, opt);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddLast(TObject *obj)
+{
+   // Add object at the end of the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddLast(obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddLast(TObject *obj, Option_t *opt)
+{
+   // Add object at the end of the list and also store option.
+   // Storing an option is useful when one wants to change the behaviour
+   // of an object a little without having to create a complete new
+   // copy of the object. This feature is used, for example, by the Draw()
+   // method. It allows the same object to be drawn in different ways.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddLast(obj, opt);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddAt(TObject *obj, Int_t idx)
+{
+   // Insert object at location idx in the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddAt(obj, idx);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddAfter(const TObject *after, TObject *obj)
+{
+   // Insert object after object after in the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddAfter(after, obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddAfter(TObjLink *after, TObject *obj)
+{
+   // Insert object after object after in the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddAfter(after, obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddBefore(const TObject *before, TObject *obj)
+{
+   // Insert object before object before in the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddBefore(before, obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::AddBefore(TObjLink *before, TObject *obj)
+{
+   // Insert object before object before in the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::AddBefore(before, obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::Clear(Option_t *option)
+{
+   // Remove all objects from the list. Does not delete the objects unless
+   // the THashList is the owner (set via SetOwner()).
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::Clear(option);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::Delete(Option_t *option /* ="" */)
+{
+   // Delete all TDataMember object files.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::Delete(option);
+}
+
+//______________________________________________________________________________
+TObject *TListOfEnumsWithLock::FindObject(const char *name) const
+{
+   // Specialize FindObject to do search for the
+   // a enum just by name or create it if its not already in the list
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TObject *result = TListOfEnums::FindObject(name);
+   if (!result) {
+
+
+      TInterpreter::DeclId_t decl;
+      if (GetClass()) decl = gInterpreter->GetEnum(GetClass(), name);
+      else        decl = gInterpreter->GetEnum(0, name);
+      if (decl) result = const_cast<TListOfEnumsWithLock *>(this)->Get(decl, name);
+   }
+   return result;
+}
+
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::FindObject(const TObject* obj) const
+{
+    R__LOCKGUARD(gInterpreterMutex);
+    return TListOfEnums::FindObject(obj);
+}
+
+//______________________________________________________________________________
+void TListOfEnumsWithLock::RecursiveRemove(TObject *obj)
+{
+   // Remove object from this collection and recursively remove the object
+   // from all other objects (and collections).
+   // This function overrides TCollection::RecursiveRemove that calls
+   // the Remove function. THashList::Remove cannot be called because
+   // it uses the hash value of the hash table. This hash value
+   // is not available anymore when RecursiveRemove is called from
+   // the TObject destructor.
+
+   if (!obj) return;
+
+   R__LOCKGUARD(gInterpreterMutex);
+   TListOfEnums::RecursiveRemove(obj);
+}
+
+//______________________________________________________________________________
+TObject *TListOfEnumsWithLock::Remove(TObject *obj)
+{
+   // Remove object from the list.
+
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::Remove(obj);
+}
+
+//______________________________________________________________________________
+TObject *TListOfEnumsWithLock::Remove(TObjLink *lnk)
+{
+   // Remove object via its objlink from the list.
+
+   if (!lnk) return 0;
+
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::Remove(lnk);
+}
+
+//______________________________________________________________________________
+TIterator* TListOfEnumsWithLock::MakeIterator(Bool_t dir ) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return new TListOfEnumsWithLockIter(this,dir);
+}
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::At(Int_t idx) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::At(idx);
+}
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::After(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::After(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::Before(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::Before(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::First() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::First();
+}
+
+//______________________________________________________________________________
+TObjLink* TListOfEnumsWithLock::FirstLink() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::FirstLink();
+}
+
+//______________________________________________________________________________
+TObject** TListOfEnumsWithLock::GetObjectRef(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::GetObjectRef(obj);
+}
+
+//______________________________________________________________________________
+TObject* TListOfEnumsWithLock::Last() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::Last();
+}
+
+//______________________________________________________________________________
+TObjLink* TListOfEnumsWithLock::LastLink() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::LastLink();
+}
+
+
+//______________________________________________________________________________
+Int_t TListOfEnumsWithLock::GetLast() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::GetLast();
+}
+
+//______________________________________________________________________________
+Int_t TListOfEnumsWithLock::IndexOf(const TObject *obj) const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::IndexOf(obj);
+}
+
+
+//______________________________________________________________________________
+Int_t TListOfEnumsWithLock::GetSize() const
+{
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::GetSize();
+}
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TListOfEnumsWithLockIter                                                 //
+//                                                                      //
+// Iterator for TListOfEnumsWithLock.                                       //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+ClassImp(TListOfEnumsWithLockIter)
+
+//______________________________________________________________________________
+TListOfEnumsWithLockIter::TListOfEnumsWithLockIter(const TListOfEnumsWithLock *l, Bool_t dir ):
+  TListIter(l,dir) {}
+
+//______________________________________________________________________________
+TObject *TListOfEnumsWithLockIter::Next()
+{
+  R__LOCKGUARD(gInterpreterMutex);
+  return TListIter::Next();
+}

From 7c1add597cba38e8526f3a902528f4bbb33b9852 Mon Sep 17 00:00:00 2001
From: Christopher Jones <cdj@fnal.gov>
Date: Tue, 3 Mar 2015 22:05:54 +0100
Subject: [PATCH 178/200] Fix bug in loading of enums into TClass

Now properly handle the case of enums from a namespace
---
 core/meta/inc/TInterpreter.h   | 3 ++-
 core/meta/src/TClass.cxx       | 4 ++--
 core/meta/src/TCling.cxx       | 8 +++-----
 core/meta/src/TCling.h         | 2 +-
 core/meta/src/TListOfEnums.cxx | 2 +-
 5 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/core/meta/inc/TInterpreter.h b/core/meta/inc/TInterpreter.h
index 2050ed5e30a97..f539c0a841699 100644
--- a/core/meta/inc/TInterpreter.h
+++ b/core/meta/inc/TInterpreter.h
@@ -43,6 +43,7 @@ class TInterpreterValue;
 class TMethod;
 class TObjArray;
 class TEnum;
+class TListOfEnums;
 
 R__EXTERN TVirtualMutex *gInterpreterMutex;
 
@@ -248,7 +249,7 @@ class TInterpreter : public TNamed {
    virtual DeclId_t GetEnum(TClass *cl, const char *name) const = 0;
    virtual TEnum*   CreateEnum(void *VD, TClass *cl) const = 0;
    virtual void     UpdateEnumConstants(TEnum* enumObj, TClass* cl) const = 0;
-   virtual void     LoadEnums(TClass* cl) const = 0;
+   virtual void     LoadEnums(TListOfEnums& cl) const = 0;
    virtual DeclId_t GetFunction(ClassInfo_t *cl, const char *funcname) = 0;
    virtual DeclId_t GetFunctionWithPrototype(ClassInfo_t *cl, const char* method, const char* proto, Bool_t objectIsConst = kFALSE, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch) = 0;
    virtual DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char* method, const char* params, Bool_t objectIsConst = kFALSE) = 0;
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index f87957c26c9e1..b98450ca4e2e3 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3334,7 +3334,7 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    }
 
    if(not load) {
-     if(! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
+      if(! ((kIsClass | kIsStruct | kIsUnion) & Property()) ) {
          R__LOCKGUARD(gInterpreterMutex);
          if(fEnums) {
             return fEnums.load();
@@ -3352,7 +3352,7 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    if(fEnums) {
       return fEnums.load();
    }
-   if( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
+   if( (kIsClass | kIsStruct | kIsUnion) & Property()) {
       // For this case, the list will be immutable
       temp = new TListOfEnums(this);
    } else {
diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index b2d895fb2d9ad..c168fb4b7e220 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -3187,20 +3187,18 @@ void TCling::CreateListOfBaseClasses(TClass *cl) const
 }
 
 //______________________________________________________________________________
-void TCling::LoadEnums(TClass* cl) const
+void TCling::LoadEnums(TListOfEnums& enumList) const
 {
    // Create list of pointers to enums for TClass cl.
    R__LOCKGUARD2(gInterpreterMutex);
 
    const Decl * D;
-   TListOfEnums* enumList;
+   TClass* cl = enumList.GetClass();
    if (cl) {
       D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
-      enumList = (TListOfEnums*)cl->GetListOfEnums(false);
    }
    else {
       D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
-      enumList = (TListOfEnums*)gROOT->GetListOfEnums();
    }
    // Iterate on the decl of the class and get the enums.
    if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
@@ -3224,7 +3222,7 @@ void TCling::LoadEnums(TClass* cl) const
                if (!buf.empty()) {
                   const char* name = buf.c_str();
                   // Add the enum to the list of loaded enums.
-                  enumList->Get(ED, name);
+                  enumList.Get(ED, name);
                }
             }
          }
diff --git a/core/meta/src/TCling.h b/core/meta/src/TCling.h
index 225e0d49dc111..449334c2cee55 100644
--- a/core/meta/src/TCling.h
+++ b/core/meta/src/TCling.h
@@ -240,7 +240,7 @@ class TCling : public TInterpreter {
    virtual DeclId_t GetEnum(TClass *cl, const char *name) const;
    virtual TEnum*   CreateEnum(void *VD, TClass *cl) const;
    virtual void     UpdateEnumConstants(TEnum* enumObj, TClass* cl) const;
-   virtual void     LoadEnums(TClass* cl) const;
+   virtual void     LoadEnums(TListOfEnums& cl) const;
    TString GetMangledName(TClass* cl, const char* method, const char* params, Bool_t objectIsConst = kFALSE);
    TString GetMangledNameWithPrototype(TClass* cl, const char* method, const char* proto, Bool_t objectIsConst = kFALSE, ROOT::EFunctionMatchMode mode = ROOT::kConversionMatch);
    void*   GetInterfaceMethod(TClass* cl, const char* method, const char* params, Bool_t objectIsConst = kFALSE);
diff --git a/core/meta/src/TListOfEnums.cxx b/core/meta/src/TListOfEnums.cxx
index 92ea5c21075cb..1c6ed28be44ff 100644
--- a/core/meta/src/TListOfEnums.cxx
+++ b/core/meta/src/TListOfEnums.cxx
@@ -364,7 +364,7 @@ void TListOfEnums::Load()
    // We cannot clear the whole unloaded list. It is too much.
 //   fUnloaded->Clear();
 
-   gInterpreter->LoadEnums(fClass);
+   gInterpreter->LoadEnums(*this);
 }
 
 //______________________________________________________________________________

From 6e0a88d8663ea8fcdc56a08e070689d0fae0240f Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Wed, 4 Mar 2015 21:52:28 -0600
Subject: [PATCH 179/200] Coding conventions

---
 core/meta/inc/TClass.h                 | 21 ++++++++++++---------
 core/meta/inc/TListOfEnums.h           | 14 +++++++-------
 core/meta/inc/TListOfEnumsWithLock.h   | 24 ++++++++++++------------
 core/meta/src/TClass.cxx               | 11 ++++++-----
 core/meta/src/TListOfEnumsWithLock.cxx | 12 ++++++------
 5 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/core/meta/inc/TClass.h b/core/meta/inc/TClass.h
index eaa457f8eaf84..99bd5b06e8624 100644
--- a/core/meta/inc/TClass.h
+++ b/core/meta/inc/TClass.h
@@ -179,16 +179,19 @@ friend class TProtoClass;
    // of the replacement, fPersistentRef points to the new TClass object.
    std::atomic<TClass**> fPersistentRef;//!Persistent address of pointer to this TClass object and its successors.
 
+   typedef std::atomic<std::map<std::string, TObjArray*>*> ConvSIMap_t;
 
-   mutable TObjArray *fStreamerInfo;    //Array of TVirtualStreamerInfo
-   mutable std::atomic<std::map<std::string, TObjArray*>*> fConversionStreamerInfo; //Array of the streamer infos derived from another class.
-   TList             *fRealData;        //linked list for persistent members including base classes
-   TList             *fBase;            //linked list for base classes
-   TListOfDataMembers*fData;            //linked list for data members
-   std::atomic<TListOfEnums*> fEnums;       //linked list for the enums
-   TListOfFunctionTemplates *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
-   std::atomic<TListOfFunctions*> fMethod;          //linked list for methods
-   TViewPubDataMembers*fAllPubData;      //all public data members (including from base classes)
+   mutable TObjArray  *fStreamerInfo;           //Array of TVirtualStreamerInfo
+   mutable ConvSIMap_t fConversionStreamerInfo; //Array of the streamer infos derived from another class.
+   TList              *fRealData;        //linked list for persistent members including base classes
+   TList              *fBase;            //linked list for base classes
+   TListOfDataMembers *fData;            //linked list for data members
+
+   std::atomic<TListOfEnums*> fEnums;        //linked list for the enums
+   TListOfFunctionTemplates  *fFuncTemplate; //linked list for function templates [Not public until implemented as active list]
+   std::atomic<TListOfFunctions*> fMethod;   //linked list for methods
+
+   TViewPubDataMembers*fAllPubData;     //all public data members (including from base classes)
    TViewPubFunctions *fAllPubMethod;    //all public methods (including from base classes)
    mutable TList     *fClassMenuList;   //list of class menu items
 
diff --git a/core/meta/inc/TListOfEnums.h b/core/meta/inc/TListOfEnums.h
index 156ce01e959b3..d41cbcd94492a 100644
--- a/core/meta/inc/TListOfEnums.h
+++ b/core/meta/inc/TListOfEnums.h
@@ -50,22 +50,22 @@ class TListOfEnums : public THashList
    TListOfEnums(const TListOfEnums&) = delete;
    TListOfEnums& operator=(const TListOfEnums&) = delete;
 
-   void       MapObject(TObject *obj);
-   void       UnmapObject(TObject *obj);
+   void MapObject(TObject *obj);
+   void UnmapObject(TObject *obj);
 
    void Load();
    void Unload();
    void Unload(TEnum *e);
-   void       SetClass(TClass* cl) { fClass = cl; }
+   void SetClass(TClass* cl) { fClass = cl; }
 
 public:
    typedef TDictionary::DeclId_t DeclId_t;
 
 protected:
-   TClass* GetClass() const {return fClass;}
-   TExMap* GetIds() { return fIds;}
-   TEnum* FindUnloaded(const char* name) { return (TEnum*)fUnloaded->FindObject(name);}
-   TEnum *Get(DeclId_t id, const char *name);
+   TClass *GetClass() const {return fClass;}
+   TExMap *GetIds() { return fIds;}
+   TEnum  *FindUnloaded(const char* name) { return (TEnum*)fUnloaded->FindObject(name);}
+   TEnum  *Get(DeclId_t id, const char *name);
 
 public:
    TListOfEnums(TClass *cl = 0);
diff --git a/core/meta/inc/TListOfEnumsWithLock.h b/core/meta/inc/TListOfEnumsWithLock.h
index 458a3ebd441ca..9c318341fa87c 100644
--- a/core/meta/inc/TListOfEnumsWithLock.h
+++ b/core/meta/inc/TListOfEnumsWithLock.h
@@ -49,17 +49,17 @@ class TListOfEnumsWithLock : public TListOfEnums
    TObject   *FindObject(const char *name) const override;
    TIterator *MakeIterator(Bool_t dir = kIterForward) const override;
 
-   TObject  *At(Int_t idx) const override;
-   TObject  *After(const TObject *obj) const override;
-   TObject  *Before(const TObject *obj) const override;
-   TObject  *First() const override;
-   TObjLink *FirstLink() const override;
-   TObject **GetObjectRef(const TObject *obj) const override;
-   TObject  *Last() const override;
-   TObjLink *LastLink() const override;
-
-   Int_t     GetLast() const override;
-   Int_t     IndexOf(const TObject *obj) const override;
+   TObject   *At(Int_t idx) const override;
+   TObject   *After(const TObject *obj) const override;
+   TObject   *Before(const TObject *obj) const override;
+   TObject   *First() const override;
+   TObjLink  *FirstLink() const override;
+   TObject  **GetObjectRef(const TObject *obj) const override;
+   TObject   *Last() const override;
+   TObjLink  *LastLink() const override;
+
+   Int_t      GetLast() const override;
+   Int_t      IndexOf(const TObject *obj) const override;
 
    Int_t      GetSize() const override;
 
@@ -95,7 +95,7 @@ class TListOfEnumsWithLockIter : public TListIter
 
    using TListIter::operator=;
 
-   TObject           *Next();
+   TObject *Next();
 
    ClassDef(TListOfEnumsWithLockIter,0)
 };
diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index b98450ca4e2e3..e6ae36e79d5b9 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3333,10 +3333,10 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
       return temp;
    }
 
-   if(not load) {
-      if(! ((kIsClass | kIsStruct | kIsUnion) & Property()) ) {
+   if (!load) {
+      if (! ((kIsClass | kIsStruct | kIsUnion) & Property()) ) {
          R__LOCKGUARD(gInterpreterMutex);
-         if(fEnums) {
+         if (fEnums) {
             return fEnums.load();
          }
          //namespaces can have enums added to them
@@ -3349,10 +3349,11 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    }
 
    R__LOCKGUARD(gInterpreterMutex);
-   if(fEnums) {
+   if (fEnums) {
+      if (load) (*fEnums).Load();
       return fEnums.load();
    }
-   if( (kIsClass | kIsStruct | kIsUnion) & Property()) {
+   if ( (kIsClass | kIsStruct | kIsUnion) & Property()) {
       // For this case, the list will be immutable
       temp = new TListOfEnums(this);
    } else {
diff --git a/core/meta/src/TListOfEnumsWithLock.cxx b/core/meta/src/TListOfEnumsWithLock.cxx
index e3fa9ea1586a0..1d973f5209f5d 100644
--- a/core/meta/src/TListOfEnumsWithLock.cxx
+++ b/core/meta/src/TListOfEnumsWithLock.cxx
@@ -35,7 +35,7 @@ ClassImp(TListOfEnumsWithLock)
 
 //______________________________________________________________________________
 TListOfEnumsWithLock::TListOfEnumsWithLock(TClass *cl /*=0*/) :
-   TListOfEnums(cl)
+TListOfEnums(cl)
 {
 }
 
@@ -177,8 +177,8 @@ TObject *TListOfEnumsWithLock::FindObject(const char *name) const
 //______________________________________________________________________________
 TObject* TListOfEnumsWithLock::FindObject(const TObject* obj) const
 {
-    R__LOCKGUARD(gInterpreterMutex);
-    return TListOfEnums::FindObject(obj);
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListOfEnums::FindObject(obj);
 }
 
 //______________________________________________________________________________
@@ -316,11 +316,11 @@ ClassImp(TListOfEnumsWithLockIter)
 
 //______________________________________________________________________________
 TListOfEnumsWithLockIter::TListOfEnumsWithLockIter(const TListOfEnumsWithLock *l, Bool_t dir ):
-  TListIter(l,dir) {}
+TListIter(l,dir) {}
 
 //______________________________________________________________________________
 TObject *TListOfEnumsWithLockIter::Next()
 {
-  R__LOCKGUARD(gInterpreterMutex);
-  return TListIter::Next();
+   R__LOCKGUARD(gInterpreterMutex);
+   return TListIter::Next();
 }

From ef2a0686dc800ef336848ddfb1784100d967d186 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Fri, 6 Mar 2015 16:46:50 -0600
Subject: [PATCH 180/200] Use faster pattern to use/set fProperty

---
 core/meta/src/TClass.cxx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index e6ae36e79d5b9..72c1200e2eb3d 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3334,7 +3334,8 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
    }
 
    if (!load) {
-      if (! ((kIsClass | kIsStruct | kIsUnion) & Property()) ) {
+      if (fProperty == -1) Property();
+      if (! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
          R__LOCKGUARD(gInterpreterMutex);
          if (fEnums) {
             return fEnums.load();
@@ -3353,7 +3354,8 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
       if (load) (*fEnums).Load();
       return fEnums.load();
    }
-   if ( (kIsClass | kIsStruct | kIsUnion) & Property()) {
+   if (fProperty == -1) Property();
+   if ( (kIsClass | kIsStruct | kIsUnion) & fProperty) {
       // For this case, the list will be immutable
       temp = new TListOfEnums(this);
    } else {

From 96ae8e8670db6dc697db05d65c6e88093480e98a Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Fri, 6 Mar 2015 16:48:50 -0600
Subject: [PATCH 181/200] In GetListOfEnums act on load request for namespace
 even if list already created

---
 core/meta/src/TClass.cxx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index 72c1200e2eb3d..deb3547d848be 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3329,7 +3329,14 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
 {
    // Return list containing the TEnums of a class.
    auto temp = fEnums.load();
-   if(temp) {
+   if (temp) {
+      if (load) {
+         if (fProperty == -1) Property();
+         if (! ((kIsClass | kIsStruct | kIsUnion) & fProperty) ) {
+            R__LOCKGUARD2(gROOTMutex);
+            temp->Load();
+         }
+      }
       return temp;
    }
 

From d29afc2236c3fa9e0a9ca12afe6c37339bd05b24 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 08:03:12 -0500
Subject: [PATCH 182/200] C++11 is now required

---
 core/base/inc/TROOT.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/base/inc/TROOT.h b/core/base/inc/TROOT.h
index c0dc8bd498f18..736d4cc82624f 100644
--- a/core/base/inc/TROOT.h
+++ b/core/base/inc/TROOT.h
@@ -98,7 +98,7 @@ friend TROOT *ROOT::GetROOT2();
    TString         fGitBranch;            //Git branch
    TString         fGitDate;              //Date and time when make was run
    Int_t           fTimer;                //Timer flag
-   std::atomic<TApplication*> fApplication;         //Pointer to current application
+   std::atomic<TApplication*> fApplication;  //Pointer to current application
    TInterpreter    *fInterpreter;         //Command interpreter
    Bool_t          fBatch;                //True if session without graphics
    Bool_t          fEditHistograms;       //True if histograms can be edited with the mouse

From 08307aa4f56ba1d219485ff8b0b43ae0c1cd4035 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 08:08:27 -0500
Subject: [PATCH 183/200] Add support to 'load' TROOT enum list without
 exposing TListOfEnums

---
 core/base/inc/TROOT.h        |  6 ++++--
 core/base/src/TROOT.cxx      | 15 +++++++++++----
 core/meta/inc/TListOfEnums.h |  1 +
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/core/base/inc/TROOT.h b/core/base/inc/TROOT.h
index 736d4cc82624f..041082c8137a0 100644
--- a/core/base/inc/TROOT.h
+++ b/core/base/inc/TROOT.h
@@ -85,6 +85,8 @@ friend TROOT *ROOT::GetROOT2();
    TROOT& operator=(const TROOT&);        //Not implemented
 
 protected:
+   typedef std::atomic<TListOfEnums*> AListOfEnums_t;
+
    TString         fConfigOptions;        //ROOT ./configure set build options
    TString         fConfigFeatures;       //ROOT ./configure detected build features
    TString         fVersion;              //ROOT version (from CMZ VERSQQ) ex 0.05/01
@@ -137,7 +139,7 @@ friend TROOT *ROOT::GetROOT2();
    TSeqCollection  *fProofs;              //List of proof sessions
    TSeqCollection  *fClipboard;           //List of clipbard objects
    TSeqCollection  *fDataSets;            //List of data sets (TDSet or TChain)
-   TCollection     *fEnums;               //List of enum types
+   AListOfEnums_t   fEnums;               //List of enum types
    TProcessUUID    *fUUIDs;               //Pointer to TProcessID managing TUUIDs
    TFolder         *fRootFolder;          //top level folder //root
    TList           *fBrowsables;          //List of browsables
@@ -227,7 +229,7 @@ friend TROOT *ROOT::GetROOT2();
    TSeqCollection   *GetListOfProofs() const { return fProofs; }
    TSeqCollection   *GetClipboard() const { return fClipboard; }
    TSeqCollection   *GetListOfDataSets() const { return fDataSets; }
-   TCollection      *GetListOfEnums();
+   TCollection      *GetListOfEnums(Bool_t load = kTRUE);
    TCollection      *GetListOfFunctionTemplates();
    TList            *GetListOfBrowsables() const { return fBrowsables; }
    TDataType        *GetType(const char *name, Bool_t load = kFALSE) const;
diff --git a/core/base/src/TROOT.cxx b/core/base/src/TROOT.cxx
index e17b6cf54fcbc..5fd189124ff2e 100644
--- a/core/base/src/TROOT.cxx
+++ b/core/base/src/TROOT.cxx
@@ -1378,18 +1378,25 @@ TObject *TROOT::GetGeometry(const char *name) const
 }
 
 //______________________________________________________________________________
-TCollection *TROOT::GetListOfEnums()
+TCollection *TROOT::GetListOfEnums(Bool_t load /* = kTRUE */)
 {
-   R__LOCKGUARD2(gROOTMutex);
    if(!fEnums) {
-      fEnums = new TListOfEnumsWithLock(0);
+      R__LOCKGUARD2(gROOTMutex);
+      // Test again just in case, another thread did the work while we were
+      // waiting.
+      if (!fEnums) fEnums = new TListOfEnumsWithLock(0);
    }
-   return fEnums;
+   if (load) {
+      R__LOCKGUARD2(gROOTMutex);
+      (*fEnums).Load(); // Refresh the list of enums.
+   }
+   return fEnums.load();
 }
 
 //______________________________________________________________________________
 TCollection *TROOT::GetListOfFunctionTemplates()
 {
+   R__LOCKGUARD2(gROOTMutex);
    if(!fFuncTemplate) {
       fFuncTemplate = new TListOfFunctionTemplates(0);
    }
diff --git a/core/meta/inc/TListOfEnums.h b/core/meta/inc/TListOfEnums.h
index d41cbcd94492a..3341e3af886a4 100644
--- a/core/meta/inc/TListOfEnums.h
+++ b/core/meta/inc/TListOfEnums.h
@@ -39,6 +39,7 @@ class TListOfEnums : public THashList
    friend class TCling;
    friend class TClass;
    friend class TProtoClass;
+   friend class TROOT;
 
    TClass    *fClass; //! Context of this list.  Not owned.
 

From ceff684ee923c11e9476cbb612017f52f0771c98 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 11:41:15 -0500
Subject: [PATCH 184/200] Revert to the correct default behavior for
 TROOT::GetListOfEnums

---
 core/base/inc/TROOT.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/base/inc/TROOT.h b/core/base/inc/TROOT.h
index 041082c8137a0..3ac0a96dff017 100644
--- a/core/base/inc/TROOT.h
+++ b/core/base/inc/TROOT.h
@@ -229,7 +229,7 @@ friend TROOT *ROOT::GetROOT2();
    TSeqCollection   *GetListOfProofs() const { return fProofs; }
    TSeqCollection   *GetClipboard() const { return fClipboard; }
    TSeqCollection   *GetListOfDataSets() const { return fDataSets; }
-   TCollection      *GetListOfEnums(Bool_t load = kTRUE);
+   TCollection      *GetListOfEnums(Bool_t load = kFALSE);
    TCollection      *GetListOfFunctionTemplates();
    TList            *GetListOfBrowsables() const { return fBrowsables; }
    TDataType        *GetType(const char *name, Bool_t load = kFALSE) const;

From 10a4af2170e043cad3eacd74a8183eef632b6a34 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 11:35:20 -0500
Subject: [PATCH 185/200] Properly create the TListOfEnums in LoadPCM.

Since the TListOfEnums for a class is immutable (and thus does not use lock), LoadPCM need to
explicitly create it rathen than going through GetListOfEnums(false) which for a class
does not really create the list (it is delayed until an actual load and in the meantime
a global empty one is returned).
---
 core/meta/src/TCling.cxx | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index c168fb4b7e220..17e61ceec231f 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -66,6 +66,7 @@
 #include "TVirtualStreamerInfo.h"
 #include "TListOfDataMembers.h"
 #include "TListOfEnums.h"
+#include "TListOfEnumsWithLock.h"
 #include "TListOfFunctions.h"
 #include "TListOfFunctionTemplates.h"
 #include "TProtoClass.h"
@@ -1314,7 +1315,17 @@ bool TCling::LoadPCM(TString pcmFileName,
                if (!nsTClassEntry){
                   nsTClassEntry = new TClass(enumScope,0,TClass::kNamespaceForMeta, true);
                }
-               auto listOfEnums = dynamic_cast<THashList*>(nsTClassEntry->GetListOfEnums(false));
+               auto listOfEnums = nsTClassEntry->fEnums.load();
+               if (!listOfEnums) {
+                  if ( (kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property() ) {
+                     // For this case, the list will be immutable once constructed
+                     // (i.e. in this case, by the end of this routine).
+                     listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
+                  } else {
+                     //namespaces can have enums added to them
+                     listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
+                  }
+               }
                if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)){
                   ((TEnum*) selEnum)->SetClass(nsTClassEntry);
                   listOfEnums->Add(selEnum);

From a9650ef622c77a5b7fadfd666530c17eef512e6f Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 11:41:07 -0500
Subject: [PATCH 186/200] White space

---
 core/meta/src/TClass.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/meta/src/TClass.cxx b/core/meta/src/TClass.cxx
index deb3547d848be..14439116614cd 100644
--- a/core/meta/src/TClass.cxx
+++ b/core/meta/src/TClass.cxx
@@ -3351,7 +3351,7 @@ TList *TClass::GetListOfEnums(Bool_t load /* = kTRUE */)
          fEnums = new TListOfEnumsWithLock(this);
          return fEnums;
       }
-      //no one is supposed to modify the returned results
+      // no one is supposed to modify the returned results
       static TListOfEnums s_list;
       return &s_list;
    }

From 43b6c775123c371bf02fe7d744e0be8612499f27 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 11:58:53 -0500
Subject: [PATCH 187/200] Allow run-time disable of RooFit Banner via
 rootrc/gEnv.

Set the value of
   RooFit.Banner
either via a rootrc file or a direct call to gEnv to disable (or enable) the printing of the RooFit banner.
---
 config/rootrc.in                    |  3 +++
 roofit/roofitcore/src/RooBanner.cxx | 12 ++++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/config/rootrc.in b/config/rootrc.in
index 081f9107cd8b6..42c8c2be3574d 100644
--- a/config/rootrc.in
+++ b/config/rootrc.in
@@ -110,6 +110,9 @@ WinNT.*.Editor:          notepad
 # Default Fitter (current choices are Minuit and Fumili).
 Root.Fitter:             Minuit
 
+# Enable (default) or disable the RooFit banner printing.
+# RooFit.Banner:  yes
+
 # Specify list of file endings which TTabCom (TAB completion) should ignore.
 #TabCom.FileIgnore:       .cpp:.h:.cmz
 
diff --git a/roofit/roofitcore/src/RooBanner.cxx b/roofit/roofitcore/src/RooBanner.cxx
index 89c0338d387ee..8f45a89949b48 100644
--- a/roofit/roofitcore/src/RooBanner.cxx
+++ b/roofit/roofitcore/src/RooBanner.cxx
@@ -2,6 +2,7 @@
 
 #include "Rtypes.h"
 #include "Riostream.h"
+#include "TEnv.h"
 
 //////////////////////////////////////////////////////////////////////////////
 // 
@@ -18,10 +19,13 @@ Int_t doBanner()
 
 {
 #ifndef __ROOFIT_NOBANNER
-  cout << endl
-  << "\033[1mRooFit v" << VTAG << " -- Developed by Wouter Verkerke and David Kirkby\033[0m " << endl 
-              << "                Copyright (C) 2000-2013 NIKHEF, University of California & Stanford University" << endl 
-              << "                All rights reserved, please read http://roofit.sourceforge.net/license.txt" << endl << endl ;
+   if (gEnv->GetValue("RooFit.Banner", 1)) {
+       cout << endl
+      << "\033[1mRooFit v" << VTAG << " -- Developed by Wouter Verkerke and David Kirkby\033[0m " << endl
+      << "                Copyright (C) 2000-2013 NIKHEF, University of California & Stanford University" << endl
+      << "                All rights reserved, please read http://roofit.sourceforge.net/license.txt" << endl
+      << endl ;
+   }
 #endif
   return 0 ;
 }

From 83dbf3604bf9ff2e011eb86cfebc99b6602db69a Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 12:31:34 -0500
Subject: [PATCH 188/200] Don't find the scope in the middle of a template
 argument ... in TEnum::GetEnum

---
 core/meta/src/TEnum.cxx | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx
index bc2852caf9513..d8ed1dac16444 100644
--- a/core/meta/src/TEnum.cxx
+++ b/core/meta/src/TEnum.cxx
@@ -198,7 +198,20 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
       return theEnum;
    };
 
-   const auto lastPos = strrchr(enumName, ':');
+   const char *lastPos = nullptr;
+   {
+      long depth = 0;
+      for(auto cursor = enumName; *cursor != '\0'; ++cursor) {
+         if ( *cursor == '<') ++depth;
+         else if ( *cursor == '>') --depth;
+         else if ( *cursor == ':' ) {
+            if (depth==0) {
+               lastPos = cursor;
+               break;
+            }
+         }
+      }
+   }
    if (lastPos != nullptr) {
       // We have a scope
       // All of this C gymnastic is to avoid allocations on the heap

From 1f4bb359577ee8c335ea51e7bcd05a990d833482 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 12:59:50 -0500
Subject: [PATCH 189/200] In TEnum::GetEnum set lastPos to after the _last_
 double colon

---
 core/meta/src/TEnum.cxx | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx
index d8ed1dac16444..158a114c5e7ef 100644
--- a/core/meta/src/TEnum.cxx
+++ b/core/meta/src/TEnum.cxx
@@ -205,9 +205,8 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
          if ( *cursor == '<') ++depth;
          else if ( *cursor == '>') --depth;
          else if ( *cursor == ':' ) {
-            if (depth==0) {
-               lastPos = cursor;
-               break;
+            if (depth==0 && *(cursor+1) == ':' && *(cursor+2) != '\0') {
+               lastPos = cursor+2;
             }
          }
       }
@@ -215,8 +214,8 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
    if (lastPos != nullptr) {
       // We have a scope
       // All of this C gymnastic is to avoid allocations on the heap
-      const auto enName = lastPos + 1;
-      const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)enumName) / sizeof(decltype(*lastPos)) - 1;
+      const auto enName = lastPos;
+      const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)enumName) / sizeof(decltype(*lastPos)) - 2;
 #ifdef R__WIN32
       char *scopeName = new char[scopeNameSize + 1];
 #else

From 5a8d413eb569df4fd7a48ac6872a5570843af4ae Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 13:07:51 -0500
Subject: [PATCH 190/200] Use $(OSTHREADLIB) for platform independence

---
 core/utils/Module.mk | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/core/utils/Module.mk b/core/utils/Module.mk
index 6d0aa0d4868bb..6e35952455bcd 100644
--- a/core/utils/Module.mk
+++ b/core/utils/Module.mk
@@ -7,10 +7,6 @@
 
 MODNAME := utils
 
-ifneq ($(GCC_MAJOR),)
-LDPTHREAD := -pthread
-endif
-
 ifneq ($(HOST),)
 
 .PHONY: all-$(MODNAME) clean-$(MODNAME) distclean-$(MODNAME)
@@ -32,7 +28,7 @@ ROOTCLINGEXEEXTRAO = $(COREO) $(COREDO) $(IOO) $(IODO) $(THREADO) $(THREADDO) $(
 $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 	   $(CLINGMETAUTILSO) $(SNPRINTFO) $(CLINGO) $(ROOTCLINGEXEEXTRAO) \
            $(PCREDEP) $(CORELIBDEP)
-	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(OSTHREADLIBDIR) $(OSTHREADLIB) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
 	   $(ROOTCLINGTCLINGO) $(CLINGMETAUTILSO) \
 	   $(SNPRINTFO)  $(CLINGO) $(ROOTCLINGEXEEXTRAO) $(CLINGLIBEXTRA) \
 	   $(RPATH) $(CILIBS) $(CORELIBEXTRA) $(PCRELDFLAGS) $(PCRELIB) \
@@ -40,7 +36,7 @@ $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 
 $(ROOTCLINGTMPEXE): $(CINTTMPO) $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) $(CLINGO)
-	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(OSTHREADLIBDIR) $(OSTHREADLIB) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) \
 	   $(CINTTMPLIBS) $(CLINGO) $(CLINGLIBEXTRA) $(CILIBS)
 

From 818147ed29202fb2e506b1204e13e2d8bffd9d34 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 14:58:43 -0500
Subject: [PATCH 191/200] Add TClassEdit::GetUnqualifiedName and use in
 TEnum::GetEnum and TClingLookupHelper__ExistingTypeCheck

---
 core/meta/src/TCling.cxx          |  4 ++--
 core/meta/src/TEnum.cxx           | 17 +++--------------
 core/metautils/inc/TClassEdit.h   |  1 +
 core/metautils/src/TClassEdit.cxx | 21 +++++++++++++++++++++
 4 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index 17e61ceec231f..dba2f93644a1c 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -893,8 +893,8 @@ bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
    }
 
    // Check if the name is an enumerator
-   const auto lastPos = strrchr(inner, ':');
-   if (lastPos != nullptr)   // Main switch: case 1 - scoped enum, case 2 global enum
+   const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
+   if (lastPos != inner)   // Main switch: case 1 - scoped enum, case 2 global enum
    {
       // We have a scope
       // All of this C gymnastic is here to get the scope name and to avoid
diff --git a/core/meta/src/TEnum.cxx b/core/meta/src/TEnum.cxx
index 158a114c5e7ef..9aa8e256e5413 100644
--- a/core/meta/src/TEnum.cxx
+++ b/core/meta/src/TEnum.cxx
@@ -198,20 +198,9 @@ TEnum *TEnum::GetEnum(const char *enumName, ESearchAction sa)
       return theEnum;
    };
 
-   const char *lastPos = nullptr;
-   {
-      long depth = 0;
-      for(auto cursor = enumName; *cursor != '\0'; ++cursor) {
-         if ( *cursor == '<') ++depth;
-         else if ( *cursor == '>') --depth;
-         else if ( *cursor == ':' ) {
-            if (depth==0 && *(cursor+1) == ':' && *(cursor+2) != '\0') {
-               lastPos = cursor+2;
-            }
-         }
-      }
-   }
-   if (lastPos != nullptr) {
+   const char *lastPos = TClassEdit::GetUnqualifiedName(enumName);
+
+   if (lastPos != enumName) {
       // We have a scope
       // All of this C gymnastic is to avoid allocations on the heap
       const auto enName = lastPos;
diff --git a/core/metautils/inc/TClassEdit.h b/core/metautils/inc/TClassEdit.h
index 08838346ef069..01c7e31bd97b0 100644
--- a/core/metautils/inc/TClassEdit.h
+++ b/core/metautils/inc/TClassEdit.h
@@ -154,6 +154,7 @@ namespace TClassEdit {
    std::string ResolveTypedef(const char *tname, bool resolveAll = false);
    std::string ShortType (const char *typeDesc, int mode);
    std::string InsertStd(const char *tname);
+   const char* GetUnqualifiedName(const char*name);
    inline char* DemangleName(const char* mangled_name, int& errorCode)
    {
    // Demangle in a portable way the name.
diff --git a/core/metautils/src/TClassEdit.cxx b/core/metautils/src/TClassEdit.cxx
index 925a96950f066..c2d85f929ceba 100644
--- a/core/metautils/src/TClassEdit.cxx
+++ b/core/metautils/src/TClassEdit.cxx
@@ -734,6 +734,27 @@ string TClassEdit::GetLong64_Name(const string& original)
    return result;
 }
 
+//______________________________________________________________________________
+const char *TClassEdit::GetUnqualifiedName(const char *original)
+{
+   // Return the start of the unqualified name include in 'original'.
+
+   const char *lastPos = original;
+   {
+      long depth = 0;
+      for(auto cursor = original; *cursor != '\0'; ++cursor) {
+         if ( *cursor == '<') ++depth;
+         else if ( *cursor == '>') --depth;
+         else if ( *cursor == ':' ) {
+            if (depth==0 && *(cursor+1) == ':' && *(cursor+2) != '\0') {
+               lastPos = cursor+2;
+            }
+         }
+      }
+   }
+   return lastPos;
+}
+
 //______________________________________________________________________________
 static void R__FindTrailing(std::string &full,  /*modified*/
                             std::string &stars /* the literal output */

From f6caebaf54e7838d0b878196224714c199f5cf44 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 15:35:04 -0500
Subject: [PATCH 192/200] Remove unused variable

---
 core/meta/src/TListOfEnumsWithLock.cxx | 2 --
 1 file changed, 2 deletions(-)

diff --git a/core/meta/src/TListOfEnumsWithLock.cxx b/core/meta/src/TListOfEnumsWithLock.cxx
index 1d973f5209f5d..147373d168814 100644
--- a/core/meta/src/TListOfEnumsWithLock.cxx
+++ b/core/meta/src/TListOfEnumsWithLock.cxx
@@ -29,8 +29,6 @@
 #include "TInterpreter.h"
 #include "TVirtualMutex.h"
 
-constexpr unsigned int listSize=3;
-
 ClassImp(TListOfEnumsWithLock)
 
 //______________________________________________________________________________

From 7cc58f9e1e64978d92dfe7027d49ab821853f86e Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sun, 8 Mar 2015 15:35:23 -0500
Subject: [PATCH 193/200] Using the override keyword require using
 ClassDefOverride

---
 core/meta/inc/TListOfEnums.h         | 2 +-
 core/meta/inc/TListOfEnumsWithLock.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/meta/inc/TListOfEnums.h b/core/meta/inc/TListOfEnums.h
index 3341e3af886a4..d69df867fdd0f 100644
--- a/core/meta/inc/TListOfEnums.h
+++ b/core/meta/inc/TListOfEnums.h
@@ -92,7 +92,7 @@ class TListOfEnums : public THashList
    TObject   *Remove(TObject *obj) override;
    TObject   *Remove(TObjLink *lnk) override;
 
-   ClassDef(TListOfEnums,2);  // List of TDataMembers for a class
+   ClassDefOverride(TListOfEnums,2);  // List of TDataMembers for a class
 };
 
 #endif // ROOT_TListOfEnums
diff --git a/core/meta/inc/TListOfEnumsWithLock.h b/core/meta/inc/TListOfEnumsWithLock.h
index 9c318341fa87c..6397038fe1dd4 100644
--- a/core/meta/inc/TListOfEnumsWithLock.h
+++ b/core/meta/inc/TListOfEnumsWithLock.h
@@ -77,7 +77,7 @@ class TListOfEnumsWithLock : public TListOfEnums
    TObject   *Remove(TObject *obj) override;
    TObject   *Remove(TObjLink *lnk) override;
 
-   ClassDef(TListOfEnumsWithLock,2);  // List of TDataMembers for a class
+   ClassDefOverride(TListOfEnumsWithLock,2);  // List of TDataMembers for a class
 };
 
 

From 2bcc3dae26724c65b1a822153c86608e3341f3f6 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Mon, 9 Mar 2015 09:00:28 +0100
Subject: [PATCH 194/200] Use "official" -pthread variable. Symmetry with
 v6.02.

---
 core/utils/Module.mk | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/core/utils/Module.mk b/core/utils/Module.mk
index 6d0aa0d4868bb..6e35952455bcd 100644
--- a/core/utils/Module.mk
+++ b/core/utils/Module.mk
@@ -7,10 +7,6 @@
 
 MODNAME := utils
 
-ifneq ($(GCC_MAJOR),)
-LDPTHREAD := -pthread
-endif
-
 ifneq ($(HOST),)
 
 .PHONY: all-$(MODNAME) clean-$(MODNAME) distclean-$(MODNAME)
@@ -32,7 +28,7 @@ ROOTCLINGEXEEXTRAO = $(COREO) $(COREDO) $(IOO) $(IODO) $(THREADO) $(THREADDO) $(
 $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 	   $(CLINGMETAUTILSO) $(SNPRINTFO) $(CLINGO) $(ROOTCLINGEXEEXTRAO) \
            $(PCREDEP) $(CORELIBDEP)
-	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(OSTHREADLIBDIR) $(OSTHREADLIB) -o $@ $(ROOTCLINGO) $(ROOTCLINGUTILO) \
 	   $(ROOTCLINGTCLINGO) $(CLINGMETAUTILSO) \
 	   $(SNPRINTFO)  $(CLINGO) $(ROOTCLINGEXEEXTRAO) $(CLINGLIBEXTRA) \
 	   $(RPATH) $(CILIBS) $(CORELIBEXTRA) $(PCRELDFLAGS) $(PCRELIB) \
@@ -40,7 +36,7 @@ $(ROOTCLINGEXE): $(ROOTCLINGO) $(ROOTCLINGUTILO) $(ROOTCLINGTCLINGO) \
 
 $(ROOTCLINGTMPEXE): $(CINTTMPO) $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) $(CLINGO)
-	$(LD) $(LDFLAGS) $(LDPTHREAD) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
+	$(LD) $(LDFLAGS) $(OSTHREADLIBDIR) $(OSTHREADLIB) -o $@ $(ROOTCLINGTMPO) $(ROOTCLINGUTILO) \
 	   $(METAUTILSO) $(CLINGMETAUTILSO) $(SNPRINTFO) $(STRLCPYO) \
 	   $(CINTTMPLIBS) $(CLINGO) $(CLINGLIBEXTRA) $(CILIBS)
 

From a523a7e973c58204407443ab4bbd2a6d811da2c4 Mon Sep 17 00:00:00 2001
From: Bertrand Bellenot <bertrand.bellenot@cern.ch>
Date: Mon, 9 Mar 2015 09:43:38 +0100
Subject: [PATCH 195/200] Add space formatting for MathJax

---
 etc/http/scripts/JSRootPainter.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/etc/http/scripts/JSRootPainter.js b/etc/http/scripts/JSRootPainter.js
index aa11c85261564..fd03ecceee314 100644
--- a/etc/http/scripts/JSRootPainter.js
+++ b/etc/http/scripts/JSRootPainter.js
@@ -820,6 +820,7 @@
          str = str.replace(/#right/g, "\\right");
          // processing of #[] #{} should be done
          str = str.replace(/#\[\]/g, "\\[]");
+         str = str.replace(/ /g, "\\;");
 
          for (var x in JSROOT.Painter.symbols_map) {
             var y = "\\" + x.substr(1);

From 43534527ed2fb29cc1253806aa1ff448aa7f5b47 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Mon, 9 Mar 2015 10:42:33 +0100
Subject: [PATCH 196/200] update the root man pages. More updates are needed .

---
 man/man1/root.1 | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/man/man1/root.1 b/man/man1/root.1
index 2baecbf9efc81..b0699f69d3a07 100644
--- a/man/man1/root.1
+++ b/man/man1/root.1
@@ -1,7 +1,7 @@
 .\"
 .\" $Id: root.1,v 1.1 2001/08/15 13:30:48 rdm Exp $
 .\"
-.TH ROOT 1 "Version 3" "ROOT"
+.TH ROOT 1 "Version 6" "ROOT"
 .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
 .\" other parms are allowed: see man(7), man(1)
 .SH NAME
@@ -29,6 +29,9 @@ Show summary of options.
 .B -b
 Run in batch mode without graphics
 .TP
+.B -e
+Execute the command passed between single quotes
+.TP
 .B -n
 Do not execute logon and logoff macros as specified in
 .B .rootrc
@@ -40,7 +43,7 @@ Exit after processing command line macro files
 Do not show splash screen
 .SH "SEE ALSO"
 .SB
-\fIrootcint\fR(1), \fIcint\fR(1), \fIroot-config\fR(1),
+\fIrootcling\fR(1), \fIcling\fR(1), \fIroot-config\fR(1),
 \fIrootd\fR(1), \fIh2root\fR(1), \fIg2root\fR(1)
 .PP
 For extensive documentation on the \fBROOT\fR system, see

From db0b9354e963303370034ba61f91dfcb5de63a59 Mon Sep 17 00:00:00 2001
From: Olivier Couet <olivier.couet@cern.ch>
Date: Mon, 9 Mar 2015 11:29:25 +0100
Subject: [PATCH 197/200] The ROOT version is taken from ROOT itself to
 generate a proper title and footer.

---
 documentation/doxygen/Doxyfile          |  2 +-
 documentation/doxygen/Makefile          |  3 +++
 documentation/doxygen/htmlfooter.html   | 10 ----------
 documentation/doxygen/makehtmlfooter.sh | 12 ++++++++++++
 4 files changed, 16 insertions(+), 11 deletions(-)
 delete mode 100644 documentation/doxygen/htmlfooter.html
 create mode 100755 documentation/doxygen/makehtmlfooter.sh

diff --git a/documentation/doxygen/Doxyfile b/documentation/doxygen/Doxyfile
index f72e1d54a85e0..3f6e057704ed5 100644
--- a/documentation/doxygen/Doxyfile
+++ b/documentation/doxygen/Doxyfile
@@ -21,7 +21,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 6.03/03
+PROJECT_NUMBER         = $(DOXYGEN_ROOT_VERSION)
 
 # This tag specifies the encoding used for all characters in the config file
 # that follow. The default is UTF-8 which is also the encoding used for all text
diff --git a/documentation/doxygen/Makefile b/documentation/doxygen/Makefile
index ded6d29b33edb..23f7391529e1d 100644
--- a/documentation/doxygen/Makefile
+++ b/documentation/doxygen/Makefile
@@ -1,6 +1,7 @@
 
 .PHONY: filter doxygen clean
 
+export DOXYGEN_ROOT_VERSION=$(shell root -l -b -q -e 'printf("%s\n", gROOT->GetVersion());')
 export DOXYGEN_OUTPUT_DIRECTORY=/tmp/doxygen/rootdoc
 export DOXYGEN_EXAMPLE_PATH=$(DOXYGEN_OUTPUT_DIRECTORY)/macros
 
@@ -12,9 +13,11 @@ filter:
 doxygen:
 	if [ ! -d $(DOXYGEN_OUTPUT_DIRECTORY) ]; then mkdir $(DOXYGEN_OUTPUT_DIRECTORY); fi
 	if [ ! -d $(DOXYGEN_EXAMPLE_PATH) ]; then mkdir $(DOXYGEN_EXAMPLE_PATH); fi
+	./makehtmlfooter.sh > htmlfooter.html
 	doxygen
 	rm c1*
 	rm stdout.dat
+	rm htmlfooter.html
 
 clean:
 	rm -r $(DOXYGEN_OUTPUT_DIRECTORY)
diff --git a/documentation/doxygen/htmlfooter.html b/documentation/doxygen/htmlfooter.html
deleted file mode 100644
index 8386bc75a19aa..0000000000000
--- a/documentation/doxygen/htmlfooter.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-</body>
-<div id="footer" style="background-color:#DDDDDD;">
-  <small>
-    <img class="footer" src="rootlogo_s.gif" alt="root"/></a>
-    ROOT (5.99/04) Reference Guide Generated on $datetime.
-  </small>
-</div>
-</body>
-</html>
diff --git a/documentation/doxygen/makehtmlfooter.sh b/documentation/doxygen/makehtmlfooter.sh
new file mode 100755
index 0000000000000..08fedeafdb311
--- /dev/null
+++ b/documentation/doxygen/makehtmlfooter.sh
@@ -0,0 +1,12 @@
+# Generates the HTML footer
+
+echo '<html>'
+echo '</body>'
+echo '<div id="footer" style="background-color:#DDDDDD;">'
+echo '<small>'
+echo '<img class="footer" src="rootlogo_s.gif" alt="root"/></a>'
+echo 'ROOT ('$DOXYGEN_ROOT_VERSION' ) Reference Guide Generated on $datetime.'
+echo '</small>'
+echo '</div>'
+echo '</body>'
+echo '</html>'
\ No newline at end of file

From 6374a92ea193bf869a93f4a727eafffbff36c80d Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Mon, 9 Mar 2015 11:54:22 +0100
Subject: [PATCH 198/200] Support IO of unordered set

including proper naming in the typesystem.
---
 core/meta/inc/TDictionary.h                 | 21 ++---
 core/meta/inc/TStreamerElement.h            | 23 ++---
 core/meta/src/TBaseClass.cxx                | 21 ++---
 core/meta/src/TCling.cxx                    |  1 +
 core/meta/src/TStreamerElement.cxx          | 20 +++--
 core/metautils/CMakeLists.txt               |  2 +-
 core/metautils/inc/ESTLType.h               | 27 +++---
 core/metautils/inc/TClassEdit.h             | 29 ++++---
 core/metautils/src/TClassEdit.cxx           | 94 +++++++++++++++++----
 core/metautils/src/TMetaUtils.cxx           | 11 ++-
 core/metautils/src/unordered_setLinkdef.h   | 13 +++
 core/utils/src/rootcling.cxx                |  1 +
 io/io/src/TGenCollectionProxy.cxx           |  4 +
 io/io/src/TGenCollectionStreamer.cxx        |  9 +-
 io/io/src/TMakeProject.cxx                  | 10 +++
 io/io/src/TStreamerInfo.cxx                 |  1 +
 io/io/src/TStreamerInfoActions.cxx          |  6 +-
 io/xml/src/TXMLPlayer.cxx                   | 17 ++--
 tree/tree/src/TBranchElement.cxx            |  2 +
 tree/treeplayer/src/TTreeProxyGenerator.cxx | 17 ++--
 20 files changed, 224 insertions(+), 105 deletions(-)
 create mode 100644 core/metautils/src/unordered_setLinkdef.h

diff --git a/core/meta/inc/TDictionary.h b/core/meta/inc/TDictionary.h
index 911d52c65cae3..2e3d0f1a65531 100644
--- a/core/meta/inc/TDictionary.h
+++ b/core/meta/inc/TDictionary.h
@@ -190,16 +190,17 @@ class TDictionary : public TNamed {
 
    // Type of STL container (returned by IsSTLContainer).
    enum ESTLType {
-      kNone        = ROOT::kNotSTL,
-      kVector      = ROOT::kSTLvector,
-      kList        = ROOT::kSTLlist,
-      kForwardlist = ROOT::kSTLforwardlist,
-      kDeque       = ROOT::kSTLdeque,
-      kMap         = ROOT::kSTLmap,
-      kMultimap    = ROOT::kSTLmultimap,
-      kSet         = ROOT::kSTLset,
-      kMultiset    = ROOT::kSTLmultiset,
-      kBitset      = ROOT::kSTLbitset
+      kNone         = ROOT::kNotSTL,
+      kVector       = ROOT::kSTLvector,
+      kList         = ROOT::kSTLlist,
+      kForwardlist  = ROOT::kSTLforwardlist,
+      kDeque        = ROOT::kSTLdeque,
+      kMap          = ROOT::kSTLmap,
+      kMultimap     = ROOT::kSTLmultimap,
+      kSet          = ROOT::kSTLset,
+      kUnorderedSet = ROOT::kSTLunorderedset,
+      kMultiset     = ROOT::kSTLmultiset,
+      kBitset       = ROOT::kSTLbitset
    };
 
    typedef const void *DeclId_t;
diff --git a/core/meta/inc/TStreamerElement.h b/core/meta/inc/TStreamerElement.h
index 3b6f5ca572537..9876f7509e855 100644
--- a/core/meta/inc/TStreamerElement.h
+++ b/core/meta/inc/TStreamerElement.h
@@ -59,17 +59,18 @@ class TStreamerElement : public TNamed {
 public:
 
    enum ESTLtype {
-      kSTL            = ROOT::kSTLany,
-      kSTLstring      = ROOT::kSTLstring,
-      kSTLvector      = ROOT::kSTLvector,
-      kSTLlist        = ROOT::kSTLlist,
-      kSTLforwardlist = ROOT::kSTLforwardlist,
-      kSTLdeque       = ROOT::kSTLdeque,
-      kSTLmap         = ROOT::kSTLmap,
-      kSTLmultimap    = ROOT::kSTLmultimap,
-      kSTLset         = ROOT::kSTLset,
-      kSTLmultiset    = ROOT::kSTLmultiset,
-      kSTLbitset      = ROOT::kSTLbitset
+      kSTL             = ROOT::kSTLany,
+      kSTLstring       = ROOT::kSTLstring,
+      kSTLvector       = ROOT::kSTLvector,
+      kSTLlist         = ROOT::kSTLlist,
+      kSTLforwardlist  = ROOT::kSTLforwardlist,
+      kSTLdeque        = ROOT::kSTLdeque,
+      kSTLmap          = ROOT::kSTLmap,
+      kSTLmultimap     = ROOT::kSTLmultimap,
+      kSTLset          = ROOT::kSTLset,
+      kSTLunorderedset = ROOT::kSTLunorderedset,
+      kSTLmultiset     = ROOT::kSTLmultiset,
+      kSTLbitset       = ROOT::kSTLbitset
    };
    // TStreamerElement status bits
    enum {
diff --git a/core/meta/src/TBaseClass.cxx b/core/meta/src/TBaseClass.cxx
index 89428be6dfe7f..e04400fc60a82 100644
--- a/core/meta/src/TBaseClass.cxx
+++ b/core/meta/src/TBaseClass.cxx
@@ -110,16 +110,17 @@ ROOT::ESTLType TBaseClass::IsSTLContainer()
          fSTLType = -2;
       } else {
          const char *type = gCling->BaseClassInfo_TmpltName(fInfo);
-         if (!type)                             fSTLType = ROOT::kNotSTL;
-         else if (!strcmp(type, "vector"))      fSTLType = ROOT::kSTLvector;
-         else if (!strcmp(type, "list"))        fSTLType = ROOT::kSTLlist;
-         else if (!strcmp(type, "forward_list"))fSTLType = ROOT::kSTLforwardlist;
-         else if (!strcmp(type, "deque"))       fSTLType = ROOT::kSTLdeque;
-         else if (!strcmp(type, "map"))         fSTLType = ROOT::kSTLmap;
-         else if (!strcmp(type, "multimap"))    fSTLType = ROOT::kSTLmultimap;
-         else if (!strcmp(type, "set"))         fSTLType = ROOT::kSTLset;
-         else if (!strcmp(type, "multiset"))    fSTLType = ROOT::kSTLmultiset;
-         else                                   fSTLType = ROOT::kNotSTL;
+         if (!type)                               fSTLType = ROOT::kNotSTL;
+         else if (!strcmp(type, "vector"))        fSTLType = ROOT::kSTLvector;
+         else if (!strcmp(type, "list"))          fSTLType = ROOT::kSTLlist;
+         else if (!strcmp(type, "forward_list"))  fSTLType = ROOT::kSTLforwardlist;
+         else if (!strcmp(type, "deque"))         fSTLType = ROOT::kSTLdeque;
+         else if (!strcmp(type, "map"))           fSTLType = ROOT::kSTLmap;
+         else if (!strcmp(type, "multimap"))      fSTLType = ROOT::kSTLmultimap;
+         else if (!strcmp(type, "set"))           fSTLType = ROOT::kSTLset;
+         else if (!strcmp(type, "unordered_set")) fSTLType = ROOT::kSTLunorderedset;
+         else if (!strcmp(type, "multiset"))      fSTLType = ROOT::kSTLmultiset;
+         else                                     fSTLType = ROOT::kNotSTL;
       }
    }
    if (fSTLType == -2) return ROOT::kNotSTL;
diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index dba2f93644a1c..b7c365f16c633 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -1630,6 +1630,7 @@ void TCling::RegisterModule(const char* modulename,
        && strcmp(modulename,"libmapDict")!=0 && strcmp(modulename,"libmultimap2Dict")!=0
        && strcmp(modulename,"libmap2Dict")!=0 && strcmp(modulename,"libmultimapDict")!=0
        && strcmp(modulename,"libsetDict")!=0 && strcmp(modulename,"libmultisetDict")!=0
+       && strcmp(modulename,"libunordered_setDict")!=0
        && strcmp(modulename,"libvalarrayDict")!=0
        && strcmp(modulename,"G__GenVector32")!=0 && strcmp(modulename,"G__Smatrix32")!=0
 
diff --git a/core/meta/src/TStreamerElement.cxx b/core/meta/src/TStreamerElement.cxx
index 1a8c66e6be366..28f7f8650d5ae 100644
--- a/core/meta/src/TStreamerElement.cxx
+++ b/core/meta/src/TStreamerElement.cxx
@@ -1710,6 +1710,7 @@ TStreamerSTL::TStreamerSTL(const char *name, const char *title, Int_t offset,
    else if (strstr(s,"bitset"))            fSTLtype = ROOT::kSTLbitset;
    else if (strstr(s,"map"))               fSTLtype = ROOT::kSTLmap;
    else if (strstr(s,"set"))               fSTLtype = ROOT::kSTLset;
+   else if (strstr(s,"unordered_set"))     fSTLtype = ROOT::kSTLunorderedset;
    if (fSTLtype == 0) { delete [] s; return;}
    if (dmPointer) fSTLtype += TVirtualStreamerInfo::kOffsetP;
 
@@ -1861,15 +1862,16 @@ const char *TStreamerSTL::GetInclude() const
 {
    // Return the proper include for this element.
 
-   if      (fSTLtype == ROOT::kSTLvector)      IncludeNameBuffer().Form("<%s>","vector");
-   else if (fSTLtype == ROOT::kSTLlist)        IncludeNameBuffer().Form("<%s>","list");
-   else if (fSTLtype == ROOT::kSTLforwardlist) IncludeNameBuffer().Form("<%s>","forward_list");
-   else if (fSTLtype == ROOT::kSTLdeque)       IncludeNameBuffer().Form("<%s>","deque");
-   else if (fSTLtype == ROOT::kSTLmap)         IncludeNameBuffer().Form("<%s>","map");
-   else if (fSTLtype == ROOT::kSTLset)         IncludeNameBuffer().Form("<%s>","set");
-   else if (fSTLtype == ROOT::kSTLmultimap)    IncludeNameBuffer().Form("<%s>","map");
-   else if (fSTLtype == ROOT::kSTLmultiset)    IncludeNameBuffer().Form("<%s>","set");
-   else if (fSTLtype == ROOT::kSTLbitset)      IncludeNameBuffer().Form("<%s>","bitset");
+   if      (fSTLtype == ROOT::kSTLvector)       IncludeNameBuffer().Form("<%s>","vector");
+   else if (fSTLtype == ROOT::kSTLlist)         IncludeNameBuffer().Form("<%s>","list");
+   else if (fSTLtype == ROOT::kSTLforwardlist)  IncludeNameBuffer().Form("<%s>","forward_list");
+   else if (fSTLtype == ROOT::kSTLdeque)        IncludeNameBuffer().Form("<%s>","deque");
+   else if (fSTLtype == ROOT::kSTLmap)          IncludeNameBuffer().Form("<%s>","map");
+   else if (fSTLtype == ROOT::kSTLset)          IncludeNameBuffer().Form("<%s>","set");
+   else if (fSTLtype == ROOT::kSTLunorderedset) IncludeNameBuffer().Form("<%s>","unordered_set");
+   else if (fSTLtype == ROOT::kSTLmultimap)     IncludeNameBuffer().Form("<%s>","map");
+   else if (fSTLtype == ROOT::kSTLmultiset)     IncludeNameBuffer().Form("<%s>","set");
+   else if (fSTLtype == ROOT::kSTLbitset)       IncludeNameBuffer().Form("<%s>","bitset");
    return IncludeNameBuffer();
 }
 
diff --git a/core/metautils/CMakeLists.txt b/core/metautils/CMakeLists.txt
index 202872c9d0e8b..8b8091b679fb4 100644
--- a/core/metautils/CMakeLists.txt
+++ b/core/metautils/CMakeLists.txt
@@ -30,7 +30,7 @@ ROOT_INSTALL_HEADERS()
 
 #### STL dictionary (replacement for cintdlls)##############################
 
-set(stldicts vector list forward_list deque map map2 set multimap multimap2 multiset complex)
+set(stldicts vector list forward_list deque map map2 set unordered_set multimap multimap2 multiset complex)
 if(NOT WIN32)
   list(APPEND stldicts valarray)
 endif()
diff --git a/core/metautils/inc/ESTLType.h b/core/metautils/inc/ESTLType.h
index f4ff19e11bfd1..516445a277dc6 100644
--- a/core/metautils/inc/ESTLType.h
+++ b/core/metautils/inc/ESTLType.h
@@ -26,22 +26,23 @@
 namespace ROOT {
 
    enum ESTLType {
-      kNotSTL         = 0,
-      kSTLvector      = 1,
-      kSTLlist        = 2,
-      kSTLdeque       = 3,
-      kSTLmap         = 4,
-      kSTLmultimap    = 5,
-      kSTLset         = 6,
-      kSTLmultiset    = 7,
-      kSTLbitset      = 8,
+      kNotSTL          = 0,
+      kSTLvector       = 1,
+      kSTLlist         = 2,
+      kSTLdeque        = 3,
+      kSTLmap          = 4,
+      kSTLmultimap     = 5,
+      kSTLset          = 6,
+      kSTLmultiset     = 7,
+      kSTLbitset       = 8,
       // Here the c++11 containers start. Order counts. For example,
       // tstreamerelements in written rootfiles carry a value and we cannot
       // introduce shifts.
-      kSTLforwardlist = 9,
-      kSTLend         = 10,
-      kSTLany         = 300 /* TVirtualStreamerInfo::kSTL */,
-      kSTLstring      = 365 /* TVirtualStreamerInfo::kSTLstring */
+      kSTLforwardlist  = 9,
+      kSTLunorderedset = 10,
+      kSTLend          = 11,
+      kSTLany          = 300 /* TVirtualStreamerInfo::kSTL */,
+      kSTLstring       = 365 /* TVirtualStreamerInfo::kSTLstring */
    };
 
 }
diff --git a/core/metautils/inc/TClassEdit.h b/core/metautils/inc/TClassEdit.h
index 01c7e31bd97b0..9abc0e3abc177 100644
--- a/core/metautils/inc/TClassEdit.h
+++ b/core/metautils/inc/TClassEdit.h
@@ -84,21 +84,24 @@ namespace TClassEdit {
       kLong64           = 1<<8, /* replace all 'long long' with Long64_t. */
       kDropStd          = 1<<9, /* Drop any std:: */
       kKeepOuterConst   = 1<<10,/* Make sure to keep the const keyword even outside the template parameters */
-      kResolveTypedef   = 1<<11 /* Strip all typedef except Double32_t and co. */
+      kResolveTypedef   = 1<<11,/* Strip all typedef except Double32_t and co. */
+      kDropPredicate    = 1<<12,/* Drop the predicate if applies to the collection */
+      kDropHash         = 1<<13 /* Drop the hash if applies to the collection */
    };
 
    enum ESTLType {
-      kNotSTL     = ROOT::kNotSTL,
-      kVector     = ROOT::kSTLvector,
-      kList       = ROOT::kSTLlist,
-      kForwardist = ROOT::kSTLforwardlist,
-      kDeque      = ROOT::kSTLdeque,
-      kMap        = ROOT::kSTLmap,
-      kMultiMap   = ROOT::kSTLmultimap,
-      kSet        = ROOT::kSTLset,
-      kMultiSet   = ROOT::kSTLmultiset,
-      kBitSet     = ROOT::kSTLbitset,
-      kEnd        = ROOT::kSTLend
+      kNotSTL       = ROOT::kNotSTL,
+      kVector       = ROOT::kSTLvector,
+      kList         = ROOT::kSTLlist,
+      kForwardist   = ROOT::kSTLforwardlist,
+      kDeque        = ROOT::kSTLdeque,
+      kMap          = ROOT::kSTLmap,
+      kMultiMap     = ROOT::kSTLmultimap,
+      kSet          = ROOT::kSTLset,
+      kUnorderedSet = ROOT::kSTLunorderedset,
+      kMultiSet     = ROOT::kSTLmultiset,
+      kBitSet       = ROOT::kSTLbitset,
+      kEnd          = ROOT::kSTLend
    };
 
    class TInterpreterLookupHelper {
@@ -139,6 +142,8 @@ namespace TClassEdit {
    bool        IsDefAlloc(const char *alloc, const char *classname);
    bool        IsDefAlloc(const char *alloc, const char *keyclassname, const char *valueclassname);
    bool        IsDefComp (const char *comp , const char *classname);
+   bool        IsDefPred(const char *predname, const char *classname);
+   bool        IsDefHash(const char *hashname, const char *classname);
    bool        IsInterpreterDetail(const char *type);
    bool        IsSTLBitset(const char *type);
    ROOT::ESTLType IsSTLCont (const char *type);
diff --git a/core/metautils/src/TClassEdit.cxx b/core/metautils/src/TClassEdit.cxx
index c2d85f929ceba..c428ba30f136f 100644
--- a/core/metautils/src/TClassEdit.cxx
+++ b/core/metautils/src/TClassEdit.cxx
@@ -210,8 +210,8 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
    //    fprintf(stderr,"calling ShortType %d for %s with narg %d tail %d\n",imode,typeDesc,narg,tailLoc);
 
    //kind of stl container
-   int kind = STLKind(fElements[0].c_str());
-   int iall = STLArgs(kind);
+   const int kind = STLKind(fElements[0].c_str());
+   const int iall = STLArgs(kind);
 
    // Only class is needed
    if (mode&(8|16)) {
@@ -247,6 +247,7 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
                   case ROOT::kSTLforwardlist:
                   case ROOT::kSTLdeque:
                   case ROOT::kSTLset:
+                  case ROOT::kSTLunorderedset:
                   case ROOT::kSTLmultiset:
                      dropAlloc = IsDefAlloc(fElements[iall+1].c_str(),fElements[1].c_str());
                      break;
@@ -295,7 +296,36 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
                break;
          }
       }
-   }
+
+      // Treat now Pred and Hash for unordered containers. Signature is:
+      // template < class Key,
+      //             class Hash = hash<Key>,
+      //             class Pred = equal_to<Key>,
+      //             class Alloc = allocator<Key>
+      //          > class unordered_{set,multiset}
+
+      if (kind == ROOT::kSTLunorderedset){
+
+         bool predRemoved = false;
+
+         if ( allocRemoved && (mode & kDropStlDefault) && narg-1 == iall) { // remove default predicate
+            if ( IsDefPred( fElements[iall].c_str(), fElements[1].c_str() ) ) {
+               predRemoved=true;
+               narg--;
+            }
+         }
+
+         bool hashRemoved = false;
+
+         if ( predRemoved && (mode & kDropStlDefault) && narg == iall) { // remove default hash
+            if ( IsDefHash( fElements[iall-1].c_str(), fElements[1].c_str() ) ) {
+               hashRemoved = true;
+               narg--;
+            }
+         }
+      }
+
+   } // End of treatment of stl containers
    else {
       if ( (mode & kDropStlDefault) && (narg >= 3)) {
          unsigned int offset = (0==strncmp("const ",fElements[0].c_str(),6)) ? 6 : 0;
@@ -412,15 +442,17 @@ ROOT::ESTLType TClassEdit::STLKind(const char *type, size_t len)
 
    //container names
    static const char *stls[] =
-      { "any", "vector", "list", "deque", "map", "multimap", "set", "multiset", "bitset", "forward_list", 0};
+      { "any", "vector", "list", "deque", "map", "multimap", "set", "multiset", "bitset", "forward_list", "unordered_set", 0};
    static const size_t stllen[] =
-      { 3, 6, 4, 5, 3, 8, 3, 8, 6, 12, 0};
+      { 3, 6, 4, 5, 3, 8, 3, 8, 6, 12, 13, 0};
    static const ROOT::ESTLType values[] =
       {  ROOT::kNotSTL, ROOT::kSTLvector,
          ROOT::kSTLlist, ROOT::kSTLdeque,
          ROOT::kSTLmap, ROOT::kSTLmultimap,
          ROOT::kSTLset, ROOT::kSTLmultiset,
-         ROOT::kSTLbitset, ROOT::kSTLforwardlist,
+         ROOT::kSTLbitset,
+         ROOT::kSTLforwardlist,
+         ROOT::kSTLunorderedset,
          ROOT::kNotSTL
       };
 
@@ -444,8 +476,8 @@ int   TClassEdit::STLArgs(int kind)
 //      Return number of arguments for STL container before allocator
 
    static const char  stln[] =// min number of container arguments
-      //     vector, list, deque, map, multimap, set, multiset, bitset, forward_list
-      {    1,     1,    1,     1,   3,        3,   2,        2,      1,            1};
+      //     vector, list, deque, map, multimap, set, multiset, bitset, forward_list, unordered_set
+      {    1,     1,    1,     1,   3,        3,   2,        2,      1,            1,             3};
 
    return stln[kind];
 }
@@ -623,20 +655,19 @@ bool TClassEdit::IsDefAlloc(const char *allocname,
 }
 
 //______________________________________________________________________________
-bool TClassEdit::IsDefComp(const char *compname, const char *classname)
+static bool IsDefElement(const char *elementName, const char* defaultElementName, const char *classname)
 {
-   // return whether or not 'compare' is the STL default comparator for type
+   // return whether or not 'elementName' is the STL default Element for type
    // 'classname'
-
-   string c = compname;
+   string c = elementName;
 
    size_t pos = StdLen(c);
 
-   const static int lesslen = strlen("less<");
-   if (c.compare(pos,lesslen,"less<") != 0) {
+   const int elementlen = strlen(defaultElementName);
+   if (c.compare(pos,elementlen,defaultElementName) != 0) {
       return false;
    }
-   pos += lesslen;
+   pos += elementlen;
 
    string k = classname;
    if (c.compare(pos,k.length(),k) != 0) {
@@ -644,10 +675,10 @@ bool TClassEdit::IsDefComp(const char *compname, const char *classname)
       size_t end = findNameEnd(c,pos);
 
       std::string keypart;
-      GetNormalizedName(keypart,c.substr(pos,end-pos).c_str());
+      TClassEdit::GetNormalizedName(keypart,c.substr(pos,end-pos).c_str());
 
       std::string norm_key;
-      GetNormalizedName(norm_key,k.c_str());
+      TClassEdit::GetNormalizedName(norm_key,k.c_str());
 
       if (keypart != norm_key) {
          return false;
@@ -664,6 +695,32 @@ bool TClassEdit::IsDefComp(const char *compname, const char *classname)
    return true;
 }
 
+//______________________________________________________________________________
+bool TClassEdit::IsDefComp(const char *compname, const char *classname)
+{
+   // return whether or not 'compare' is the STL default comparator for type
+   // 'classname'
+
+   return IsDefElement(compname, "less<", classname);
+}
+
+//______________________________________________________________________________
+bool TClassEdit::IsDefPred(const char *predname, const char *classname)
+{
+   // return whether or not 'predname' is the STL default predicate for type
+   // 'classname'
+   return IsDefElement(predname, "equal_to<", classname);
+}
+
+//______________________________________________________________________________
+bool TClassEdit::IsDefHash(const char *hashname, const char *classname)
+{
+   // return whether or not 'hashname' is the STL default hash for type
+   // 'classname'
+
+   return IsDefElement(hashname, "hash<", classname);
+}
+
 //______________________________________________________________________________
 void TClassEdit::GetNormalizedName(std::string &norm_name, const char *name)
 {
@@ -1161,6 +1218,7 @@ bool TClassEdit::IsStdClass(const char *classname)
    if ( strncmp(classname,"map<",strlen("map<"))==0) return true;
    if ( strncmp(classname,"multimap<",strlen("multimap<"))==0) return true;
    if ( strncmp(classname,"set<",strlen("set<"))==0) return true;
+   if ( strncmp(classname,"unordered_set<",strlen("unordered_set<"))==0) return true;
    if ( strncmp(classname,"multiset<",strlen("multiset<"))==0) return true;
    if ( strncmp(classname,"bitset<",strlen("bitset<"))==0) return true;
 
@@ -1521,6 +1579,7 @@ string TClassEdit::InsertStd(const char *tname)
       "greater",
       "gslice_array",
       "gslice",
+      "hash",
       "indirect_array",
       "invalid_argument",
       "ios_base",
@@ -1591,6 +1650,7 @@ string TClassEdit::InsertStd(const char *tname)
       "unary_function",
       "unary_negate",
       "underflow_error",
+      "unordered_set",
       "valarray",
       "vector",
       "wstring"
diff --git a/core/metautils/src/TMetaUtils.cxx b/core/metautils/src/TMetaUtils.cxx
index 6bc2791d52869..124c6485123f7 100644
--- a/core/metautils/src/TMetaUtils.cxx
+++ b/core/metautils/src/TMetaUtils.cxx
@@ -1836,8 +1836,8 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
 
       needCollectionProxy = true;
    } else if (stl != 0 &&
-              ((stl>0 && stl<10) || (stl<0 && stl>-10)) && // is an stl container
-              (stl != 8 && stl !=-8) ){     // is no bitset
+              ((stl > 0 && stl<ROOT::kSTLend) || (stl < 0 && stl>-ROOT::kSTLend)) && // is an stl container
+              (stl != ROOT::kSTLbitset && stl !=-ROOT::kSTLbitset) ){     // is no bitset
       int idx = classname.find("<");
       int stlType = (idx!=(int)std::string::npos) ? TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
       const char* methodTCP=0;
@@ -1855,6 +1855,7 @@ void ROOT::TMetaUtils::WriteClassInit(std::ostream& finalString,
             methodTCP="MapInsert";
             break;
          case ROOT::kSTLset:
+         case ROOT::kSTLunorderedset:
          case ROOT::kSTLmultiset:
             methodTCP="Insert";
             break;
@@ -4583,13 +4584,15 @@ ROOT::ESTLType ROOT::TMetaUtils::STLKind(const llvm::StringRef type)
    // Converts STL container name to number. vector -> 1, etc..
 
    static const char *stls[] =                  //container names
-      {"any","vector","list", "deque","map","multimap","set","multiset","bitset","forward_list",0};
+      {"any","vector","list", "deque","map","multimap","set","multiset","bitset","forward_list","unordered_set",0};
    static const ROOT::ESTLType values[] =
       {ROOT::kNotSTL, ROOT::kSTLvector,
        ROOT::kSTLlist, ROOT::kSTLdeque,
        ROOT::kSTLmap, ROOT::kSTLmultimap,
        ROOT::kSTLset, ROOT::kSTLmultiset,
-       ROOT::kSTLbitset, ROOT::kSTLforwardlist,
+       ROOT::kSTLbitset,
+       ROOT::kSTLforwardlist,
+       ROOT::kSTLunorderedset,
        ROOT::kNotSTL
       };
    //              kind of stl container
diff --git a/core/metautils/src/unordered_setLinkdef.h b/core/metautils/src/unordered_setLinkdef.h
new file mode 100644
index 0000000000000..cc7d28a667021
--- /dev/null
+++ b/core/metautils/src/unordered_setLinkdef.h
@@ -0,0 +1,13 @@
+#include <unordered_set>
+#include <string>
+#ifndef __hpux
+using namespace std;
+#endif
+
+#pragma create TClass unordered_set<int>;
+#pragma create TClass unordered_set<long>;
+#pragma create TClass unordered_set<float>;
+#pragma create TClass unordered_set<double>;
+#pragma create TClass unordered_set<void*>;
+#pragma create TClass unordered_set<char*>;
+#pragma create TClass unordered_set<string>;
diff --git a/core/utils/src/rootcling.cxx b/core/utils/src/rootcling.cxx
index 6a4d871e55411..10f8335ca6dae 100644
--- a/core/utils/src/rootcling.cxx
+++ b/core/utils/src/rootcling.cxx
@@ -1192,6 +1192,7 @@ int STLContainerStreamer(const clang::FieldDecl &m,
                break;
             }
          case kSTLset:
+         case kSTLunorderedset:
          case kSTLmultiset:
             dictStream << "            R__stl.insert(R__t);" << std::endl;
             break;
diff --git a/io/io/src/TGenCollectionProxy.cxx b/io/io/src/TGenCollectionProxy.cxx
index bd5d6dced6c5e..e5cffb524dd67 100644
--- a/io/io/src/TGenCollectionProxy.cxx
+++ b/io/io/src/TGenCollectionProxy.cxx
@@ -753,6 +753,7 @@ TVirtualCollectionProxy* TGenCollectionProxy::Generate() const
       case ROOT::kSTLmultimap:
          return new TGenMapProxy(*this);
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
       case ROOT::kSTLmultiset:
          return new TGenSetProxy(*this);
       default:
@@ -843,6 +844,7 @@ TGenCollectionProxy *TGenCollectionProxy::InitializeEx(Bool_t silent)
             case ROOT::kSTLmap:
             case ROOT::kSTLmultimap:
             case ROOT::kSTLset:
+            case ROOT::kSTLunorderedset:
             case ROOT::kSTLmultiset:
             case ROOT::kSTLbitset: // not really an associate container but it has no real iterator.
                fProperties |= kIsAssociative;
@@ -999,6 +1001,7 @@ void* TGenCollectionProxy::At(UInt_t idx)
             return ((char*)fEnv->fStart) + fValDiff*idx;
          }
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
       case ROOT::kSTLmultiset:
       case ROOT::kSTLmap:
       case ROOT::kSTLmultimap:
@@ -1086,6 +1089,7 @@ void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t /* forceDelete */ )
    if ( fEnv && fEnv->fObject ) {
       switch ( fSTL_type ) {
          case ROOT::kSTLset:
+         case ROOT::kSTLunorderedset:
          case ROOT::kSTLmultiset:
          case ROOT::kSTLmap:
          case ROOT::kSTLmultimap: {
diff --git a/io/io/src/TGenCollectionStreamer.cxx b/io/io/src/TGenCollectionStreamer.cxx
index 599b9589ada7a..802f518c22490 100644
--- a/io/io/src/TGenCollectionStreamer.cxx
+++ b/io/io/src/TGenCollectionStreamer.cxx
@@ -439,6 +439,7 @@ void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b, const TClass
          // Once they are created. Need to take memory from stack or heap.
       case ROOT::kSTLmultiset:
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
          fEnv->fStart = itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
          fConstruct(itm,nElements);
@@ -548,6 +549,7 @@ void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b)
          // Once they are created. Need to take memory from stack or heap.
       case ROOT::kSTLmultiset:
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
          fEnv->fStart = itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
          fConstruct(itm,nElements);
@@ -1022,6 +1024,7 @@ void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b)
       case ROOT::kSTLdeque:
       case ROOT::kSTLmultiset:
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
          switch (fVal->fCase) {
             case kIsClass:
@@ -1375,6 +1378,7 @@ void TGenCollectionStreamer::ReadBufferGeneric(TBuffer &b, void *obj, const TCla
          case ROOT::kSTLdeque:
          case ROOT::kSTLmultiset:
          case ROOT::kSTLset:
+         case ROOT::kSTLunorderedset:
             if (obj) {
                if (fProperties & kNeedDelete)   {
                   TGenCollectionProxy::Clear("force");
@@ -1426,6 +1430,7 @@ void TGenCollectionStreamer::Streamer(TBuffer &b)
             case ROOT::kSTLdeque:
             case ROOT::kSTLmultiset:
             case ROOT::kSTLset:
+            case ROOT::kSTLunorderedset:
                switch (fVal->fCase) {
                   case kIsFundamental:  // Only handle primitives this way
                   case kIsEnum:
@@ -1456,6 +1461,7 @@ void TGenCollectionStreamer::Streamer(TBuffer &b)
             case ROOT::kSTLdeque:
             case ROOT::kSTLmultiset:
             case ROOT::kSTLset:
+            case ROOT::kSTLunorderedset:
                switch (fVal->fCase) {
                   case kIsFundamental:  // Only handle primitives this way
                   case kIsEnum:
@@ -1495,7 +1501,8 @@ void TGenCollectionStreamer::StreamerAsMap(TBuffer &b)
             case ROOT::kSTLforwardlist:
             case ROOT::kSTLdeque:
             case ROOT::kSTLmultiset:
-            case ROOT::kSTLset: {
+            case ROOT::kSTLset:
+            case ROOT::kSTLunorderedset: {
                   ReadPairFromMap(nElements, b);
                   break;
                }
diff --git a/io/io/src/TMakeProject.cxx b/io/io/src/TMakeProject.cxx
index f4918d3d54c25..154c6c126d5d1 100644
--- a/io/io/src/TMakeProject.cxx
+++ b/io/io/src/TMakeProject.cxx
@@ -478,6 +478,9 @@ UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, ch
                      case ROOT::kSTLset:
                         what = "set";
                         break;
+                     case ROOT::kSTLunorderedset:
+                        what = "unordered_set";
+                        break;
                      case ROOT::kSTLmultiset:
                         what = "set";
                         break;
@@ -655,6 +658,12 @@ TString TMakeProject::UpdateAssociativeToVector(const char *name)
                --narg;
             }
             break;
+         case ROOT::kSTLunorderedset:
+         // case ROOT::kSTLunorderedmultiset:
+            if (narg>5 && strncmp(inside[5].c_str(),"std::allocator<",strlen("std::allocator<"))==0) {
+               --narg;
+            }
+            break;
       }
       if (stlkind!=0) {
          TClass *key = TClass::GetClass(inside[1].c_str());
@@ -682,6 +691,7 @@ TString TMakeProject::UpdateAssociativeToVector(const char *name)
                   break;
                }
                case ROOT::kSTLset:
+               case ROOT::kSTLunorderedset:
                case ROOT::kSTLmultiset:
                   inside[0] = "std::vector";
                   break;
diff --git a/io/io/src/TStreamerInfo.cxx b/io/io/src/TStreamerInfo.cxx
index 599fbdb7be79f..2c163341a6727 100644
--- a/io/io/src/TStreamerInfo.cxx
+++ b/io/io/src/TStreamerInfo.cxx
@@ -3488,6 +3488,7 @@ void TStreamerInfo::GenerateDeclaration(FILE *fp, FILE *sfp, const TList *subCla
                case ROOT::kSTLmap:
                case ROOT::kSTLmultimap:
                case ROOT::kSTLset:
+               case ROOT::kSTLunorderedset:
                case ROOT::kSTLmultiset:
                {
                   enamebasic = TMakeProject::UpdateAssociativeToVector(enamebasic);
diff --git a/io/io/src/TStreamerInfoActions.cxx b/io/io/src/TStreamerInfoActions.cxx
index f1c218f019070..f8388777b42ce 100644
--- a/io/io/src/TStreamerInfoActions.cxx
+++ b/io/io/src/TStreamerInfoActions.cxx
@@ -958,7 +958,8 @@ namespace TStreamerInfoActions
    {
       if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated) ) {
          return kVectorLooper;
-      } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
+      } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
+                 || proxy.GetCollectionType() == ROOT::kSTLmultiset
                  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap
                  || proxy.GetCollectionType() == ROOT::kSTLbitset) {
          return kAssociativeLooper;
@@ -2912,7 +2913,8 @@ TStreamerInfoActions::TActionSequence *TStreamerInfoActions::TActionSequence::Cr
       // We can speed up the iteration in case of vector.  We also know that all emulated collection are stored internally as a vector.
       Long_t increment = proxy.GetIncrement();
       sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kTRUE);
-   } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
+   } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
+              || proxy.GetCollectionType() == ROOT::kSTLmultiset
               || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)
    {
       Long_t increment = proxy.GetIncrement();
diff --git a/io/xml/src/TXMLPlayer.cxx b/io/xml/src/TXMLPlayer.cxx
index 1a4096d45f840..7dd98dbb19a6f 100644
--- a/io/xml/src/TXMLPlayer.cxx
+++ b/io/xml/src/TXMLPlayer.cxx
@@ -968,14 +968,15 @@ Bool_t TXMLPlayer::ProduceSTLstreamer(std::ostream& fs, TClass* cl, TStreamerSTL
 
          stltyp = TClassEdit::STLKind(splitName[0].c_str());
          switch (stltyp) {
-            case ROOT::kSTLvector      : narg = 1; break;
-            case ROOT::kSTLlist        : narg = 1; break;
-            case ROOT::kSTLforwardlist : narg = 1; break;
-            case ROOT::kSTLdeque       : narg = 1; break;
-            case ROOT::kSTLmap         : narg = 2; break;
-            case ROOT::kSTLmultimap    : narg = 2; break;
-            case ROOT::kSTLset         : narg = 1; break;
-            case ROOT::kSTLmultiset    : narg = 1; break;
+            case ROOT::kSTLvector       : narg = 1; break;
+            case ROOT::kSTLlist         : narg = 1; break;
+            case ROOT::kSTLforwardlist  : narg = 1; break;
+            case ROOT::kSTLdeque        : narg = 1; break;
+            case ROOT::kSTLmap          : narg = 2; break;
+            case ROOT::kSTLmultimap     : narg = 2; break;
+            case ROOT::kSTLset          : narg = 1; break;
+            case ROOT::kSTLunorderedset : narg = 1; break;
+            case ROOT::kSTLmultiset     : narg = 1; break;
             default: return false;
          }
 
diff --git a/tree/tree/src/TBranchElement.cxx b/tree/tree/src/TBranchElement.cxx
index 6cf4decff498b..4d3ac62c6f424 100644
--- a/tree/tree/src/TBranchElement.cxx
+++ b/tree/tree/src/TBranchElement.cxx
@@ -2299,6 +2299,7 @@ Int_t TBranchElement::GetEntry(Long64_t entry, Int_t getall)
       }
       switch(fSTLtype) {
          case ROOT::kSTLset:
+         case ROOT::kSTLunorderedset:
          case ROOT::kSTLmultiset:
          case ROOT::kSTLmap:
          case ROOT::kSTLmultimap:
@@ -3774,6 +3775,7 @@ void TBranchElement::ReadLeavesCollection(TBuffer& b)
    Int_t nbranches = fBranches.GetEntriesFast();
    switch (fSTLtype) {
       case ROOT::kSTLset:
+      case ROOT::kSTLunorderedset:
       case ROOT::kSTLmultiset:
       case ROOT::kSTLmap:
       case ROOT::kSTLmultimap:
diff --git a/tree/treeplayer/src/TTreeProxyGenerator.cxx b/tree/treeplayer/src/TTreeProxyGenerator.cxx
index 2fd3998eb5319..496e9275d0d48 100644
--- a/tree/treeplayer/src/TTreeProxyGenerator.cxx
+++ b/tree/treeplayer/src/TTreeProxyGenerator.cxx
@@ -385,18 +385,21 @@ namespace ROOT {
       } else if (cl->GetCollectionProxy() && (stlType=TClassEdit::IsSTLCont(cl->GetName()))) {
          const char *what = "";
          switch(stlType)  {
-            case ROOT::kSTLvector:   what = "vector"; break;
-            case ROOT::kSTLlist:     what = "list"; break;
+            case ROOT::kSTLvector:       what = "vector"; break;
+            case ROOT::kSTLlist:         what = "list"; break;
+            case ROOT::kSTLforwardlist:  what = "forward_list"; break;
             case -ROOT::kSTLdeque: // same as positive
-            case ROOT::kSTLdeque:    what = "deque"; break;
+            case ROOT::kSTLdeque:        what = "deque"; break;
             case -ROOT::kSTLmap: // same as positive
-            case ROOT::kSTLmap:      what = "map"; break;
+            case ROOT::kSTLmap:          what = "map"; break;
             case -ROOT::kSTLmultimap: // same as positive
-            case ROOT::kSTLmultimap: what = "map"; break;
+            case ROOT::kSTLmultimap:     what = "map"; break;
             case -ROOT::kSTLset:  // same as positive
-            case ROOT::kSTLset:      what = "set"; break;
+            case ROOT::kSTLset:          what = "set"; break;
+            case -ROOT::kSTLunorderedset:  // same as positive
+            case ROOT::kSTLunorderedset: what = "unordered_set"; break;
             case -ROOT::kSTLmultiset: // same as positive
-            case ROOT::kSTLmultiset: what = "set"; break;
+            case ROOT::kSTLmultiset:     what = "set"; break;
          }
          if (what[0]) {
             directive = "#include <";

From a872dfba1f4057655e6468f518d6263d7ee3ac3c Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Mon, 9 Mar 2015 06:11:13 -0500
Subject: [PATCH 199/200] Add missing lock in TCling::AutoParse

---
 core/meta/src/TCling.cxx | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/meta/src/TCling.cxx b/core/meta/src/TCling.cxx
index b7c365f16c633..ff5911631d161 100644
--- a/core/meta/src/TCling.cxx
+++ b/core/meta/src/TCling.cxx
@@ -4983,6 +4983,8 @@ Int_t TCling::AutoParse(const char *cls)
    // Parse the headers relative to the class
    // Returns 1 in case of success, 0 in case of failure
 
+   R__LOCKGUARD(gInterpreterMutex);
+
    if (!fHeaderParsingOnDemand || fIsAutoParsingSuspended) {
       if (fClingCallbacks->IsAutoloadingEnabled()) {
          return AutoLoad(cls);

From 58f8198a0685c090bc8b70132fc76443a19d714a Mon Sep 17 00:00:00 2001
From: Danilo Piparo <danilo.piparo@cern.ch>
Date: Mon, 9 Mar 2015 12:58:02 +0100
Subject: [PATCH 200/200] Remove unused variable

---
 core/metautils/src/TClassEdit.cxx | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/core/metautils/src/TClassEdit.cxx b/core/metautils/src/TClassEdit.cxx
index c428ba30f136f..ff5d3e897e197 100644
--- a/core/metautils/src/TClassEdit.cxx
+++ b/core/metautils/src/TClassEdit.cxx
@@ -315,11 +315,8 @@ void TClassEdit::TSplitType::ShortType(std::string &answ, int mode)
             }
          }
 
-         bool hashRemoved = false;
-
          if ( predRemoved && (mode & kDropStlDefault) && narg == iall) { // remove default hash
             if ( IsDefHash( fElements[iall-1].c_str(), fElements[1].c_str() ) ) {
-               hashRemoved = true;
                narg--;
             }
          }