]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - SHUTTLE/AliShuttle.cxx
bug fix in the name of the raw tag files (Raw instead of raw)
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttle.cxx
index 13474e7268c18af31badc172c9640678b8172720..02a723f4e0bd2cab204aa03a01ae174018434be9 100644 (file)
 
 /*
 $Log$
+Revision 1.75  2007/12/18 15:42:14  jgrosseo
+adding number of open runs to monitoring
+
+Revision 1.74  2007/12/17 03:23:32  jgrosseo
+several bugfixes
+added "empty preprocessor" as placeholder for Acorde in FDR
+
+Revision 1.73  2007/12/14 19:31:36  acolla
+Sending email to DCS experts is temporarily commented
+
+Revision 1.72  2007/12/13 15:44:28  acolla
+Run type added in mail sent to detector expert (eases understanding)
+
+Revision 1.71  2007/12/12 14:56:14  jgrosseo
+sending shuttle_ignore to ML also in case of 0 events
+
+Revision 1.70  2007/12/12 13:45:35  acolla
+Monalisa started in Collect() function. Alive message to monitor is sent at each Collect and every minute during preprocessor processing.
+
+Revision 1.69  2007/12/12 10:06:29  acolla
+in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times:
+
+time_start==0 && time_end==0
+
+logbook is NOT updated if time_start != 0 && time_end == 0, because it may mean that the run is still ongoing.
+
+Revision 1.68  2007/12/11 10:15:17  acolla
+Added marking SHUTTLE=DONE for invalid runs
+(invalid start time or end time) and runs with totalEvents < 1
+
+Revision 1.67  2007/12/07 19:14:36  acolla
+in AliShuttleTrigger:
+
+Added automatic collection of new runs on a regular time basis (settable from the configuration)
+
+in AliShuttleConfig: new members
+
+- triggerWait: time to wait for DIM trigger (s) before starting automatic collection of new runs
+- mode: run mode (test, prod) -> used to build log folder (logs or logs_PROD)
+
+in AliShuttle:
+
+- logs now stored in logs/#RUN/DET_#RUN.log
+
+Revision 1.66  2007/12/05 10:45:19  jgrosseo
+changed order of arguments to TMonaLisaWriter
+
+Revision 1.65  2007/11/26 16:58:37  acolla
+Monalisa configuration added: host and table name
+
+Revision 1.64  2007/11/13 16:15:47  acolla
+DCS map is stored in a file in the temp folder where the detector is processed.
+If the preprocessor fails, the temp folder is not removed. This will help the debugging of the problem.
+
+Revision 1.63  2007/11/02 10:53:16  acolla
+Protection added to AliShuttle::CopyFileLocally
+
+Revision 1.62  2007/10/31 18:23:13  acolla
+Furter developement on the Shuttle:
+
+- Shuttle now connects to the Grid as alidaq. The OCDB and Reference folders
+are now built from /alice/data, e.g.:
+/alice/data/2007/LHC07a/OCDB
+
+the year and LHC period are taken from the Shuttle.
+Raw metadata files are stored by GRP to:
+/alice/data/2007/LHC07a/<runNb>/Raw/RunMetadata.root
+
+- Shuttle sends a mail to DCS experts each time DP retrieval fails.
+
+Revision 1.61  2007/10/30 20:33:51  acolla
+Improved managing of temporary folders, which weren't correctly handled.
+Resolved bug introduced in StoreReferenceFile, which caused SPD preprocessor fail.
+
+Revision 1.60  2007/10/29 18:06:16  acolla
+
+New function StoreRunMetadataFile added to preprocessor and Shuttle interface
+This function can be used by GRP only. It stores raw data tags merged file to the
+raw data folder (e.g. /alice/data/2008/LHC08a/000099999/Raw).
+
+KNOWN ISSUES:
+
+1. Shuttle cannot write to /alice/data/ because it belongs to alidaq. Tag file is stored in /alice/simulation/... for the time being.
+2. Due to a bug in TAlien::Mkdir, the creation of a folder in recursive mode (-p option) does not work. The problem
+has been corrected in the root package on the Shuttle machine.
+
+Revision 1.59  2007/10/05 12:40:55  acolla
+
+Result error code added to AliDCSClient data members (it was "lost" with the new implementation of TMap* GetAliasValues and GetDPValues).
+
+Revision 1.58  2007/09/28 15:27:40  acolla
+
+AliDCSClient "multiSplit" option added in the DCS configuration
+in AliDCSMessage: variable MAX_BODY_SIZE set to 500000
+
+Revision 1.57  2007/09/27 16:53:13  acolla
+Detectors can have more than one AMANDA server. SHUTTLE queries the servers sequentially,
+merges the dcs aliases/DPs in one TMap and sends it to the preprocessor.
+
+Revision 1.56  2007/09/14 16:46:14  jgrosseo
+1) Connect and Close are called before and after each query, so one can
+keep the same AliDCSClient object.
+2) The splitting of a query is moved to GetDPValues/GetAliasValues.
+3) Splitting interval can be specified in constructor
+
+Revision 1.55  2007/08/06 12:26:40  acolla
+Function Bool_t GetHLTStatus added to preprocessor. It returns the status of HLT
+read from the run logbook.
+
+Revision 1.54  2007/07/12 09:51:25  jgrosseo
+removed duplicated log message in GetFile
+
+Revision 1.53  2007/07/12 09:26:28  jgrosseo
+updating hlt fxs base path
+
+Revision 1.52  2007/07/12 08:06:45  jgrosseo
+adding log messages in getfile... functions
+adding not implemented copy constructor in alishuttleconfigholder
+
+Revision 1.51  2007/07/03 17:24:52  acolla
+root moved to v5-16-00. TFileMerger->Cp moved to TFile::Cp.
+
+Revision 1.50  2007/07/02 17:19:32  acolla
+preprocessor is run in a temp directory that is removed when process is finished.
+
+Revision 1.49  2007/06/29 10:45:06  acolla
+Number of columns in MySql Shuttle logbook increased by one (HLT added)
+
+Revision 1.48  2007/06/21 13:06:19  acolla
+GetFileSources returns dummy list with 1 source if system=DCS (better than
+returning error as it was)
+
+Revision 1.47  2007/06/19 17:28:56  acolla
+HLT updated; missing map bug removed.
+
+Revision 1.46  2007/06/09 13:01:09  jgrosseo
+Switching to retrieval of several DCS DPs at a time (multiDPrequest)
+
+Revision 1.45  2007/05/30 06:35:20  jgrosseo
+Adding functionality to the Shuttle/TestShuttle:
+o) Function to retrieve list of sources from a given system (GetFileSources with id=0)
+o) Function to retrieve list of IDs for a given source      (GetFileIDs)
+These functions are needed for dealing with the tag files that are saved for the GRP preprocessor
+Example code has been added to the TestProcessor in TestShuttle
+
+Revision 1.44  2007/05/11 16:09:32  acolla
+Reference files for ITS, MUON and PHOS are now stored in OfflineDetName/OnlineDetName/run_...
+example: ITS/SPD/100_filename.root
+
+Revision 1.43  2007/05/10 09:59:51  acolla
+Various bug fixes in StoreRefFilesToGrid; Cleaning of reference storage before processing detector (CleanReferenceStorage)
+
+Revision 1.42  2007/05/03 08:01:39  jgrosseo
+typo in last commit :-(
+
+Revision 1.41  2007/05/03 08:00:48  jgrosseo
+fixing log message when pp want to skip dcs value retrieval
+
+Revision 1.40  2007/04/27 07:06:48  jgrosseo
+GetFileSources returns empty list in case of no files, but successful query
+No mails sent in testmode
+
+Revision 1.39  2007/04/17 12:43:57  acolla
+Correction in StoreOCDB; change of text in mail to detector expert
+
+Revision 1.38  2007/04/12 08:26:18  jgrosseo
+updated comment
+
+Revision 1.37  2007/04/10 16:53:14  jgrosseo
+redirecting sub detector stdout, stderr to sub detector log file
+
+Revision 1.35  2007/04/04 16:26:38  acolla
+1. Re-organization of function calls in TestPreprocessor to make it more meaningful.
+2. Added missing dependency in test preprocessors.
+3. in AliShuttle.cxx: processing time and memory consumption info on a single line.
+
+Revision 1.34  2007/04/04 10:33:36  jgrosseo
+1) Storing of files to the Grid is now done _after_ your preprocessors succeeded. This is transparent, which means that you can still use the same functions (Store, StoreReferenceData) to store files to the Grid. However, the Shuttle first stores them locally and transfers them after the preprocessor finished. The return code of these two functions has changed from UInt_t to Bool_t which gives you the success of the storing.
+In case of an error with the Grid, the Shuttle will retry the storing later, the preprocessor does not need to be run again.
+
+2) The meaning of the return code of the preprocessor has changed. 0 is now success and any other value means failure. This value is stored in the log and you can use it to keep details about the error condition.
+
+3) New function StoreReferenceFile to _directly_ store a file (without opening it) to the reference storage.
+
+4) The memory usage of the preprocessor is monitored. If it exceeds 2 GB it is terminated.
+
+5) New function AliPreprocessor::ProcessDCS(). If you do not need to have DCS data in all cases, you can skip the processing by implemting this function and returning kFALSE under certain conditions. E.g. if there is a certain run type.
+If you always need DCS data (like before), you do not need to implement it.
+
+6) The run type has been added to the monitoring page
+
+Revision 1.33  2007/04/03 13:56:01  acolla
+Grid Storage at the end of preprocessing. Added virtual method to disable DCS query according to the
+run type.
+
+Revision 1.32  2007/02/28 10:41:56  acolla
+Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
+AliPreprocessor::GetRunType() function.
+Added some ldap definition files.
+
+Revision 1.30  2007/02/13 11:23:21  acolla
+Moved getters and setters of Shuttle's main OCDB/Reference, local
+OCDB/Reference, temp and log folders to AliShuttleInterface
+
+Revision 1.27  2007/01/30 17:52:42  jgrosseo
+adding monalisa monitoring
+
+Revision 1.26  2007/01/23 19:20:03  acolla
+Removed old ldif files, added TOF, MCH ldif files. Added some options in
+AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
+SetShuttleLogDir
+
+Revision 1.25  2007/01/15 19:13:52  acolla
+Moved some AliInfo to AliDebug in SendMail function
+
 Revision 1.21  2006/12/07 08:51:26  jgrosseo
 update (alberto):
 table, db names in ldap configuration
@@ -161,6 +376,13 @@ some docs added
 #include <TSQLResult.h>
 #include <TSQLRow.h>
 #include <TMutex.h>
+#include <TSystemDirectory.h>
+#include <TSystemFile.h>
+#include <TFile.h>
+#include <TGrid.h>
+#include <TGridResult.h>
+
+#include <TMonaLisaWriter.h>
 
 #include <fstream>
 
@@ -169,16 +391,6 @@ some docs added
 
 ClassImp(AliShuttle)
 
-TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
-TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
-TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
-TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
-
-Bool_t AliShuttle::fgkProcessDCS(kTRUE); 
-
-const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
-const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
-
 //______________________________________________________________________________________________
 AliShuttle::AliShuttle(const AliShuttleConfig* config,
                UInt_t timeout, Int_t retries):
@@ -188,10 +400,13 @@ fPreprocessorMap(),
 fLogbookEntry(0),
 fCurrentDetector(),
 fStatusEntry(0),
-fGridError(kFALSE),
 fMonitoringMutex(0),
 fLastActionTime(0),
-fLastAction()
+fLastAction(),
+fMonaLisa(0),
+fTestMode(kNone),
+fReadTestMode(kFALSE),
+fOutputRedirected(kFALSE)
 {
        //
        // config: AliShuttleConfig used
@@ -216,7 +431,9 @@ fLastAction()
 //______________________________________________________________________________________________
 AliShuttle::~AliShuttle()
 {
-// destructor
+       //
+       // destructor
+       //
 
        fPreprocessorMap.DeleteAll();
        for(int iSys=0;iSys<4;iSys++)
@@ -260,56 +477,59 @@ void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
        fPreprocessorMap.Add(new TObjString(detName), preprocessor);
 }
 //______________________________________________________________________________________________
-UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
+Bool_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
                AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
 {
-  // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
-  // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
-  // using this function. Use StoreReferenceData instead!
-  // It calls WriteToCDB function which perform actual storage
-
-       return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
-                               metaData, validityStart, validityInfinite);
+       // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
+       // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
+       // using this function. Use StoreReferenceData instead!
+       // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
+       // finishes the data are transferred to the main storage (Grid).
 
+       return StoreLocally(fgkLocalCDB, path, object, metaData, validityStart, validityInfinite);
 }
 
 //______________________________________________________________________________________________
-UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
+Bool_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
 {
-  // Stores a CDB object in the storage for reference data. This objects will not be available during
-  // offline reconstrunction. Use this function for reference data only!
-  // It calls WriteToCDB function which perform actual storage
-
-       return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object, metaData);
+       // Stores a CDB object in the storage for reference data. This objects will not be available during
+       // offline reconstrunction. Use this function for reference data only!
+       // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
+       // finishes the data are transferred to the main storage (Grid).
 
+       return StoreLocally(fgkLocalRefStorage, path, object, metaData);
 }
 
 //______________________________________________________________________________________________
-UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
+Bool_t AliShuttle::StoreLocally(const TString& localUri,
                        const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
                        Int_t validityStart, Bool_t validityInfinite)
 {
-  // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
-  // The parameters are:
-  //   1) Uri of the main storage (Grid)
-  //   2) Uri of the backup storage (Local)
-  //   3) the object's path.
-  //   4) the object to be stored
-  //   5) the metaData to be associated with the object
-  //   6) the validity start run number w.r.t. the current run,
-  //      if the data is valid only for this run leave the default 0
-  //   7) specifies if the calibration data is valid for infinity (this means until updated),
-  //      typical for calibration runs, the default is kFALSE
-  //
-  // returns 0 if fail
-  //        1 if stored in main (Grid) storage
-  //        2 if stored in backup (Local) storage
-
-       const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
+       // Store object temporarily in local storage. Parameters are passed by Store and StoreReferenceData functions.
+       // when the preprocessor finishes the data are transferred to the main storage (Grid).
+       // The parameters are:
+       //   1) Uri of the backup storage (Local)
+       //   2) the object's path.
+       //   3) the object to be stored
+       //   4) the metaData to be associated with the object
+       //   5) the validity start run number w.r.t. the current run,
+       //      if the data is valid only for this run leave the default 0
+       //   6) specifies if the calibration data is valid for infinity (this means until updated),
+       //      typical for calibration runs, the default is kFALSE
+       //
+       // returns 0 if fail, 1 otherwise
+
+       if (fTestMode & kErrorStorage)
+       {
+               Log(fCurrentDetector, "StoreLocally - In TESTMODE - Simulating error while storing locally");
+               return kFALSE;
+       }
+       
+       const char* cdbType = (localUri == fgkLocalCDB) ? "CDB" : "Reference";
 
        Int_t firstRun = GetCurrentRun() - validityStart;
        if(firstRun < 0) {
-               AliError("First valid run happens to be less than 0! Setting it to 0.");
+               AliWarning("First valid run happens to be less than 0! Setting it to 0.");
                firstRun=0;
        }
 
@@ -320,1209 +540,1814 @@ UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
                lastRun = GetCurrentRun();
        }
 
-       AliCDBId id(path, firstRun, lastRun, -1, -1);
+       // Version is set to current run, it will be used later to transfer data to Grid
+       AliCDBId id(path, firstRun, lastRun, GetCurrentRun(), -1);
 
        if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
                TObjString runUsed = Form("%d", GetCurrentRun());
                metaData->SetProperty("RunUsed(TObjString)", runUsed.Clone());
        }
 
-       UInt_t result = 0;
+       Bool_t result = kFALSE;
 
-       if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
-               AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
+       if (!(AliCDBManager::Instance()->GetStorage(localUri))) {
+               Log("SHUTTLE", Form("StoreLocally - Cannot activate local %s storage", cdbType));
        } else {
-               result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
+               result = AliCDBManager::Instance()->GetStorage(localUri)
                                        ->Put(object, id, metaData);
        }
 
        if(!result) {
 
-               Log(fCurrentDetector,
-                       Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
-                               cdbType, path.GetPath().Data()));
-
-               // Set Grid version to current run number, to ease retrieval later
-               id.SetVersion(GetCurrentRun());
-
-               result = AliCDBManager::Instance()->GetStorage(localUri)
-                                       ->Put(object, id, metaData);
-
-               if(result) {
-                       result = 2;
-                       fGridError = kTRUE;
-               }else{
-                       Log(fCurrentDetector, "WriteToCDB - Can't store data!");
-               }
+               Log(fCurrentDetector, Form("StoreLocally - Can't store object <%s>!", id.ToString().Data()));
        }
 
        return result;
-
 }
 
 //______________________________________________________________________________________________
-AliShuttleStatus* AliShuttle::ReadShuttleStatus()
+Bool_t AliShuttle::StoreOCDB()
 {
-// Reads the AliShuttleStatus from the CDB
+       //
+       // Called when preprocessor ends successfully or when previous storage attempt failed (kStoreError status)
+       // Calls underlying StoreOCDB(const char*) function twice, for OCDB and Reference storage.
+       // Then calls StoreRefFilesToGrid to store reference files. 
+       //
+       
+       if (fTestMode & kErrorGrid)
+       {
+               Log("SHUTTLE", "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
+               Log(fCurrentDetector, "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
+               return kFALSE;
+       }
+       
+       Log("SHUTTLE","StoreOCDB - Storing OCDB data ...");
+       Bool_t resultCDB = StoreOCDB(fgkMainCDB);
 
-       if (fStatusEntry){
-               delete fStatusEntry;
-               fStatusEntry = 0;
+       Log("SHUTTLE","StoreOCDB - Storing reference data ...");
+       Bool_t resultRef = StoreOCDB(fgkMainRefStorage);
+       
+       Log("SHUTTLE","StoreOCDB - Storing reference files ...");
+       Bool_t resultRefFiles = CopyFilesToGrid("reference");
+       
+       Bool_t resultMetadata = kTRUE;
+       if(fCurrentDetector == "GRP") 
+       {
+               Log("StoreOCDB - SHUTTLE","Storing Run Metadata file ...");
+               resultMetadata = CopyFilesToGrid("metadata");
        }
+       
+       return resultCDB && resultRef && resultRefFiles && resultMetadata;
+}
 
-       fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
-               ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
+//______________________________________________________________________________________________
+Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
+{
+       //
+       // Called by StoreOCDB(), performs actual storage to the main OCDB and reference storages (Grid)
+       //
 
-       if (!fStatusEntry) return 0;
-       fStatusEntry->SetOwner(1);
+       TObjArray* gridIds=0;
 
-       AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
-       if (!status) {
-               AliError("Invalid object stored to CDB!");
-               return 0;
+       Bool_t result = kTRUE;
+
+       const char* type = 0;
+       TString localURI;
+       if(gridURI == fgkMainCDB) {
+               type = "OCDB";
+               localURI = fgkLocalCDB;
+       } else if(gridURI == fgkMainRefStorage) {
+               type = "reference";
+               localURI = fgkLocalRefStorage;
+       } else {
+               AliError(Form("Invalid storage URI: %s", gridURI.Data()));
+               return kFALSE;
        }
 
-       return status;
-}
+       AliCDBManager* man = AliCDBManager::Instance();
 
-//______________________________________________________________________________________________
-Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
-{
-// writes the status for one subdetector
+       AliCDBStorage *gridSto = man->GetStorage(gridURI);
+       if(!gridSto) {
+               Log("SHUTTLE",
+                       Form("StoreOCDB - cannot activate main %s storage", type));
+               return kFALSE;
+       }
 
-       if (fStatusEntry){
-               delete fStatusEntry;
-               fStatusEntry = 0;
+       gridIds = gridSto->GetQueryCDBList();
+
+       // get objects previously stored in local CDB
+       AliCDBStorage *localSto = man->GetStorage(localURI);
+       if(!localSto) {
+               Log("SHUTTLE",
+                       Form("StoreOCDB - cannot activate local %s storage", type));
+               return kFALSE;
        }
+       AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
+       // Local objects were stored with current run as Grid version!
+       TList* localEntries = localSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
+       localEntries->SetOwner(1);
 
-       Int_t run = GetCurrentRun();
+       // loop on local stored objects
+       TIter localIter(localEntries);
+       AliCDBEntry *aLocEntry = 0;
+       while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
+               aLocEntry->SetOwner(1);
+               AliCDBId aLocId = aLocEntry->GetId();
+               aLocEntry->SetVersion(-1);
+               aLocEntry->SetSubVersion(-1);
 
-       AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
+               // If local object is valid up to infinity we store it only if it is
+               // the first unprocessed run!
+               if (aLocId.GetLastRun() == AliCDBRunRange::Infinity() &&
+                       !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
+               {
+                       Log("SHUTTLE", Form("StoreOCDB - %s: object %s has validity infinite but "
+                                               "there are previous unprocessed runs!",
+                                               fCurrentDetector.Data(), aLocId.GetPath().Data()));
+                       result = kFALSE;
+                       continue;
+               }
 
-       fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
-       fStatusEntry->SetOwner(1);
+               // loop on Grid valid Id's
+               Bool_t store = kTRUE;
+               TIter gridIter(gridIds);
+               AliCDBId* aGridId = 0;
+               while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
+                       if(aGridId->GetPath() != aLocId.GetPath()) continue;
+                       // skip all objects valid up to infinity
+                       if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
+                       // if we get here, it means there's already some more recent object stored on Grid!
+                       store = kFALSE;
+                       break;
+               }
 
-       UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
+               // If we get here, the file can be stored!
+               Bool_t storeOk = gridSto->Put(aLocEntry);
+               if(!store || storeOk){
 
-       if (!result) {
-               AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
-               return kFALSE;
+                       if (!store)
+                       {
+                               Log(fCurrentDetector.Data(),
+                                       Form("StoreOCDB - A more recent object already exists in %s storage: <%s>",
+                                               type, aGridId->ToString().Data()));
+                       } else {
+                               Log("SHUTTLE",
+                                       Form("StoreOCDB - Object <%s> successfully put into %s storage",
+                                               aLocId.ToString().Data(), type));
+                               Log(fCurrentDetector.Data(),
+                                       Form("StoreOCDB - Object <%s> successfully put into %s storage",
+                                               aLocId.ToString().Data(), type));
+                       }
+
+                       // removing local filename...
+                       TString filename;
+                       localSto->IdToFilename(aLocId, filename);
+                       Log("SHUTTLE", Form("StoreOCDB - Removing local file %s", filename.Data()));
+                       RemoveFile(filename.Data());
+                       continue;
+               } else  {
+                       Log("SHUTTLE",
+                               Form("StoreOCDB - Grid %s storage of object <%s> failed",
+                                       type, aLocId.ToString().Data()));
+                       Log(fCurrentDetector.Data(),
+                               Form("StoreOCDB - Grid %s storage of object <%s> failed",
+                                       type, aLocId.ToString().Data()));
+                       result = kFALSE;
+               }
        }
+       localEntries->Clear();
 
-       return kTRUE;
+       return result;
 }
 
 //______________________________________________________________________________________________
-void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
+Bool_t AliShuttle::CleanReferenceStorage(const char* detector)
 {
-  // changes the AliShuttleStatus for the given detector and run to the given status
+       // clears the directory used to store reference files of a given subdetector
+  
+       AliCDBManager* man = AliCDBManager::Instance();
+       AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
+       TString localBaseFolder = sto->GetBaseFolder();
 
-       if (!fStatusEntry){
-               AliError("UNEXPECTED: fStatusEntry empty");
-               return;
-       }
+       TString targetDir = GetRefFilePrefix(localBaseFolder.Data(), detector);
+       
+       Log("SHUTTLE", Form("CleanReferenceStorage - Cleaning %s", targetDir.Data()));
 
-       AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
+       TString begin;
+       begin.Form("%d_", GetCurrentRun());
+       
+       TSystemDirectory* baseDir = new TSystemDirectory("/", targetDir);
+       if (!baseDir)
+               return kTRUE;
+               
+       TList* dirList = baseDir->GetListOfFiles();
+       delete baseDir;
+       
+       if (!dirList) return kTRUE;
+                       
+       if (dirList->GetEntries() < 3) 
+       {
+               delete dirList;
+               return kTRUE;
+       }
+                               
+       Int_t nDirs = 0, nDel = 0;
+       TIter dirIter(dirList);
+       TSystemFile* entry = 0;
 
-       if (!status){
-               AliError("UNEXPECTED: status could not be read from current CDB entry");
-               return;
+       Bool_t success = kTRUE;
+       
+       while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
+       {                                       
+               if (entry->IsDirectory())
+                       continue;
+               
+               TString fileName(entry->GetName());
+               if (!fileName.BeginsWith(begin))
+                       continue;
+                       
+               nDirs++;
+                                               
+               // delete file
+               Int_t result = gSystem->Unlink(fileName.Data());
+               
+               if (result)
+               {
+                       Log("SHUTTLE", Form("CleanReferenceStorage - Could not delete file %s!", fileName.Data()));
+                       success = kFALSE;
+               } else {
+                       nDel++;
+               }
        }
 
-       TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
-                               fCurrentDetector.Data(),
-                               status->GetStatusName(), 
-                               status->GetStatusName(newStatus));
-       Log("SHUTTLE", actionStr);
-       SetLastAction(actionStr);
+       if(nDirs > 0)
+               Log("SHUTTLE", Form("CleanReferenceStorage - %d (over %d) reference files in folder %s were deleted.", 
+                       nDel, nDirs, targetDir.Data()));
 
-       status->SetStatus(newStatus);
-       if (increaseCount) status->IncreaseCount();
+               
+       delete dirList;
+       return success;
 
-       AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
-}
-//______________________________________________________________________________________________
-Bool_t AliShuttle::ContinueProcessing()
-{
-// this function reads the AliShuttleStatus information from CDB and
-// checks if the processing should be continued
-// if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
 
-       if (!fConfig->HostProcessDetector(fCurrentDetector)) return kFALSE;
 
-       AliPreprocessor* aPreprocessor =
-               dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
-       if (!aPreprocessor)
-       {
-               AliInfo(Form("%s: no preprocessor registered", fCurrentDetector.Data()));
-               return kFALSE;
-       }
 
-       AliShuttleLogbookEntry::Status entryStatus =
-               fLogbookEntry->GetDetectorStatus(fCurrentDetector);
 
-       if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
-               AliInfo(Form("ContinueProcessing - %s is %s",
-                               fCurrentDetector.Data(),
-                               fLogbookEntry->GetDetectorStatusName(entryStatus)));
-               return kFALSE;
-       }
 
-       // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
+  Int_t result = gSystem->GetPathInfo(targetDir, 0, (Long64_t*) 0, 0, 0);
+  if (result == 0)
+  {
+    // delete directory
+    result = gSystem->Exec(Form("rm -rf %s", targetDir.Data()));
+    if (result != 0)
+    {  
+      Log("SHUTTLE", Form("CleanReferenceStorage - Could not clean directory %s", targetDir.Data()));
+      return kFALSE;
+    }
+  }
 
-       // check if current run is first unprocessed run for current detector
-       if (fConfig->StrictRunOrder(fCurrentDetector) &&
-               !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
-       {
-               Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering but this is not the first unprocessed run!"));
-               return kFALSE;
-       }
+  result = gSystem->mkdir(targetDir, kTRUE);
+  if (result != 0)
+  {
+    Log("SHUTTLE", Form("CleanReferenceStorage - Error creating base directory %s", targetDir.Data()));
+    return kFALSE;
+  }
+       
+  return kTRUE;
+}
 
-       AliShuttleStatus* status = ReadShuttleStatus();
-       if (!status) {
-               // first time
-               Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
-                               fCurrentDetector.Data()));
-               status = new AliShuttleStatus(AliShuttleStatus::kStarted);
-               return WriteShuttleStatus(status);
-       }
-
-       // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
-       // If it happens it may mean Logbook updating failed... let's do it now!
-       if (status->GetStatus() == AliShuttleStatus::kDone ||
-           status->GetStatus() == AliShuttleStatus::kFailed){
-               Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
-                                       fCurrentDetector.Data(),
-                                       status->GetStatusName(status->GetStatus())));
-               UpdateShuttleLogbook(fCurrentDetector.Data(),
-                                       status->GetStatusName(status->GetStatus()));
+//______________________________________________________________________________________________
+Bool_t AliShuttle::StoreReferenceFile(const char* detector, const char* localFile, const char* gridFileName)
+{
+       //
+       // Stores reference file directly (without opening it). This function stores the file locally.
+       //
+       // The file is stored under the following location: 
+       // <base folder of local reference storage>/<DET>/<RUN#>_<gridFileName>
+       // where <gridFileName> is the second parameter given to the function
+       // 
+       
+       if (fTestMode & kErrorStorage)
+       {
+               Log(fCurrentDetector, "StoreReferenceFile - In TESTMODE - Simulating error while storing locally");
                return kFALSE;
        }
+       
+       AliCDBManager* man = AliCDBManager::Instance();
+       AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
+       
+       TString localBaseFolder = sto->GetBaseFolder();
+       
+       TString target = GetRefFilePrefix(localBaseFolder.Data(), detector);    
+       target.Append(Form("/%d_%s", GetCurrentRun(), gridFileName));
+       
+       return CopyFileLocally(localFile, target);
+}
 
-       if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
-               Log("SHUTTLE",
-                       Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
-                               fCurrentDetector.Data()));
-               if(TryToStoreAgain()){
-                       Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
-                       UpdateShuttleStatus(AliShuttleStatus::kDone);
-                       UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
-               } else {
-                       Log("SHUTTLE",
-                               Form("ContinueProcessing - %s: Grid storage failed again",
-                                       fCurrentDetector.Data()));
-               }
+//______________________________________________________________________________________________
+Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridFileName)
+{
+       //
+       // Stores Run metadata file to the Grid, in the run folder
+       //
+       // Only GRP can call this function.
+       
+       if (fTestMode & kErrorStorage)
+       {
+               Log(fCurrentDetector, "StoreRunMetaDataFile - In TESTMODE - Simulating error while storing locally");
                return kFALSE;
        }
-
-       // if we get here, there is a restart
-       Bool_t cont = kFALSE;
-
-       // abort conditions
-       if (status->GetCount() >= fConfig->GetMaxRetries()) {
-               Log("SHUTTLE", Form("ContinueProcessing - %s failed %d times in status %s - "
-                               "Updating Shuttle Logbook", fCurrentDetector.Data(),
-                               status->GetCount(), status->GetStatusName()));
-               UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
-       } else {
-               Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. "
-                               "Aborted before with %s. Retry number %d.", fCurrentDetector.Data(),
-                               status->GetStatusName(), status->GetCount()));
-               UpdateShuttleStatus(AliShuttleStatus::kStarted, kTRUE);
-               cont = kTRUE;
+       
+       AliCDBManager* man = AliCDBManager::Instance();
+       AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
+       
+       TString localBaseFolder = sto->GetBaseFolder();
+       
+       // Build Run level folder
+       // folder = /alice/data/year/lhcPeriod/runNb/raw
+       
+               
+       TString lhcPeriod = GetLHCPeriod();     
+       if (lhcPeriod.Length() == 0) 
+       {
+               Log("SHUTTLE","StoreRunMetaDataFile - LHCPeriod not found in logbook!");
+               return 0;
        }
-
-       // Send mail to detector expert!
-       AliInfo(Form("Sending mail to %s expert...", fCurrentDetector.Data()));
-       if (!SendMail())
-               Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert",
-                               fCurrentDetector.Data()));
-
-       return cont;
+       
+       TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s", 
+                               localBaseFolder.Data(), GetCurrentYear(), 
+                               lhcPeriod.Data(), GetCurrentRun(), gridFileName);
+                                       
+       return CopyFileLocally(localFile, target);
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
+Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
 {
        //
-       // Makes data retrieval for all detectors in the configuration.
-       // entry: Shuttle logbook entry, contains run paramenters and status of detectors
-       // (Unprocessed, Inactive, Failed or Done).
-       // Returns kFALSE in case of error occured and kTRUE otherwise
+       // Stores file locally. Called by StoreReferenceFile and StoreRunMetadataFile
+       // Files are temporarily stored in the local reference storage. When the preprocessor 
+       // finishes, the Shuttle calls CopyFilesToGrid to transfer the files to AliEn 
+       // (in reference or run level folders)
        //
+       
+       TString targetDir(target(0, target.Last('/')));
+       
+       //try to open base dir folder, if it does not exist
+       void* dir = gSystem->OpenDirectory(targetDir.Data());
+       if (dir == NULL) {
+               if (gSystem->mkdir(targetDir.Data(), kTRUE)) {
+                       Log("SHUTTLE", Form("StoreFileLocally - Can't open directory <%s>", targetDir.Data()));
+                       return kFALSE;
+               }
 
-       if(!entry) return kFALSE;
+       } else {
+               gSystem->FreeDirectory(dir);
+       }
+       
+       Int_t result = 0;
+       
+       result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0);
+       if (result)
+       {
+               Log("SHUTTLE", Form("StoreFileLocally - %s does not exist", localFile));
+               return kFALSE;
+       }
 
-       fLogbookEntry = entry;
+       result = gSystem->GetPathInfo(target, 0, (Long64_t*) 0, 0, 0);
+       if (!result)
+       {
+               Log("SHUTTLE", Form("StoreFileLocally - target file %s already exist, removing...", target.Data()));
+               if (gSystem->Unlink(target.Data()))
+               {
+                       Log("SHUTTLE", Form("StoreFileLocally - Could not remove existing target file %s!", target.Data()));
+                       return kFALSE;
+               }
+       }       
+       
+       result = gSystem->CopyFile(localFile, target);
 
-       if(fLogbookEntry->IsDone()){
-               Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
-               UpdateShuttleLogbook("shuttle_done");
-               fLogbookEntry = 0;
+       if (result == 0)
+       {
+               Log("SHUTTLE", Form("StoreFileLocally - File %s stored locally to %s", localFile, target.Data()));
                return kTRUE;
        }
-
-
-       AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
-                                       GetCurrentRun()));
-
-       fLogbookEntry->Print("all");
-
-       // Initialization
-       Bool_t hasError = kFALSE;
-       for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
-
-       AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
-       if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
-       AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
-       if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
-
-       // Loop on detectors in the configuration
-       TIter iter(fConfig->GetDetectors());
-       TObjString* aDetector = 0;
-
-       while ((aDetector = (TObjString*) iter.Next()))
+       else
        {
-               fCurrentDetector = aDetector->String();
-
-               if (ContinueProcessing() == kFALSE) continue;
+               Log("SHUTTLE", Form("StoreFileLocally - Could not store file %s to %s! Error code = %d", 
+                               localFile, target.Data(), result));
+               return kFALSE;
+       }       
 
-               AliInfo(Form("\n\n \t\t\t****** run %d - %s: START  ******",
-                                               GetCurrentRun(), aDetector->GetName()));
 
 
-               Int_t pid = fork();
+}
 
-               if (pid < 0)
+//______________________________________________________________________________________________
+Bool_t AliShuttle::CopyFilesToGrid(const char* type)
+{
+       //
+       // Transfers local files to the Grid. Local files can be reference files 
+       // or run metadata file (from GRP only).
+       //
+       // According to the type (ref, metadata) the files are stored under the following location: 
+       // ref --> <base folder of reference storage>/<DET>/<RUN#>_<gridFileName>
+       // metadata --> <run data folder>/<MetadataFileName>
+       //
+               
+       AliCDBManager* man = AliCDBManager::Instance();
+       AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
+       if (!sto)
+               return kFALSE;
+       TString localBaseFolder = sto->GetBaseFolder();
+       
+       TString dir;
+       TString alienDir;
+       TString begin;
+       
+       if (strcmp(type, "reference") == 0) 
+       {
+               dir = GetRefFilePrefix(localBaseFolder.Data(), fCurrentDetector.Data());
+               AliCDBStorage* gridSto = man->GetStorage(fgkMainRefStorage);
+               if (!gridSto)
+                       return kFALSE;
+               TString gridBaseFolder = gridSto->GetBaseFolder();
+               alienDir = GetRefFilePrefix(gridBaseFolder.Data(), fCurrentDetector.Data());
+               begin = Form("%d_", GetCurrentRun());
+       } 
+       else if (strcmp(type, "metadata") == 0)
+       {
+                       
+               TString lhcPeriod = GetLHCPeriod();
+       
+               if (lhcPeriod.Length() == 0) 
                {
-                       Log("SHUTTLE", "ERROR: Forking failed");
+                       Log("SHUTTLE","CopyFilesToGrid - LHCPeriod not found in logbook!");
+                       return 0;
                }
-               else if (pid > 0)
-               {
-                       // parent
-                       AliInfo(Form("In parent process of %d - %s: Starting monitoring",
-                                                       GetCurrentRun(), aDetector->GetName()));
-
-                       Long_t begin = time(0);
-
-                       int status; // to be used with waitpid, on purpose an int (not Int_t)!
-                       while (waitpid(pid, &status, WNOHANG) == 0)
-                       {
-                               Long_t expiredTime = time(0) - begin;
-
-                               if (expiredTime > fConfig->GetPPTimeOut())
-                               {
-                                       Log("SHUTTLE", Form("Process time out. Run time: %d seconds. Killing...",
-                                                               expiredTime));
-
-                                       kill(pid, 9);
-
-                                       hasError = kTRUE;
-
-                                       gSystem->Sleep(1000);
-                               }
-                               else
-                               {
-                                       if (expiredTime % 60 == 0)
-                                       Log("SHUTTLE", Form("Checked process. Run time: %d seconds.",
-                                                               expiredTime));
-                                       gSystem->Sleep(1000);
-                               }
-                       }
-
-                       AliInfo(Form("In parent process of %d - %s: Client has terminated.",
-                                                               GetCurrentRun(), aDetector->GetName()));
-
-                       if (WIFEXITED(status))
-                       {
-                               Int_t returnCode = WEXITSTATUS(status);
-
-                               Log("SHUTTLE", Form("The return code is %d", returnCode));
+               
+               dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw", 
+                               localBaseFolder.Data(), GetCurrentYear(), 
+                               lhcPeriod.Data(), GetCurrentRun());
+               alienDir = dir(dir.Index("/alice/data/"), dir.Length());
+               
+               begin = "";
+       }
+       else 
+       {
+               Log("SHUTTLE", "CopyFilesToGrid - Unexpected: type label must be reference or metadata!");
+               return kFALSE;
+       }
+               
+       TSystemDirectory* baseDir = new TSystemDirectory("/", dir);
+       if (!baseDir)
+               return kTRUE;
+               
+       TList* dirList = baseDir->GetListOfFiles();
+       delete baseDir;
+       
+       if (!dirList) return kTRUE;
+               
+       if (dirList->GetEntries() < 3) 
+       {
+               delete dirList;
+               return kTRUE;
+       }
+                       
+       if (!gGrid)
+       { 
+               Log("SHUTTLE", "CopyFilesToGrid - Connection to Grid failed: Cannot continue!");
+               delete dirList;
+               return kFALSE;
+       }
+       
+       Int_t nDirs = 0, nTransfer = 0;
+       TIter dirIter(dirList);
+       TSystemFile* entry = 0;
 
-                               if (returnCode != 0)
-                               hasError = kTRUE;
-                       }
-               }
-               else if (pid == 0)
+       Bool_t success = kTRUE;
+       Bool_t first = kTRUE;
+       
+       while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
+       {                       
+               if (entry->IsDirectory())
+                       continue;
+                       
+               TString fileName(entry->GetName());
+               if (!fileName.BeginsWith(begin))
+                       continue;
+                       
+               nDirs++;
+                       
+               if (first)
                {
-                       // client
-                       AliInfo(Form("In client process of %d - %s", GetCurrentRun(), aDetector->GetName()));
-
-                       UInt_t result = ProcessCurrentDetector();
-
-                       Int_t returnCode = 0; // will be set to 1 in case of an error
-
+                       first = kFALSE;
+                       // check that folder exists, otherwise create it
+                       TGridResult* result = gGrid->Ls(alienDir.Data(), "a");
+                       
                        if (!result)
                        {
-                               returnCode = 1;
-                               AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
-                                                       GetCurrentRun(), aDetector->GetName()));
-                       }
-                       else if (result == 2)
-                       {
-                               AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
-                                                       GetCurrentRun(), aDetector->GetName()));
-                       } else
-                       {
-                               AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
-                                                       GetCurrentRun(), aDetector->GetName()));
+                               delete dirList;
+                               return kFALSE;
                        }
-
-                       if (result > 0)
+                       
+                       if (!result->GetFileName(1)) // TODO: It looks like element 0 is always 0!!
                        {
-                               // Process successful: Update time_processed field in FXS logbooks!
-                               if (fFXSCalled[kDAQ])
-                               {
-                                       if (UpdateDAQTable() == kFALSE)
-                                       returnCode = 1;
-                                       fFXSlist[kDAQ].Clear();
-                               }
-                               //if(fFXSCalled[kDCS]) {
-                               //  if (UpdateDCSTable(aDetector->GetName()) == kFALSE)
-                               //    returnCode = 1;
-                               //  fFXSlist[kDCS].Clear();
-                               //}
-                               if (fFXSCalled[kHLT])
+                               // TODO It does not work currently! Bug in TAliEn::Mkdir
+                               // TODO Manually fixed in local root v5-16-00
+                               if (!gGrid->Mkdir(alienDir.Data(),"-p",0))
                                {
-                                       if (UpdateHLTTable() == kFALSE)
-                                       returnCode = 1;
-                                       fFXSlist[kHLT].Clear();
+                                       Log("SHUTTLE", Form("CopyFilesToGrid - Cannot create directory %s",
+                                                       alienDir.Data()));
+                                       delete dirList;
+                                       return kFALSE;
+                               } else {
+                                       Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s created", alienDir.Data()));
                                }
+                               
+                       } else {
+                                       Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s found", alienDir.Data()));
                        }
-
-                       AliInfo(Form("Client process of %d - %s is exiting now with %d.",
-                                                       GetCurrentRun(), aDetector->GetName(), returnCode));
-
-                       // the client exits here
-                       gSystem->Exit(returnCode);
-
-                       AliError("We should never get here!!!");
                }
-       }
-
-       AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
-                                                       GetCurrentRun()));
-
-       //check if shuttle is done for this run, if so update logbook
-       TObjArray checkEntryArray;
-       checkEntryArray.SetOwner(1);
-       TString whereClause = Form("where run=%d", GetCurrentRun());
-       if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) || checkEntryArray.GetEntries() == 0) {
-               Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!",
-                                               GetCurrentRun()));
-               return hasError == kFALSE;
-       }
-
-       AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
-                                               (checkEntryArray.At(0));
-
-       if (checkEntry)
-       {
-               if (checkEntry->IsDone())
+                       
+               TString fullLocalPath;
+               fullLocalPath.Form("%s/%s", dir.Data(), fileName.Data());
+               
+               TString fullGridPath;
+               fullGridPath.Form("alien://%s/%s", alienDir.Data(), fileName.Data());
+
+               Bool_t result = TFile::Cp(fullLocalPath, fullGridPath);
+               
+               if (result)
                {
-                       Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
-                       UpdateShuttleLogbook("shuttle_done");
+                       Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s succeeded!", 
+                                               fullLocalPath.Data(), fullGridPath.Data()));
+                       RemoveFile(fullLocalPath);
+                       nTransfer++;
                }
                else
                {
-                       for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
-                       {
-                               if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
-                               {
-                                       AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
-                                                       checkEntry->GetRun(), GetDetName(iDet)));
-                                       fFirstUnprocessed[iDet] = kFALSE;
-                               }
-                       }
+                       Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s FAILED!", 
+                                               fullLocalPath.Data(), fullGridPath.Data()));
+                       success = kFALSE;
                }
        }
 
-       fLogbookEntry = 0;
+       Log("SHUTTLE", Form("CopyFilesToGrid - %d (over %d) files in folder %s copied to Grid.", 
+                                               nTransfer, nDirs, dir.Data()));
 
-       return hasError == kFALSE;
+               
+       delete dirList;
+       return success;
 }
 
 //______________________________________________________________________________________________
-UInt_t AliShuttle::ProcessCurrentDetector()
+const char* AliShuttle::GetRefFilePrefix(const char* base, const char* detector)
 {
        //
-        // Makes data retrieval just for a specific detector (fCurrentDetector).
-       // Threre should be a configuration for this detector.
-
-       AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
-
-       UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
-
-       TMap dcsMap;
-       dcsMap.SetOwner(1);
-
-       Bool_t aDCSError = kFALSE;
-       fGridError = kFALSE;
+       // Get folder name of reference files 
+       //
 
-       // TODO Test only... I've added a flag that allows to
-       // exclude DCS archive DB query
-       if (!fgkProcessDCS)
+       TString offDetStr(GetOfflineDetName(detector));
+       TString dir;
+       if (offDetStr == "ITS" || offDetStr == "MUON" || offDetStr == "PHOS")
        {
-               AliInfo("Skipping DCS processing!");
-               aDCSError = kFALSE;
+               dir.Form("%s/%s/%s", base, offDetStr.Data(), detector);
        } else {
-               TString host(fConfig->GetDCSHost(fCurrentDetector));
-               Int_t port = fConfig->GetDCSPort(fCurrentDetector);
+               dir.Form("%s/%s", base, offDetStr.Data());
+       }
+       
+       return dir.Data();
+       
 
-               // Retrieval of Aliases
-               TObjString* anAlias = 0;
-               TIter iterAliases(fConfig->GetDCSAliases(fCurrentDetector));
-               while ((anAlias = (TObjString*) iterAliases.Next()))
-               {
-                       TObjArray *valueSet = new TObjArray();
-                       valueSet->SetOwner(1);
+}
 
-                       AliInfo("Querying DCS archive DB (Aliases)...");
-                       aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet, kAlias) == 0);
+//______________________________________________________________________________________________
+void AliShuttle::CleanLocalStorage(const TString& uri)
+{
+       //
+       // Called in case the preprocessor is declared failed. Remove remaining objects from the local storages.
+       //
 
-                       if(!aDCSError)
-                       {
-                               dcsMap.Add(anAlias->Clone(), valueSet);
-                       } else {
-                               Log(fCurrentDetector,
-                                       Form("ProcessCurrentDetector - Error while retrieving alias %s",
-                                               anAlias->GetName()));
-                               UpdateShuttleStatus(AliShuttleStatus::kDCSError);
-                               dcsMap.DeleteAll();
-                               return 0;
-                       }
-               }
+       const char* type = 0;
+       if(uri == fgkLocalCDB) {
+               type = "OCDB";
+       } else if(uri == fgkLocalRefStorage) {
+               type = "Reference";
+       } else {
+               AliError(Form("Invalid storage URI: %s", uri.Data()));
+               return;
+       }
 
-               // Retrieval of Data Points
-               TObjString* aDP = 0;
-               TIter iterDP(fConfig->GetDCSDataPoints(fCurrentDetector));
-               while ((aDP = (TObjString*) iterDP.Next()))
-               {
-                       TObjArray *valueSet = new TObjArray();
-                       valueSet->SetOwner(1);
-                       AliInfo("Querying DCS archive DB (Data Points)...");
-                       aDCSError = (GetValueSet(host, port, aDP->String(), valueSet, kDP) == 0);
+       AliCDBManager* man = AliCDBManager::Instance();
 
-                       if(!aDCSError)
-                       {
-                               dcsMap.Add(aDP->Clone(), valueSet);
-                       } else {
-                               Log(fCurrentDetector,
-                                       Form("ProcessCurrentDetector - Error while retrieving data point %s",
-                                               aDP->GetName()));
-                               UpdateShuttleStatus(AliShuttleStatus::kDCSError);
-                               dcsMap.DeleteAll();
-                               return 0;
-                       }
-               }
+       // open local storage
+       AliCDBStorage *localSto = man->GetStorage(uri);
+       if(!localSto) {
+               Log("SHUTTLE",
+                       Form("CleanLocalStorage - cannot activate local %s storage", type));
+               return;
        }
 
-       // DCS Archive DB processing successful. Call Preprocessor!
-       UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
-
-       AliPreprocessor* aPreprocessor =
-               dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
+       TString filename(Form("%s/%s/*/Run*_v%d_s*.root",
+               localSto->GetBaseFolder().Data(), GetOfflineDetName(fCurrentDetector.Data()), GetCurrentRun()));
 
-       aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
-       UInt_t aPPResult = aPreprocessor->Process(&dcsMap);
+       AliDebug(2, Form("filename = %s", filename.Data()));
 
-       UInt_t returnValue = 0;
-       if (aPPResult == 0) { // Preprocessor error
-               UpdateShuttleStatus(AliShuttleStatus::kPPError);
-               returnValue = 0;
-       } else if (fGridError == kFALSE) { // process and Grid storage ok!
-               UpdateShuttleStatus(AliShuttleStatus::kDone);
-               UpdateShuttleLogbook(fCurrentDetector, "DONE");
-               Log(fCurrentDetector.Data(),
-                       "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
-               returnValue = 1;
-        } else { // Grid storage error (process ok, but object put in local storage)
-               UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
-               returnValue = 2;
-       }
+       Log("SHUTTLE", Form("Removing remaining local files for run %d and detector %s ...",
+               GetCurrentRun(), fCurrentDetector.Data()));
 
-       dcsMap.DeleteAll();
+       RemoveFile(filename.Data());
 
-       return returnValue;
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
-               TObjArray& entries)
+void AliShuttle::RemoveFile(const char* filename)
 {
-// Query DAQ's Shuttle logbook and fills detector status object.
-// Call QueryRunParameters to query DAQ logbook for run parameters.
+       //
+       // removes local file
+       //
 
-       entries.SetOwner(1);
+       TString command(Form("rm -f %s", filename));
 
-       // check connection, in case connect
-       if(!Connect(3)) return kFALSE;
+       Int_t result = gSystem->Exec(command.Data());
+       if(result != 0)
+       {
+               Log("SHUTTLE", Form("RemoveFile - %s: Cannot remove file %s!",
+                       fCurrentDetector.Data(), filename));
+       }
+}
 
-       TString sqlQuery;
-       sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
+//______________________________________________________________________________________________
+AliShuttleStatus* AliShuttle::ReadShuttleStatus()
+{
+       //
+       // Reads the AliShuttleStatus from the CDB
+       //
 
-       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
-       if (!aResult) {
-               AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
-               return kFALSE;
+       if (fStatusEntry){
+               delete fStatusEntry;
+               fStatusEntry = 0;
        }
 
-       AliDebug(2,Form("Query = %s", sqlQuery.Data()));
+       fStatusEntry = AliCDBManager::Instance()->GetStorage(GetLocalCDB())
+               ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
 
-       if(aResult->GetRowCount() == 0) {
-//             if(sqlQuery.EndsWith("where shuttle_done=0 order by run")){
-//                     Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
-//                     delete aResult;
-//                     return kTRUE;
-//             } else {
-                       AliInfo("No entries in Shuttle Logbook match request");
-                       delete aResult;
-                       return kTRUE;
-//             }
+       if (!fStatusEntry) return 0;
+       fStatusEntry->SetOwner(1);
+
+       AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
+       if (!status) {
+               AliError("Invalid object stored to CDB!");
+               return 0;
        }
 
-       // TODO Check field count!
-       const UInt_t nCols = 22;
-       if (aResult->GetFieldCount() != (Int_t) nCols) {
-               AliError("Invalid SQL result field number!");
-               delete aResult;
-               return kFALSE;
+       return status;
+}
+
+//______________________________________________________________________________________________
+Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
+{
+       //
+       // writes the status for one subdetector
+       //
+
+       if (fStatusEntry){
+               delete fStatusEntry;
+               fStatusEntry = 0;
        }
 
-       TSQLRow* aRow;
-       while ((aRow = aResult->Next())) {
-               TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
-               Int_t run = runString.Atoi();
+       Int_t run = GetCurrentRun();
 
-               AliShuttleLogbookEntry *entry = QueryRunParameters(run);
-               if (!entry)
-                       continue;
+       AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
 
-               // loop on detectors
-               for(UInt_t ii = 0; ii < nCols; ii++)
-                       entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
+       fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
+       fStatusEntry->SetOwner(1);
 
-               entries.AddLast(entry);
-               delete aRow;
+       UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
+
+       if (!result) {
+               Log("SHUTTLE", Form("WriteShuttleStatus - Failed for %s, run %d",
+                                               fCurrentDetector.Data(), run));
+               return kFALSE;
        }
+       
+       SendMLInfo();
 
-//     if(sqlQuery.EndsWith("where shuttle_done=0 order by run"))
-//             Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
-//                                                     entries.GetEntriesFast()));
-       delete aResult;
        return kTRUE;
 }
 
 //______________________________________________________________________________________________
-AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
+void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
 {
        //
-       // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
+       // changes the AliShuttleStatus for the given detector and run to the given status
        //
 
-       // check connection, in case connect
-       if (!Connect(3))
-               return 0;
-
-       TString sqlQuery;
-       sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
-
-       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
-       if (!aResult) {
-               AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
-               return 0;
-       }
-
-       if (aResult->GetRowCount() == 0) {
-               Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
-               delete aResult;
-               return 0;
+       if (!fStatusEntry){
+               AliError("UNEXPECTED: fStatusEntry empty");
+               return;
        }
 
-       if (aResult->GetRowCount() > 1) {
-               AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
-               delete aResult;
-               return 0;
-       }
+       AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
 
-       TSQLRow* aRow = aResult->Next();
-       if (!aRow)
-       {
-               AliError(Form("Could not retrieve row for run %d. Skipping", run));
-               delete aResult;
-               return 0;
+       if (!status){
+               Log("SHUTTLE", "UpdateShuttleStatus - UNEXPECTED: status could not be read from current CDB entry");
+               return;
        }
 
-       AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
-
-       for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
-               entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
-
-       UInt_t startTime = entry->GetStartTime();
-       UInt_t endTime = entry->GetEndTime();
+       TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
+                               fCurrentDetector.Data(),
+                               status->GetStatusName(),
+                               status->GetStatusName(newStatus));
+       Log("SHUTTLE", actionStr);
+       SetLastAction(actionStr);
 
-       if (!startTime || !endTime || startTime > endTime) {
-               Log("SHUTTLE",
-                       Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
-                               run, startTime, endTime));
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
-       }
+       status->SetStatus(newStatus);
+       if (increaseCount) status->IncreaseCount();
 
-       delete aRow;
-       delete aResult;
+       AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
 
-       return entry;
+       SendMLInfo();
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::TryToStoreAgain()
+void AliShuttle::SendMLInfo()
 {
-  // Called in case the detector failed to store the object in Grid OCDB
-  // It tries to store the object again, if it does not find more recent and overlapping objects
-  // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
-
-       AliInfo("Trying to store OCDB data again...");
-       Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
+       //
+       // sends ML information about the current status of the current detector being processed
+       //
+       
+       AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
+       
+       if (!status){
+               Log("SHUTTLE", "SendMLInfo - UNEXPECTED: status could not be read from current CDB entry");
+               return;
+       }
+       
+       TMonaLisaText  mlStatus(Form("%s_status", fCurrentDetector.Data()), status->GetStatusName());
+       TMonaLisaValue mlRetryCount(Form("%s_count", fCurrentDetector.Data()), status->GetCount());
 
-       AliInfo("Trying to store reference data again...");
-       Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
+       TList mlList;
+       mlList.Add(&mlStatus);
+       mlList.Add(&mlRetryCount);
 
-       return resultCDB && resultRef;
+       TString mlID;
+       mlID.Form("%d", GetCurrentRun());
+       fMonaLisa->SendParameters(&mlList, mlID);
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
+Bool_t AliShuttle::ContinueProcessing()
 {
-  // Called by TryToStoreAgain(), performs actual storage retry
+       // this function reads the AliShuttleStatus information from CDB and
+       // checks if the processing should be continued
+       // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
 
-       TObjArray* gridIds=0;
-
-       Bool_t result = kTRUE;
+       if (!fConfig->HostProcessDetector(fCurrentDetector)) return kFALSE;
 
-       const char* type = 0;
-       TString backupURI;
-       if(gridURI == fgkMainCDB) {
-               type = "OCDB";
-               backupURI = fgkLocalCDB;
-       } else if(gridURI == fgkMainRefStorage) {
-               type = "reference";
-               backupURI = fgkLocalRefStorage;
-       } else {
-               AliError(Form("Invalid storage URI: %s", gridURI.Data()));
+       AliPreprocessor* aPreprocessor =
+               dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
+       if (!aPreprocessor)
+       {
+               Log("SHUTTLE", Form("ContinueProcessing - %s: no preprocessor registered", fCurrentDetector.Data()));
                return kFALSE;
        }
 
-       AliCDBManager* man = AliCDBManager::Instance();
+       AliShuttleLogbookEntry::Status entryStatus =
+               fLogbookEntry->GetDetectorStatus(fCurrentDetector);
 
-       AliCDBStorage *gridSto = man->GetStorage(gridURI);
-       if(!gridSto) {
-               Log(fCurrentDetector.Data(),
-                       Form("TryToStoreAgain - cannot activate main %s storage", type));
+       if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
+               Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
+                               fCurrentDetector.Data(),
+                               fLogbookEntry->GetDetectorStatusName(entryStatus)));
                return kFALSE;
        }
 
-       gridIds = gridSto->GetQueryCDBList();
+       // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
 
-       // get objects previously stored in local CDB
-       AliCDBStorage *backupSto = man->GetStorage(backupURI);
-       AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
-       // Local objects were stored with current run as Grid version!
-       TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
-       localEntries->SetOwner(1);
+       // check if current run is first unprocessed run for current detector
+       if (fConfig->StrictRunOrder(fCurrentDetector) &&
+               !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
+       {
+               if (fTestMode == kNone)
+               {
+                       Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering"
+                                       " but this is not the first unprocessed run!"));
+                       return kFALSE;
+               }
+               else
+               {
+                       Log("SHUTTLE", Form("ContinueProcessing - In TESTMODE - "
+                                       "Although %s requires strict run ordering "
+                                       "and this is not the first unprocessed run, "
+                                       "the SHUTTLE continues"));
+               }
+       }
 
-       // loop on local stored objects
-       TIter localIter(localEntries);
-       AliCDBEntry *aLocEntry = 0;
-       while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
-               aLocEntry->SetOwner(1);
-               AliCDBId aLocId = aLocEntry->GetId();
-               aLocEntry->SetVersion(-1);
-               aLocEntry->SetSubVersion(-1);
+       AliShuttleStatus* status = ReadShuttleStatus();
+       if (!status) {
+               // first time
+               Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
+                               fCurrentDetector.Data()));
+               status = new AliShuttleStatus(AliShuttleStatus::kStarted);
+               return WriteShuttleStatus(status);
+       }
 
-               // loop on Grid valid Id's
-               Bool_t store = kTRUE;
-               TIter gridIter(gridIds);
-               AliCDBId* aGridId = 0;
-               while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
-                       // If local object is valid up to infinity we store it only if it is
-                       // the first unprocessed run!
-                       if (aLocId.GetLastRun() == AliCDBRunRange::Infinity())
-                       {
-                               if (!fFirstUnprocessed[GetDetPos(fCurrentDetector)])
-                               {
-                                       Log(fCurrentDetector.Data(),
-                                               ("TryToStoreAgain - This object has validity infinite but "
-                                                "there are previous unprocessed runs!"));
-                                       continue;
-                               } else {
-                                       break;
-                               }
-                       }
-                       if(aGridId->GetPath() != aLocId.GetPath()) continue;
-                       // skip all objects valid up to infinity
-                       if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
-                       // if we get here, it means there's already some more recent object stored on Grid!
-                       store = kFALSE;
-                       break;
-               }
+       // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
+       // If it happens it may mean Logbook updating failed... let's do it now!
+       if (status->GetStatus() == AliShuttleStatus::kDone ||
+           status->GetStatus() == AliShuttleStatus::kFailed){
+               Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
+                                       fCurrentDetector.Data(),
+                                       status->GetStatusName(status->GetStatus())));
+               UpdateShuttleLogbook(fCurrentDetector.Data(),
+                                       status->GetStatusName(status->GetStatus()));
+               return kFALSE;
+       }
 
-               if(!store){
-                       Log(fCurrentDetector.Data(),
-                               Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
-                                       type, aGridId->ToString().Data()));
-                       // removing local filename...
-                       // TODO maybe it's better not to remove it, it was not copied to the Grid!
-                       TString filename;
-                       backupSto->IdToFilename(aLocId, filename);
-                       AliInfo(Form("Removing local file %s", filename.Data()));
-                       gSystem->Exec(Form("rm %s",filename.Data()));
-                       continue;
+       if (status->GetStatus() == AliShuttleStatus::kStoreError) {
+               Log("SHUTTLE",
+                       Form("ContinueProcessing - %s: Grid storage of one or more "
+                               "objects failed. Trying again now",
+                               fCurrentDetector.Data()));
+               UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
+               if (StoreOCDB()){
+                       Log("SHUTTLE", Form("ContinueProcessing - %s: all objects "
+                               "successfully stored into main storage",
+                               fCurrentDetector.Data()));
+               } else {
+                       Log("SHUTTLE",
+                               Form("ContinueProcessing - %s: Grid storage failed again",
+                                       fCurrentDetector.Data()));
+                       UpdateShuttleStatus(AliShuttleStatus::kStoreError);
                }
+               return kFALSE;
+       }
 
-               // If we get here, the file can be stored!
-               Bool_t storeOk = gridSto->Put(aLocEntry);
-               if(storeOk){
-                       Log(fCurrentDetector.Data(),
-                               Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
-                                       aLocId.ToString().Data(), type));
+       // if we get here, there is a restart
+       Bool_t cont = kFALSE;
 
-                       // removing local filename...
-                       TString filename;
-                       backupSto->IdToFilename(aLocId, filename);
-                       AliInfo(Form("Removing local file %s", filename.Data()));
-                       gSystem->Exec(Form("rm %s", filename.Data()));
-                       continue;
-               } else  {
-                       Log(fCurrentDetector.Data(),
-                               Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
-                                       type, aLocId.ToString().Data()));
-                       result = kFALSE;
-               }
+       // abort conditions
+       if (status->GetCount() >= fConfig->GetMaxRetries()) {
+               Log("SHUTTLE", Form("ContinueProcessing - %s failed %d times in status %s - "
+                               "Updating Shuttle Logbook", fCurrentDetector.Data(),
+                               status->GetCount(), status->GetStatusName()));
+               UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
+               UpdateShuttleStatus(AliShuttleStatus::kFailed);
+
+               // there may still be objects in local OCDB and reference storage
+               // and FXS databases may be not updated: do it now!
+               
+               // TODO Currently disabled, we want to keep files in case of failure!
+               // CleanLocalStorage(fgkLocalCDB);
+               // CleanLocalStorage(fgkLocalRefStorage);
+               // UpdateTableFailCase();
+               
+               // Send mail to detector expert!
+               Log("SHUTTLE", Form("ContinueProcessing - Sending mail to %s expert...", 
+                                       fCurrentDetector.Data()));
+               if (!SendMail())
+                       Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert",
+                                       fCurrentDetector.Data()));
+
+       } else {
+               Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. "
+                               "Aborted before with %s. Retry number %d.", fCurrentDetector.Data(),
+                               status->GetStatusName(), status->GetCount()));
+               Bool_t increaseCount = kTRUE;
+               if (status->GetStatus() == AliShuttleStatus::kDCSError || 
+                       status->GetStatus() == AliShuttleStatus::kDCSStarted)
+                               increaseCount = kFALSE;
+                               
+               UpdateShuttleStatus(AliShuttleStatus::kStarted, increaseCount);
+               cont = kTRUE;
        }
-       localEntries->Clear();
 
-       return result;
+       return cont;
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* entry,
-                               TObjArray* valueSet, DCSType type)
+Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
 {
-// Retrieve all "entry" data points from the DCS server
-// host, port: TSocket connection parameters
-// entry: name of the alias or data point
-// valueSet: array of retrieved AliDCSValue's
-// type: kAlias or kDP
+       //
+       // Makes data retrieval for all detectors in the configuration.
+       // entry: Shuttle logbook entry, contains run paramenters and status of detectors
+       // (Unprocessed, Inactive, Failed or Done).
+       // Returns kFALSE in case of error occured and kTRUE otherwise
+       //
 
-       AliDCSClient client(host, port, fTimeout, fRetries);
-       if (!client.IsConnected())
-       {
-               return kFALSE;
-       }
+       if (!entry) return kFALSE;
+
+       fLogbookEntry = entry;
+
+       Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^*",
+                                       GetCurrentRun()));
 
-       Int_t result=0;
+       // Send the information to ML
+       TMonaLisaText  mlStatus("SHUTTLE_status", "Processing");
+       TMonaLisaText  mlRunType("SHUTTLE_runtype", Form("%s (%s)", entry->GetRunType(), entry->GetRunParameter("log")));
 
-       if (type == kAlias)
+       TList mlList;
+       mlList.Add(&mlStatus);
+       mlList.Add(&mlRunType);
+
+       TString mlID;
+       mlID.Form("%d", GetCurrentRun());
+       fMonaLisa->SendParameters(&mlList, mlID);
+
+       if (fLogbookEntry->IsDone())
        {
-               result = client.GetAliasValues(entry,
-                       GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
-       } else
-       if (type == kDP)
+               Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
+               UpdateShuttleLogbook("shuttle_done");
+               fLogbookEntry = 0;
+               return kTRUE;
+       }
+
+       // read test mode if flag is set
+       if (fReadTestMode)
        {
-               result = client.GetDPValues(entry,
-                       GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
+               fTestMode = kNone;
+               TString logEntry(entry->GetRunParameter("log"));
+               //printf("log entry = %s\n", logEntry.Data());
+               TString searchStr("Testmode: ");
+               Int_t pos = logEntry.Index(searchStr.Data());
+               //printf("%d\n", pos);
+               if (pos >= 0)
+               {
+                       TSubString subStr = logEntry(pos + searchStr.Length(), logEntry.Length());
+                       //printf("%s\n", subStr.String().Data());
+                       TString newStr(subStr.Data());
+                       TObjArray* token = newStr.Tokenize(' ');
+                       if (token)
+                       {
+                               //token->Print();
+                               TObjString* tmpStr = dynamic_cast<TObjString*> (token->First());
+                               if (tmpStr)
+                               {
+                                       Int_t testMode = tmpStr->String().Atoi();
+                                       if (testMode > 0)
+                                       {
+                                               Log("SHUTTLE", Form("Process - Enabling test mode %d", testMode));
+                                               SetTestMode((TestMode) testMode);
+                                       }
+                               }
+                               delete token;          
+                       }
+               }
        }
+               
+       fLogbookEntry->Print("all");
 
-       if (result < 0)
+       // Initialization
+       Bool_t hasError = kFALSE;
+
+       // Set the CDB and Reference folders according to the year and LHC period
+       TString lhcPeriod(GetLHCPeriod());
+       if (lhcPeriod.Length() == 0) 
        {
-               Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
-                       entry, AliDCSClient::GetErrorString(result)));
+               Log("SHUTTLE","Process - LHCPeriod not found in logbook!");
+               return 0; 
+       }       
+       
+       if (fgkMainCDB.Length() == 0)
+               fgkMainCDB = Form("alien://folder=/alice/data/%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache", 
+                                       GetCurrentYear(), lhcPeriod.Data());
+       
+       if (fgkMainRefStorage.Length() == 0)
+               fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache", 
+                                       GetCurrentYear(), lhcPeriod.Data());
+       
+       // Loop on detectors in the configuration
+       TIter iter(fConfig->GetDetectors());
+       TObjString* aDetector = 0;
+
+       Bool_t first = kTRUE;
+
+       while ((aDetector = (TObjString*) iter.Next()))
+       {
+               fCurrentDetector = aDetector->String();
 
-               if (result == AliDCSClient::fgkServerError)
+               if (ContinueProcessing() == kFALSE) continue;
+               
+               if (first)
                {
-                       Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
-                               client.GetServerError().Data()));
+                 // only read QueryCDB when needed and only once
+                 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
+                 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
+                 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
+                 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
+                 first = kFALSE;
                }
 
-               return kFALSE;
-       }
+               Log("SHUTTLE", Form("\t\t\t****** run %d - %s: START  ******",
+                                               GetCurrentRun(), aDetector->GetName()));
 
-       return kTRUE;
-}
+               for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
 
-//______________________________________________________________________________________________
-const char* AliShuttle::GetFile(Int_t system, const char* detector,
-               const char* id, const char* source)
-{
-// Get calibration file from file exchange servers
-// calls specific getter according to system index (kDAQ, kDCS, kHLT)
+               Log(fCurrentDetector.Data(), "Process - Starting processing");
 
-       switch(system){
-               case kDAQ:
-                       return GetDAQFileName(detector, id, source);
-                       break;
-               case kDCS:
-                       return GetDCSFileName(detector, id, source);
-                       break;
-               case kHLT:
-                       return GetHLTFileName(detector, id, source);
-                       break;
-               default:
-                       AliError(Form("No valid system index: %d",system));
+               Int_t pid = fork();
+
+               if (pid < 0)
+               {
+                       Log("SHUTTLE", "Process - ERROR: Forking failed");
+               }
+               else if (pid > 0)
+               {
+                       // parent
+                       Log("SHUTTLE", Form("Process - In parent process of %d - %s: Starting monitoring",
+                                                       GetCurrentRun(), aDetector->GetName()));
+
+                       Long_t begin = time(0);
+
+                       int status; // to be used with waitpid, on purpose an int (not Int_t)!
+                       while (waitpid(pid, &status, WNOHANG) == 0)
+                       {
+                               Long_t expiredTime = time(0) - begin;
+
+                               if (expiredTime > fConfig->GetPPTimeOut())
+                               {
+                                       TString tmp;
+                                       tmp.Form("Process - Process of %s time out. "
+                                                       "Run time: %d seconds. Killing...",
+                                                       fCurrentDetector.Data(), expiredTime);
+                                       Log("SHUTTLE", tmp);
+                                       Log(fCurrentDetector, tmp);
+
+                                       kill(pid, 9);
+
+                                       UpdateShuttleStatus(AliShuttleStatus::kPPTimeOut);
+                                       hasError = kTRUE;
+
+                                       gSystem->Sleep(1000);
+                               }
+                               else
+                               {
+                                       gSystem->Sleep(1000);
+                                       
+                                       TString checkStr;
+                                       checkStr.Form("ps -o vsize --pid %d | tail -n 1", pid);
+                                       FILE* pipe = gSystem->OpenPipe(checkStr, "r");
+                                       if (!pipe)
+                                       {
+                                               Log("SHUTTLE", Form("Process - Error: "
+                                                       "Could not open pipe to %s", checkStr.Data()));
+                                               continue;
+                                       }
+                                               
+                                       char buffer[100];
+                                       if (!fgets(buffer, 100, pipe))
+                                       {
+                                               Log("SHUTTLE", "Process - Error: ps did not return anything");
+                                               gSystem->ClosePipe(pipe);
+                                               continue;
+                                       }
+                                       gSystem->ClosePipe(pipe);
+                                       
+                                       //Log("SHUTTLE", Form("ps returned %s", buffer));
+                                       
+                                       Int_t mem = 0;
+                                       if ((sscanf(buffer, "%d\n", &mem) != 1) || !mem)
+                                       {
+                                               Log("SHUTTLE", "Process - Error: Could not parse output of ps");
+                                               continue;
+                                       }
+                                       
+                                       if (expiredTime % 60 == 0)
+                                       {
+                                               Log("SHUTTLE", Form("Process - %s: Checking process. "
+                                                       "Run time: %d seconds - Memory consumption: %d KB",
+                                                       fCurrentDetector.Data(), expiredTime, mem));
+                                               SendAlive();
+                                       }
+                                       
+                                       if (mem > fConfig->GetPPMaxMem())
+                                       {
+                                               TString tmp;
+                                               tmp.Form("Process - Process exceeds maximum allowed memory "
+                                                       "(%d KB > %d KB). Killing...",
+                                                       mem, fConfig->GetPPMaxMem());
+                                               Log("SHUTTLE", tmp);
+                                               Log(fCurrentDetector, tmp);
+       
+                                               kill(pid, 9);
+       
+                                               UpdateShuttleStatus(AliShuttleStatus::kPPOutOfMemory);
+                                               hasError = kTRUE;
+       
+                                               gSystem->Sleep(1000);
+                                       }
+                               }
+                       }
+
+                       Log("SHUTTLE", Form("Process - In parent process of %d - %s: Client has terminated.",
+                                                               GetCurrentRun(), aDetector->GetName()));
+
+                       if (WIFEXITED(status))
+                       {
+                               Int_t returnCode = WEXITSTATUS(status);
+
+                               Log("SHUTTLE", Form("Process - %s: the return code is %d", fCurrentDetector.Data(),
+                                                                               returnCode));
+
+                               if (returnCode == 0) hasError = kTRUE;
+                       }
+               }
+               else if (pid == 0)
+               {
+                       // client
+                       Log("SHUTTLE", Form("Process - In client process of %d - %s", GetCurrentRun(),
+                               aDetector->GetName()));
+
+                       Log("SHUTTLE", Form("Process - Redirecting output to %s log",fCurrentDetector.Data()));
+
+                       if ((freopen(GetLogFileName(fCurrentDetector), "a", stdout)) == 0)
+                       {
+                               Log("SHUTTLE", "Process - Could not freopen stdout");
+                       }
+                       else
+                       {
+                               fOutputRedirected = kTRUE;
+                               if ((dup2(fileno(stdout), fileno(stderr))) < 0)
+                                       Log("SHUTTLE", "Process - Could not redirect stderr");
+                               
+                       }
+                       
+                       TString wd = gSystem->WorkingDirectory();
+                       TString tmpDir = Form("%s/%s_%d_process", GetShuttleTempDir(), 
+                               fCurrentDetector.Data(), GetCurrentRun());
+                       
+                       Int_t result = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
+                       if (!result) // temp dir already exists!
+                       {
+                               Log(fCurrentDetector.Data(), 
+                                       Form("Process - %s dir already exists! Removing...", tmpDir.Data()));
+                               gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));         
+                       } 
+                       
+                       if (gSystem->mkdir(tmpDir.Data(), 1))
+                       {
+                               Log(fCurrentDetector.Data(), "Process - could not make temp directory!!");
+                               gSystem->Exit(1);
+                       }
+                       
+                       if (!gSystem->ChangeDirectory(tmpDir.Data())) 
+                       {
+                               Log(fCurrentDetector.Data(), "Process - could not change directory!!");
+                               gSystem->Exit(1);                       
+                       }
+                       
+                       Bool_t success = ProcessCurrentDetector();
+                       
+                       gSystem->ChangeDirectory(wd.Data());
+                                               
+                       if (success) // Preprocessor finished successfully!
+                       { 
+                               // remove temporary folder
+                                // temporary commented (JF)
+                               //gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
+                               
+                               // Update time_processed field in FXS DB
+                               if (UpdateTable() == kFALSE)
+                                       Log("SHUTTLE", Form("Process - %s: Could not update FXS databases!", 
+                                                       fCurrentDetector.Data()));
+
+                               // Transfer the data from local storage to main storage (Grid)
+                               UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
+                               if (StoreOCDB() == kFALSE)
+                               {
+                                       Log("SHUTTLE", 
+                                               Form("\t\t\t****** run %d - %s: STORAGE ERROR ******",
+                                                       GetCurrentRun(), aDetector->GetName()));
+                                       UpdateShuttleStatus(AliShuttleStatus::kStoreError);
+                                       success = kFALSE;
+                               } else {
+                                       Log("SHUTTLE", 
+                                               Form("\t\t\t****** run %d - %s: DONE ******",
+                                                       GetCurrentRun(), aDetector->GetName()));
+                                       UpdateShuttleStatus(AliShuttleStatus::kDone);
+                                       UpdateShuttleLogbook(fCurrentDetector, "DONE");
+                               }
+                       } else 
+                       {
+                               Log("SHUTTLE", 
+                                       Form("\t\t\t****** run %d - %s: PP ERROR ******",
+                                               GetCurrentRun(), aDetector->GetName()));
+                       }
+
+                       for (UInt_t iSys=0; iSys<3; iSys++)
+                       {
+                               if (fFXSCalled[iSys]) fFXSlist[iSys].Clear();
+                       }
+
+                       Log("SHUTTLE", Form("Process - Client process of %d - %s is exiting now with %d.",
+                                                       GetCurrentRun(), aDetector->GetName(), success));
+
+                       // the client exits here
+                       gSystem->Exit(success);
+
+                       AliError("We should never get here!!!");
+               }
        }
 
-       return 0;
-}
+       Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^*",
+                                                       GetCurrentRun()));
 
-//______________________________________________________________________________________________
-TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
-{
-// Get sources producing the condition file Id from file exchange servers
-// calls specific getter according to system index (kDAQ, kDCS, kHLT)
+       //check if shuttle is done for this run, if so update logbook
+       TObjArray checkEntryArray;
+       checkEntryArray.SetOwner(1);
+       TString whereClause = Form("where run=%d", GetCurrentRun());
+       if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) || 
+                       checkEntryArray.GetEntries() == 0) {
+               Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!",
+                                               GetCurrentRun()));
+               return hasError == kFALSE;
+       }
 
-       switch(system){
-               case kDAQ:
-                       return GetDAQFileSources(detector, id);
-                       break;
-               case kDCS:
-                       return GetDCSFileSources(detector, id);
-                       break;
-               case kHLT:
-                       return GetHLTFileSources(detector, id);
-                       break;
-               default:
-                       AliError(Form("No valid system index: %d",system));
+       AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
+                                               (checkEntryArray.At(0));
+
+       if (checkEntry)
+       {
+               if (checkEntry->IsDone())
+               {
+                       Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
+                       UpdateShuttleLogbook("shuttle_done");
+               }
+               else
+               {
+                       for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
+                       {
+                               if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
+                               {
+                                       AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
+                                                       checkEntry->GetRun(), GetDetName(iDet)));
+                                       fFirstUnprocessed[iDet] = kFALSE;
+                               }
+                       }
+               }
        }
 
-       return NULL;
+       fLogbookEntry = 0;
+
+       return hasError == kFALSE;
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::Connect(Int_t system)
+Bool_t AliShuttle::ProcessCurrentDetector()
 {
-// Connect to MySQL Server of the system's FXS MySQL databases
-// DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
+       //
+        // Makes data retrieval just for a specific detector (fCurrentDetector).
+       // Threre should be a configuration for this detector.
 
-       // check connection: if already connected return
-       if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
+       Log("SHUTTLE", Form("ProcessCurrentDetector - Retrieving values for %s, run %d", 
+                                               fCurrentDetector.Data(), GetCurrentRun()));
 
-       TString dbHost, dbUser, dbPass, dbName;
+       TString wd = gSystem->WorkingDirectory();
+       
+       if (!CleanReferenceStorage(fCurrentDetector.Data()))
+               return kFALSE;
+       
+       gSystem->ChangeDirectory(wd.Data());
+       
+       TMap* dcsMap = new TMap();
 
-       if (system < 3) // FXS db servers
+       // call preprocessor
+       AliPreprocessor* aPreprocessor =
+               dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
+
+       aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
+
+       Bool_t processDCS = aPreprocessor->ProcessDCS();
+
+       if (!processDCS)
        {
-               dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
-               dbUser = fConfig->GetFXSdbUser(system);
-               dbPass = fConfig->GetFXSdbPass(system);
-               dbName =   fConfig->GetFXSdbName(system);
-       } else { // Run & Shuttle logbook servers
-       // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
-               dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
-               dbUser = fConfig->GetDAQlbUser();
-               dbPass = fConfig->GetDAQlbPass();
-               dbName =   fConfig->GetDAQlbDB();
+               Log(fCurrentDetector, "ProcessCurrentDetector -"
+                       " The preprocessor requested to skip the retrieval of DCS values");
        }
+       else if (fTestMode & kSkipDCS)
+       {
+               Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Skipping DCS processing");
+       } 
+       else if (fTestMode & kErrorDCS)
+       {
+               Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Simulating DCS error");
+               UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
+               UpdateShuttleStatus(AliShuttleStatus::kDCSError);
+               delete dcsMap;
+               return kFALSE;
+       } else {
 
-       fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
-       if (!fServer[system] || !fServer[system]->IsConnected()) {
-               if(system < 3)
+               UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
+
+               // Query DCS archive
+               Int_t nServers = fConfig->GetNServers(fCurrentDetector);
+               
+               for (int iServ=0; iServ<nServers; iServ++)
                {
-               AliError(Form("Can't establish connection to FXS database for %s",
-                                       AliShuttleInterface::GetSystemName(system)));
-               } else {
-               AliError("Can't establish connection to Run logbook.");
+               
+                       TString host(fConfig->GetDCSHost(fCurrentDetector, iServ));
+                       Int_t port = fConfig->GetDCSPort(fCurrentDetector, iServ);
+                       Int_t multiSplit = fConfig->GetMultiSplit(fCurrentDetector, iServ);
+
+                       Log(fCurrentDetector, Form("ProcessCurrentDetector -"
+                                       " Querying DCS Amanda server %s:%d (%d of %d)", 
+                                       host.Data(), port, iServ+1, nServers));
+                       
+                       TMap* aliasMap = 0;
+                       TMap* dpMap = 0;
+       
+                       if (fConfig->GetDCSAliases(fCurrentDetector, iServ)->GetEntries() > 0)
+                       {
+                               aliasMap = GetValueSet(host, port, 
+                                               fConfig->GetDCSAliases(fCurrentDetector, iServ), 
+                                               kAlias, multiSplit);
+                               if (!aliasMap)
+                               {
+                                       Log(fCurrentDetector, 
+                                               Form("ProcessCurrentDetector -"
+                                                       " Error retrieving DCS aliases from server %s."
+                                                       " Sending mail to DCS experts!", host.Data()));
+                                       UpdateShuttleStatus(AliShuttleStatus::kDCSError);
+                                       
+                                       //if (!SendMailToDCS())
+                                       //      Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
+
+                                       delete dcsMap;
+                                       return kFALSE;
+                               }
+                       }
+                       
+                       if (fConfig->GetDCSDataPoints(fCurrentDetector, iServ)->GetEntries() > 0)
+                       {
+                               dpMap = GetValueSet(host, port, 
+                                               fConfig->GetDCSDataPoints(fCurrentDetector, iServ), 
+                                               kDP, multiSplit);
+                               if (!dpMap)
+                               {
+                                       Log(fCurrentDetector, 
+                                               Form("ProcessCurrentDetector -"
+                                                       " Error retrieving DCS data points from server %s."
+                                                       " Sending mail to DCS experts!", host.Data()));
+                                       UpdateShuttleStatus(AliShuttleStatus::kDCSError);
+                                       
+                                       //if (!SendMailToDCS())
+                                       //      Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
+                                       
+                                       if (aliasMap) delete aliasMap;
+                                       delete dcsMap;
+                                       return kFALSE;
+                               }                               
+                       }
+                       
+                       // merge aliasMap and dpMap into dcsMap
+                       if(aliasMap) {
+                               TIter iter(aliasMap);
+                               TObjString* key = 0;
+                               while ((key = (TObjString*) iter.Next()))
+                                       dcsMap->Add(key, aliasMap->GetValue(key->String()));
+                               
+                               aliasMap->SetOwner(kFALSE);
+                               delete aliasMap;
+                       }       
+                       
+                       if(dpMap) {
+                               TIter iter(dpMap);
+                               TObjString* key = 0;
+                               while ((key = (TObjString*) iter.Next()))
+                                       dcsMap->Add(key, dpMap->GetValue(key->String()));
+                               
+                               dpMap->SetOwner(kFALSE);
+                               delete dpMap;
+                       }
                }
-               if(fServer[system]) delete fServer[system];
-               return kFALSE;
        }
+       
+       // save map into file, to help debugging in case of preprocessor error
+       TFile* f = TFile::Open("DCSMap.root","recreate");
+       f->cd();
+       dcsMap->Write("DCSMap", TObject::kSingleKey);
+       f->Close();
+       delete f;
+       
+       // DCS Archive DB processing successful. Call Preprocessor!
+       UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
 
-       // Get tables
-       // TODO in the configuration should the table name be there too?
-       TSQLResult* aResult=0;
-       switch(system){
-               case kDAQ:
-                       aResult = fServer[kDAQ]->GetTables(dbName.Data());
-                       break;
-               case kDCS:
-                       //aResult = fServer[kDCS]->GetTables(dbName.Data());
-                       break;
-               case kHLT:
-                       aResult = fServer[kHLT]->GetTables(dbName.Data());
-                       break;
-               default:
-                       aResult = fServer[3]->GetTables(dbName.Data());
-                       break;
+       UInt_t returnValue = aPreprocessor->Process(dcsMap);
+
+       if (returnValue > 0) // Preprocessor error!
+       {
+               Log(fCurrentDetector, Form("ProcessCurrentDetector - "
+                               "Preprocessor failed. Process returned %d.", returnValue));
+               UpdateShuttleStatus(AliShuttleStatus::kPPError);
+               dcsMap->DeleteAll();
+               delete dcsMap;
+               return kFALSE;
        }
+       
+       // preprocessor ok!
+       UpdateShuttleStatus(AliShuttleStatus::kPPDone);
+       Log(fCurrentDetector, Form("ProcessCurrentDetector - %s preprocessor returned success",
+                               fCurrentDetector.Data()));
+
+       dcsMap->DeleteAll();
+       delete dcsMap;
 
-       delete aResult;
        return kTRUE;
 }
 
 //______________________________________________________________________________________________
-const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
+void AliShuttle::CountOpenRuns()
 {
-// Retrieves a file from the DAQ FXS.
-// First queris the DAQ FXS database for the DAQ file name, using the run, detector, id and source info
-// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
-// run: current run being processed (given by Logbook entry fLogbookEntry)
-// detector: the Preprocessor name
-// id: provided as a parameter by the Preprocessor
-// source: provided by the Preprocessor through GetFileSources function
-
+       // Query DAQ's Shuttle logbook and sends the number of open runs to ML
+       
        // check connection, in case connect
-       if (!Connect(kDAQ))
-       {
-               Log(detector, "GetDAQFileName - Couldn't connect to DAQ FXS database");
-               return 0;
-       }
-
-       // Query preparation
-       TString sqlQueryStart = Form("select filePath from %s where", fConfig->GetFXSdbTable(kDAQ));
-       TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
-                               GetCurrentRun(), detector, id, source);
-       TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
-
-       AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
+       if (!Connect(3)) 
+               return;
 
-       // Query execution
-       TSQLResult* aResult = 0;
-       aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
+       TString sqlQuery;
+       sqlQuery = Form("select count(*) from %s where shuttle_done=0", fConfig->GetShuttlelbTable());
+       
+       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
        if (!aResult) {
-               Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
-                               id, source));
-               return 0;
+               AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
+               return;
        }
 
-       if(aResult->GetRowCount() == 0)
-       {
-               Log(detector,
-                       Form("GetDAQFileName - No entry in FXS table for: id = %s, source = %s",
-                               id, source));
-               delete aResult;
-               return 0;
+       AliDebug(2,Form("Query = %s", sqlQuery.Data()));
+       
+       if (aResult->GetRowCount() == 0) {
+               AliError(Form("No result for query %s received", sqlQuery.Data()));
+               return;
        }
 
-       if (aResult->GetRowCount() > 1) {
-               Log(detector,
-                       Form("GetDAQFileName - More than one entry in FXS table for: id = %s, source = %s",
-                               id, source));
-               delete aResult;
-               return 0;
+       if (aResult->GetFieldCount() != 1) {
+               AliError(Form("Invalid field count for query %s received", sqlQuery.Data()));
+               return;
        }
 
-       TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
-
-       if (!aRow){
-               Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
-                               id, source));
-               delete aResult;
-               return 0;
+       TSQLRow* aRow = aResult->Next();
+       if (!aRow) {
+               AliError(Form("Could not receive result of query %s", sqlQuery.Data()));
+               return;
        }
-
-       TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
-
-       delete aResult;
+       
+       TString result(aRow->GetField(0), aRow->GetFieldLength(0));
+       Int_t count = result.Atoi();
+       
+       Log("SHUTTLE", Form("%d unprocessed runs", count));
+       
        delete aRow;
+       delete aResult;
 
-       AliDebug(2, Form("filePath = %s",filePath.Data()));
+       TMonaLisaValue mlStatus("SHUTTLE_openruns", count);
 
-       // retrieved file is renamed to make it unique
-       TString localFileName = Form("DAQ_%s_%d_%s_%s.shuttle",
-                                       detector, GetCurrentRun(), id, source);
+       TList mlList;
+       mlList.Add(&mlStatus);
 
-       // file retrieval from DAQ FXS
-       Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
-       if(!result) {
-               Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FXS failed", filePath.Data()));
-               return 0;
-       } else {
-               AliInfo(Form("File %s copied from DAQ FXS into %s/%s",
-                       filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
-       }
+       fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
+}
 
-       fFXSCalled[kDAQ]=kTRUE;
-       TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, source));
-       fFXSlist[kDAQ].Add(fileParams);
+//______________________________________________________________________________________________
+Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
+               TObjArray& entries)
+{
+       // Query DAQ's Shuttle logbook and fills detector status object.
+       // Call QueryRunParameters to query DAQ logbook for run parameters.
+       //
 
-       static TString fullLocalFileName;
-       fullLocalFileName = TString::Format("%s/%s", fgkShuttleTempDir, localFileName.Data());
-       
-       AliInfo(Form("fullLocalFileName = %s", fullLocalFileName.Data()));
+       entries.SetOwner(1);
 
-       return fullLocalFileName.Data();
+       // check connection, in case connect
+       if (!Connect(3)) return kFALSE;
 
-}
+       TString sqlQuery;
+       sqlQuery = Form("select * from %s %s order by run", fConfig->GetShuttlelbTable(), whereClause);
 
-//______________________________________________________________________________________________
-Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
-{
-// Copies file from DAQ FXS to local Shuttle machine
+       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
+       if (!aResult) {
+               AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
+               return kFALSE;
+       }
 
-       // check temp directory: trying to cd to temp; if it does not exist, create it
-       AliDebug(2, Form("Copy file %s from DAQ FXS into %s/%s",
-                       daqFileName, fgkShuttleTempDir, localFileName));
+       AliDebug(2,Form("Query = %s", sqlQuery.Data()));
 
-       void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
-       if (dir == NULL) {
-               if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
-                       AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
-                       return kFALSE;
-               }
+       if(aResult->GetRowCount() == 0) {
+               Log("SHUTTLE", "No entries in Shuttle Logbook match request");
+               delete aResult;
+               return kTRUE;
+       }
 
-       } else {
-               gSystem->FreeDirectory(dir);
+       // TODO Check field count!
+       const UInt_t nCols = 23;
+       if (aResult->GetFieldCount() != (Int_t) nCols) {
+               Log("SHUTTLE", "Invalid SQL result field number!");
+               delete aResult;
+               return kFALSE;
        }
 
-       TString baseDAQFXSFolder = "FES";
-       TString command = Form("scp -oPort=%d -2 %s@%s:%s/%s %s/%s",
-               fConfig->GetFXSPort(kDAQ),
-               fConfig->GetFXSUser(kDAQ),
-               fConfig->GetFXSHost(kDAQ),
-               baseDAQFXSFolder.Data(),
-               daqFileName,
-               fgkShuttleTempDir,
-               localFileName);
+       TSQLRow* aRow;
+       while ((aRow = aResult->Next())) {
+               TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
+               Int_t run = runString.Atoi();
 
-       AliDebug(2, Form("%s",command.Data()));
+               AliShuttleLogbookEntry *entry = QueryRunParameters(run);
+               if (!entry)
+                       continue;
 
-       UInt_t nRetries = 0;
-       UInt_t maxRetries = 3;
+               // loop on detectors
+               for(UInt_t ii = 0; ii < nCols; ii++)
+                       entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
 
-       // copy!! if successful TSystem::Exec returns 0
-       while(nRetries++ < maxRetries) {
-               AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
-               if(gSystem->Exec(command.Data()) == 0) return kTRUE;
+               entries.AddLast(entry);
+               delete aRow;
        }
 
-       return kFALSE;
-
+       delete aResult;
+       return kTRUE;
 }
 
 //______________________________________________________________________________________________
-TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
+AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
 {
-// Retrieves list of DAQ sources of file Id
+       //
+       // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
+       //
 
        // check connection, in case connect
-       if(!Connect(kDAQ)){
-               Log(detector, "GetDAQFileSources - Couldn't connect to DAQ FXS database");
+       if (!Connect(3))
                return 0;
-       }
 
-       // Query preparation
-       TString sqlQueryStart = Form("select DAQsource from %s where", fConfig->GetFXSdbTable(kDAQ));
-       TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
-                               GetCurrentRun(), detector, id);
-       TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
-
-       AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
+       TString sqlQuery;
+       sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
 
-       // Query execution
-       TSQLResult* aResult;
-       aResult = fServer[kDAQ]->Query(sqlQuery);
+       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
        if (!aResult) {
-               Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
+               Log("SHUTTLE", Form("Can't execute query <%s>!", sqlQuery.Data()));
                return 0;
        }
 
        if (aResult->GetRowCount() == 0) {
-               Log(detector,
-                       Form("GetDAQFileSources - No entry in FXS table for id: %s", id));
+               Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
                delete aResult;
                return 0;
        }
 
-       TSQLRow* aRow;
-       TList *list = new TList();
-       list->SetOwner(1);
+       if (aResult->GetRowCount() > 1) {
+               Log("SHUTTLE", Form("QueryRunParameters - UNEXPECTED: "
+                               "more than one entry in DAQ Logbook for run %d!", run));
+               delete aResult;
+               return 0;
+       }
+
+       TSQLRow* aRow = aResult->Next();
+       if (!aRow)
+       {
+               Log("SHUTTLE", Form("QueryRunParameters - Could not retrieve row for run %d. Skipping", run));
+               delete aResult;
+               return 0;
+       }
+
+       AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
 
-       while((aRow = aResult->Next())){
+       for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
+               entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
+
+       UInt_t startTime = entry->GetStartTime();
+       UInt_t endTime = entry->GetEndTime();
 
-               TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
-               AliDebug(2, Form("daqSource = %s", daqSource.Data()));
-               list->Add(new TObjString(daqSource));
+//     if (!startTime || !endTime || startTime > endTime) 
+//     {
+//             Log("SHUTTLE",
+//                     Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d. Skipping!",
+//                             run, startTime, endTime));              
+//             
+//             Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
+//             fLogbookEntry = entry;  
+//             if (!UpdateShuttleLogbook("shuttle_done"))
+//             {
+//                     AliError(Form("Could not update logbook for run %d !", run));
+//             }
+//             fLogbookEntry = 0;
+//                             
+//             delete entry;
+//             delete aRow;
+//             delete aResult;
+//             return 0;
+//     }
+
+       if (!startTime) 
+       {
+               Log("SHUTTLE",
+                       Form("QueryRunParameters - Invalid parameters for Run %d: " 
+                               "startTime = %d, endTime = %d. Skipping!",
+                                       run, startTime, endTime));              
+               
+               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
+               fLogbookEntry = entry;  
+               if (!UpdateShuttleLogbook("shuttle_ignored"))
+               {
+                       AliError(Form("Could not update logbook for run %d !", run));
+               }
+               fLogbookEntry = 0;
+                               
+               delete entry;
+               delete aRow;
+               delete aResult;
+               return 0;
+       }
+       
+       if (startTime && !endTime) 
+       {
+               // TODO Here we don't mark SHUTTLE done, because this may mean 
+               //the run is still ongoing!!            
+               Log("SHUTTLE",
+                       Form("QueryRunParameters - Invalid parameters for Run %d: "
+                            "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
+                                       run, startTime, endTime));              
+               
+               //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
+               //fLogbookEntry = entry;        
+               //if (!UpdateShuttleLogbook("shuttle_done"))
+               //{
+               //      AliError(Form("Could not update logbook for run %d !", run));
+               //}
+               //fLogbookEntry = 0;
+                               
+               delete entry;
+               delete aRow;
+               delete aResult;
+               return 0;
+       }
+                       
+       if (startTime && endTime && (startTime > endTime)) 
+       {
+               Log("SHUTTLE",
+                       Form("QueryRunParameters - Invalid parameters for Run %d: "
+                               "startTime = %d, endTime = %d. Skipping!",
+                                       run, startTime, endTime));              
+               
+               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
+               fLogbookEntry = entry;  
+               if (!UpdateShuttleLogbook("shuttle_ignored"))
+               {
+                       AliError(Form("Could not update logbook for run %d !", run));
+               }
+               fLogbookEntry = 0;
+                               
+               delete entry;
+               delete aRow;
+               delete aResult;
+               return 0;
+       }
+                       
+       TString totEventsStr = entry->GetRunParameter("totalEvents");  
+       Int_t totEvents = totEventsStr.Atoi();
+       if (totEvents < 1) 
+       {
+               Log("SHUTTLE",
+                       Form("QueryRunParameters - Run %d has 0 events - Skipping!", run));             
+               
+               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));           
+               fLogbookEntry = entry;  
+               if (!UpdateShuttleLogbook("shuttle_ignored"))
+               {
+                       AliError(Form("Could not update logbook for run %d !", run));
+               }
+               fLogbookEntry = 0;
+                               
+               delete entry;
                delete aRow;
+               delete aResult;
+               return 0;
        }
-       delete aResult;
 
-       return list;
+       delete aRow;
+       delete aResult;
 
+       return entry;
 }
 
 //______________________________________________________________________________________________
-const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
-// Retrieves a file from the DCS FXS.
-
-return "You're in DCS";
-
-}
+TMap* AliShuttle::GetValueSet(const char* host, Int_t port, const TSeqCollection* entries,
+                             DCSType type, Int_t multiSplit)
+{
+       // Retrieve all "entry" data points from the DCS server
+       // host, port: TSocket connection parameters
+       // entries: list of name of the alias or data point
+       // type: kAlias or kDP
+       // returns TMap of values, 0 when failure
+       
+       AliDCSClient client(host, port, fTimeout, fRetries, multiSplit);
 
-//______________________________________________________________________________________________
-TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
-// Retrieves file sources from the DCS FXS.
+       TMap* result = 0;
+       if (type == kAlias)
+       {
+               result = client.GetAliasValues(entries, GetCurrentStartTime(), 
+                       GetCurrentEndTime());
+       } 
+       else if (type == kDP)
+       {
+               result = client.GetDPValues(entries, GetCurrentStartTime(), 
+                       GetCurrentEndTime());
+       }
 
-return NULL;
+       if (result == 0)
+       {
+               Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get entries! Reason: %s",
+                       client.GetErrorString(client.GetResultErrorCode())));
+               if (client.GetResultErrorCode() == AliDCSClient::fgkServerError)        
+                       Log(fCurrentDetector.Data(), Form("GetValueSet - Server error code: %s",
+                               client.GetServerError().Data()));
 
+               return 0;
+       }
+               
+       return result;
 }
 
 //______________________________________________________________________________________________
-const char* AliShuttle::GetHLTFileName(const char* detector, const char* id, const char* source){
-// Retrieves a file from the HLT FXS.
-// First queris the HLT FXS database for the HLT file name, using the run, detector, id and source info
-// then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
-// run: current run being processed (given by Logbook entry fLogbookEntry)
-// detector: the Preprocessor name
-// id: provided as a parameter by the Preprocessor
-// source: provided by the Preprocessor through GetFileSources function
-
+const char* AliShuttle::GetFile(Int_t system, const char* detector,
+               const char* id, const char* source)
+{
+       // Get calibration file from file exchange servers
+       // First queris the FXS database for the file name, using the run, detector, id and source info
+       // then calls RetrieveFile(filename) for actual copy to local disk
+       // run: current run being processed (given by Logbook entry fLogbookEntry)
+       // detector: the Preprocessor name
+       // id: provided as a parameter by the Preprocessor
+       // source: provided by the Preprocessor through GetFileSources function
+
+       // check if test mode should simulate a FXS error
+       if (fTestMode & kErrorFXSFiles)
+       {
+               Log(detector, Form("GetFile - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
+               return 0;
+       }
+       
        // check connection, in case connect
-       if (!Connect(kHLT))
+       if (!Connect(system))
        {
-               Log(detector, "GetHLTFileName - Couldn't connect to HLT FXS database");
+               Log(detector, Form("GetFile - Couldn't connect to %s FXS database", GetSystemName(system)));
                return 0;
        }
 
        // Query preparation
-       TString sqlQueryStart = Form("select filePath,fileSize,fileChecksum from %s where",
-                                                                               fConfig->GetFXSdbTable(kHLT));
-       TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\"",
-                               GetCurrentRun(), detector, id, source);
+       TString sourceName(source);
+       Int_t nFields = 3;
+       TString sqlQueryStart = Form("select filePath,size,fileChecksum from %s where",
+                                                               fConfig->GetFXSdbTable(system));
+       TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
+                                                               GetCurrentRun(), detector, id);
+
+       if (system == kDAQ)
+       {
+               whereClause += Form(" and DAQsource=\"%s\"", source);
+       }
+       else if (system == kDCS)
+       {
+               sourceName="none";
+       }
+       else if (system == kHLT)
+       {
+               whereClause += Form(" and DDLnumbers=\"%s\"", source);
+               nFields = 3;
+       }
+
        TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
 
        AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
 
        // Query execution
        TSQLResult* aResult = 0;
-       aResult = dynamic_cast<TSQLResult*> (fServer[kHLT]->Query(sqlQuery));
+       aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
        if (!aResult) {
-               Log(detector, Form("GetHLTFileName - Can't execute SQL query for: id = %s, source = %s",
-                               id, source));
+               Log(detector, Form("GetFileName - Can't execute SQL query to %s database for: id = %s, source = %s",
+                               GetSystemName(system), id, sourceName.Data()));
                return 0;
        }
 
        if(aResult->GetRowCount() == 0)
        {
                Log(detector,
-                       Form("GetHLTFileName - No entry in FXS table for: id = %s, source = %s",
-                               id, source));
+                       Form("GetFileName - No entry in %s FXS db for: id = %s, source = %s",
+                               GetSystemName(system), id, sourceName.Data()));
                delete aResult;
                return 0;
        }
 
        if (aResult->GetRowCount() > 1) {
                Log(detector,
-                       Form("GetHLTFileName - More than one entry in FXS table for: id = %s, source = %s",
-                               id, source));
+                       Form("GetFileName - More than one entry in %s FXS db for: id = %s, source = %s",
+                               GetSystemName(system), id, sourceName.Data()));
                delete aResult;
                return 0;
        }
 
-       if (aResult->GetFieldCount() != 3) {
+       if (aResult->GetFieldCount() != nFields) {
                Log(detector,
-                       Form("GetHLTFileName - Wrong field count in FXS table for: id = %s, source = %s",
-                               id, source));
+                       Form("GetFileName - Wrong field count in %s FXS db for: id = %s, source = %s",
+                               GetSystemName(system), id, sourceName.Data()));
                delete aResult;
                return 0;
        }
@@ -1530,262 +2355,501 @@ const char* AliShuttle::GetHLTFileName(const char* detector, const char* id, con
        TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
 
        if (!aRow){
-               Log(detector, Form("GetHLTFileName - Empty set result from query: id = %s, source = %s",
-                               id, source));
+               Log(detector, Form("GetFileName - Empty set result in %s FXS db from query: id = %s, source = %s",
+                               GetSystemName(system), id, sourceName.Data()));
                delete aResult;
                return 0;
        }
 
        TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
        TString fileSize(aRow->GetField(1), aRow->GetFieldLength(1));
-       TString fileMd5Sum(aRow->GetField(2), aRow->GetFieldLength(2));
+       TString fileChecksum(aRow->GetField(2), aRow->GetFieldLength(2));
 
        delete aResult;
        delete aRow;
 
-       AliDebug(2, Form("filePath = %s",filePath.Data()));
-
-       // The full file path in HLT FXS is runNb/DET/DDLnumber/filePath
-//     TString fullFilePath = Form("%d/%s/%s/%s", GetCurrentRun(), detector, source, filePath.Data());
+       AliDebug(2, Form("filePath = %s; size = %s, fileChecksum = %s",
+                               filePath.Data(), fileSize.Data(), fileChecksum.Data()));
 
        // retrieved file is renamed to make it unique
-       TString localFileName = Form("HLT_%s_%d_%s_%s.shuttle",
-                                       detector, GetCurrentRun(), id, source);
+       TString localFileName = Form("%s/%s_%d_process/%s_%s_%d_%s_%s.shuttle",
+                                       GetShuttleTempDir(), detector, GetCurrentRun(),
+                                       GetSystemName(system), detector, GetCurrentRun(), 
+                                       id, sourceName.Data());
 
-       // file retrieval from HLT FXS
-       Bool_t result = RetrieveHLTFile(filePath.Data(), localFileName.Data());
-       if(!result)
-       {
-               Log(detector, Form("GetHLTFileName - Copy of file %s from HLT FXS failed", filePath.Data()));
-               return 0;
-       } else {
-               AliInfo(Form("File %s copied from HLT FXS into %s/%s",
-                       filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
-       }
 
-       // compare md5sum of local file with the one stored in the HLT DB
-       Int_t md5Comp = gSystem->Exec(Form("md5sum %s/%s |grep %s 2>&1 > /dev/null",
-                                               fgkShuttleTempDir, localFileName.Data(), fileMd5Sum.Data()));
+       // file retrieval from FXS
+       UInt_t nRetries = 0;
+       UInt_t maxRetries = 3;
+       Bool_t result = kFALSE;
 
-       if (md5Comp != 0)
-       {
-               Log(detector, Form("GetHLTFileName - md5sum of file %s does not match with local copy!", filePath.Data()));
-               return 0;
-       }
+       // copy!! if successful TSystem::Exec returns 0
+       while(nRetries++ < maxRetries) {
+               AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
+               result = RetrieveFile(system, filePath.Data(), localFileName.Data());
+               if(!result)
+               {
+                       Log(detector, Form("GetFileName - Copy of file %s from %s FXS failed",
+                                       filePath.Data(), GetSystemName(system)));
+                       continue;
+               } 
 
-       fFXSCalled[kHLT]=kTRUE;
-       TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, source));
-       fFXSlist[kHLT].Add(fileParams);
+               if (fileChecksum.Length()>0)
+               {
+                       // compare md5sum of local file with the one stored in the FXS DB
+                       Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s 2>&1 > /dev/null",
+                                               localFileName.Data(), fileChecksum.Data()));
 
-       static TString fullLocalFileName;
-       fullLocalFileName = TString::Format("%s/%s", fgkShuttleTempDir, localFileName.Data());
-       
-       AliInfo(Form("fullLocalFileName = %s", fullLocalFileName.Data()));
+                       if (md5Comp != 0)
+                       {
+                               Log(detector, Form("GetFileName - md5sum of file %s does not match with local copy!",
+                                                       filePath.Data()));
+                               result = kFALSE;
+                               continue;
+                       }
+               } else {
+                       Log(fCurrentDetector, Form("GetFile - md5sum of file %s not set in %s database, skipping comparison",
+                                                       filePath.Data(), GetSystemName(system)));
+               }
+               if (result) break;
+       }
 
-       return fullLocalFileName.Data();
+       if(!result) return 0;
 
+       fFXSCalled[system]=kTRUE;
+       TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, sourceName.Data()));
+       fFXSlist[system].Add(fileParams);
+
+       static TString staticLocalFileName;
+       staticLocalFileName.Form("%s", localFileName.Data());
+       
+       Log(fCurrentDetector, Form("GetFile - Retrieved file with id %s and "
+                       "source %s from %s to %s", id, source, 
+                       GetSystemName(system), localFileName.Data()));
+                       
+       return staticLocalFileName.Data();
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::RetrieveHLTFile(const char* hltFileName, const char* localFileName)
+Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const char* localFileName)
 {
-// Copies file from HLT FXS to local Shuttle machine
+       //
+       // Copies file from FXS to local Shuttle machine
+       //
 
        // check temp directory: trying to cd to temp; if it does not exist, create it
-       AliDebug(2, Form("Copy file %s from HLT FXS into %s/%s",
-                       hltFileName, fgkShuttleTempDir, localFileName));
+       AliDebug(2, Form("Copy file %s from %s FXS into %s",
+                       GetSystemName(system), fxsFileName, localFileName));
+                       
+       TString tmpDir(localFileName);
+       
+       tmpDir = tmpDir(0,tmpDir.Last('/'));
 
-       void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
-       if (dir == NULL) {
-               if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
-                       AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
+       Int_t noDir = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
+       if (noDir) // temp dir does not exists!
+       {
+               if (gSystem->mkdir(tmpDir.Data(), 1))
+               {
+                       Log(fCurrentDetector.Data(), "RetrieveFile - could not make temp directory!!");
                        return kFALSE;
                }
+       }
 
-       } else {
-               gSystem->FreeDirectory(dir);
+       TString baseFXSFolder;
+       if (system == kDAQ)
+       {
+               baseFXSFolder = "FES/";
+       }
+       else if (system == kDCS)
+       {
+               baseFXSFolder = "";
+       }
+       else if (system == kHLT)
+       {
+               baseFXSFolder = "/opt/FXS/";
        }
 
-       TString baseHLTFXSFolder = "~";
-       TString command = Form("scp -oPort=%d %s@%s:%s/%s %s/%s",
-               fConfig->GetFXSPort(kHLT),
-               fConfig->GetFXSUser(kHLT),
-               fConfig->GetFXSHost(kHLT),
-               baseHLTFXSFolder.Data(),
-               hltFileName,
-               fgkShuttleTempDir,
+
+       TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s",
+               fConfig->GetFXSPort(system),
+               fConfig->GetFXSUser(system),
+               fConfig->GetFXSHost(system),
+               baseFXSFolder.Data(),
+               fxsFileName,
                localFileName);
 
        AliDebug(2, Form("%s",command.Data()));
 
-       UInt_t nRetries = 0;
-       UInt_t maxRetries = 3;
+       Bool_t result = (gSystem->Exec(command.Data()) == 0);
 
-       // copy!! if successful TSystem::Exec returns 0
-       while(nRetries++ < maxRetries) {
-               AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
-               if(gSystem->Exec(command.Data()) == 0) return kTRUE;
+       return result;
+}
+
+//______________________________________________________________________________________________
+TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
+{
+       //
+       // Get sources producing the condition file Id from file exchange servers
+       // if id is NULL all sources are returned (distinct)
+       //
+
+       Log(detector, Form("GetFileSources - Retrieving sources with id %s from %s", id, GetSystemName(system)));
+       
+       // check if test mode should simulate a FXS error
+       if (fTestMode & kErrorFXSSources)
+       {
+               Log(detector, Form("GetFileSources - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
+               return 0;
+       }
+
+       if (system == kDCS)
+       {
+               Log(detector, "GetFileSources - WARNING: DCS system has only one source of data!");
+               TList *list = new TList();
+               list->SetOwner(1);
+               list->Add(new TObjString(" "));
+               return list;
+       }
+
+       // check connection, in case connect
+       if (!Connect(system))
+       {
+               Log(detector, Form("GetFileSources - Couldn't connect to %s FXS database", GetSystemName(system)));
+               return NULL;
+       }
+
+       TString sourceName = 0;
+       if (system == kDAQ)
+       {
+               sourceName = "DAQsource";
+       } else if (system == kHLT)
+       {
+               sourceName = "DDLnumbers";
+       }
+
+       TString sqlQueryStart = Form("select distinct %s from %s where", sourceName.Data(), fConfig->GetFXSdbTable(system));
+       TString whereClause = Form("run=%d and detector=\"%s\"",
+                               GetCurrentRun(), detector);
+       if (id)
+               whereClause += Form(" and fileId=\"%s\"", id);
+       TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
+
+       AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
+
+       // Query execution
+       TSQLResult* aResult;
+       aResult = fServer[system]->Query(sqlQuery);
+       if (!aResult) {
+               Log(detector, Form("GetFileSources - Can't execute SQL query to %s database for id: %s",
+                               GetSystemName(system), id));
+               return 0;
+       }
+
+       TList *list = new TList();
+       list->SetOwner(1);
+       
+       if (aResult->GetRowCount() == 0)
+       {
+               Log(detector,
+                       Form("GetFileSources - No entry in %s FXS table for id: %s", GetSystemName(system), id));
+               delete aResult;
+               return list;
+       }
+
+       Log(detector, Form("GetFileSources - Found %d sources", aResult->GetRowCount()));
+
+       TSQLRow* aRow;
+       while ((aRow = aResult->Next()))
+       {
+
+               TString source(aRow->GetField(0), aRow->GetFieldLength(0));
+               AliDebug(2, Form("%s = %s", sourceName.Data(), source.Data()));
+               list->Add(new TObjString(source));
+               delete aRow;
        }
 
-       return kFALSE;
+       delete aResult;
 
+       return list;
 }
 
 //______________________________________________________________________________________________
-TList* AliShuttle::GetHLTFileSources(const char* detector, const char* id){
-// Retrieves list of HLT sources (DDLnumbers) of file Id
+TList* AliShuttle::GetFileIDs(Int_t system, const char* detector, const char* source)
+{
+       //
+       // Get all ids of condition files produced by a given source from file exchange servers
+       //
+       
+        Log(detector, Form("GetFileIDs - Retrieving ids with source %s with %s", source, GetSystemName(system)));
 
-       // check connection, in case connect
-       if(!Connect(kHLT)){
-               Log(detector, "GetHLTFileSources - Couldn't connect to HLT FXS database");
+       // check if test mode should simulate a FXS error
+       if (fTestMode & kErrorFXSSources)
+       {
+               Log(detector, Form("GetFileIDs - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
                return 0;
        }
 
-       // Query preparation
-       TString sqlQueryStart = Form("select DDLnumbers from %s where", fConfig->GetFXSdbTable(kHLT));
-       TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
-                               GetCurrentRun(), detector, id);
+       // check connection, in case connect
+       if (!Connect(system))
+       {
+               Log(detector, Form("GetFileIDs - Couldn't connect to %s FXS database", GetSystemName(system)));
+               return NULL;
+       }
+
+       TString sourceName = 0;
+       if (system == kDAQ)
+       {
+               sourceName = "DAQsource";
+       } else if (system == kHLT)
+       {
+               sourceName = "DDLnumbers";
+       }
+
+       TString sqlQueryStart = Form("select fileId from %s where", fConfig->GetFXSdbTable(system));
+       TString whereClause = Form("run=%d and detector=\"%s\"",
+                               GetCurrentRun(), detector);
+       if (sourceName.Length() > 0 && source)
+               whereClause += Form(" and %s=\"%s\"", sourceName.Data(), source);
        TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
 
        AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
 
        // Query execution
        TSQLResult* aResult;
-       aResult = fServer[kHLT]->Query(sqlQuery);
+       aResult = fServer[system]->Query(sqlQuery);
        if (!aResult) {
-               Log(detector, Form("GetHLTFileSources - Can't execute SQL query for id: %s", id));
+               Log(detector, Form("GetFileIDs - Can't execute SQL query to %s database for source: %s",
+                               GetSystemName(system), source));
                return 0;
        }
 
-       if (aResult->GetRowCount() == 0) {
+       TList *list = new TList();
+       list->SetOwner(1);
+       
+       if (aResult->GetRowCount() == 0)
+       {
                Log(detector,
-                       Form("GetHLTFileSources - No entry in FXS table for id: %s", id));
+                       Form("GetFileIDs - No entry in %s FXS table for source: %s", GetSystemName(system), source));
                delete aResult;
-               return 0;
+               return list;
        }
 
+        Log(detector, Form("GetFileIDs - Found %d ids", aResult->GetRowCount()));
+
        TSQLRow* aRow;
-       TList *list = new TList();
-       list->SetOwner(1);
 
-       while((aRow = aResult->Next())){
+       while ((aRow = aResult->Next()))
+       {
 
-               TString ddlNumbers(aRow->GetField(0), aRow->GetFieldLength(0));
-               AliDebug(2, Form("DDLnumbers = %s", ddlNumbers.Data()));
-               list->Add(new TObjString(ddlNumbers));
+               TString id(aRow->GetField(0), aRow->GetFieldLength(0));
+               AliDebug(2, Form("fileId = %s", id.Data()));
+               list->Add(new TObjString(id));
                delete aRow;
        }
+
        delete aResult;
 
        return list;
-
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::UpdateDAQTable()
+Bool_t AliShuttle::Connect(Int_t system)
 {
-// Update DAQ table filling time_processed field in all rows corresponding to current run and detector
+       // Connect to MySQL Server of the system's FXS MySQL databases
+       // DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
+       //
 
-       // check connection, in case connect
-       if(!Connect(kDAQ)){
-               Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ FXS database");
+       // check connection: if already connected return
+       if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
+
+       TString dbHost, dbUser, dbPass, dbName;
+
+       if (system < 3) // FXS db servers
+       {
+               dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
+               dbUser = fConfig->GetFXSdbUser(system);
+               dbPass = fConfig->GetFXSdbPass(system);
+               dbName =   fConfig->GetFXSdbName(system);
+       } else { // Run & Shuttle logbook servers
+       // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
+               dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
+               dbUser = fConfig->GetDAQlbUser();
+               dbPass = fConfig->GetDAQlbPass();
+               dbName =   fConfig->GetDAQlbDB();
+       }
+
+       fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
+       if (!fServer[system] || !fServer[system]->IsConnected()) {
+               if(system < 3)
+               {
+               AliError(Form("Can't establish connection to FXS database for %s",
+                                       AliShuttleInterface::GetSystemName(system)));
+               } else {
+               AliError("Can't establish connection to Run logbook.");
+               }
+               if(fServer[system]) delete fServer[system];
                return kFALSE;
        }
 
-       TTimeStamp now; // now
+       // Get tables
+       TSQLResult* aResult=0;
+       switch(system){
+               case kDAQ:
+                       aResult = fServer[kDAQ]->GetTables(dbName.Data());
+                       break;
+               case kDCS:
+                       aResult = fServer[kDCS]->GetTables(dbName.Data());
+                       break;
+               case kHLT:
+                       aResult = fServer[kHLT]->GetTables(dbName.Data());
+                       break;
+               default:
+                       aResult = fServer[3]->GetTables(dbName.Data());
+                       break;
+       }
+
+       delete aResult;
+       return kTRUE;
+}
 
-       // Loop on FXS list entries
-       TIter iter(&fFXSlist[kDAQ]);
-       TObjString *aFXSentry=0;
-       while((aFXSentry = dynamic_cast<TObjString*> (iter.Next()))){
-               TString aFXSentrystr = aFXSentry->String();
-               TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
-               if(!aFXSarray || aFXSarray->GetEntries() != 2 ) {
-                       Log(fCurrentDetector, Form("UpdateDAQTable - error updating FXS entry. Check string: <%s>",
-                               aFXSentrystr.Data()));
-                       if(aFXSarray) delete aFXSarray;
-                       return kFALSE;
+//______________________________________________________________________________________________
+Bool_t AliShuttle::UpdateTable()
+{
+       //
+       // Update FXS table filling time_processed field in all rows corresponding to current run and detector
+       //
+
+       Bool_t result = kTRUE;
+
+       for (UInt_t system=0; system<3; system++)
+       {
+               if(!fFXSCalled[system]) continue;
+
+               // check connection, in case connect
+               if (!Connect(system))
+               {
+                       Log(fCurrentDetector, Form("UpdateTable - Couldn't connect to %s FXS database", GetSystemName(system)));
+                       result = kFALSE;
+                       continue;
                }
-               const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
-               const char* daqSource = ((TObjString*) aFXSarray->At(1))->GetName();
-               TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
-                       GetCurrentRun(), fCurrentDetector.Data(), fileId, daqSource);
 
-               delete aFXSarray;
+               TTimeStamp now; // now
 
-               TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(kDAQ),
-                                                       now.GetSec(), whereClause.Data());
+               // Loop on FXS list entries
+               TIter iter(&fFXSlist[system]);
+               TObjString *aFXSentry=0;
+               while ((aFXSentry = dynamic_cast<TObjString*> (iter.Next())))
+               {
+                       TString aFXSentrystr = aFXSentry->String();
+                       TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
+                       if (!aFXSarray || aFXSarray->GetEntries() != 2 )
+                       {
+                               Log(fCurrentDetector, Form("UpdateTable - error updating %s FXS entry. Check string: <%s>",
+                                       GetSystemName(system), aFXSentrystr.Data()));
+                               if(aFXSarray) delete aFXSarray;
+                               result = kFALSE;
+                               continue;
+                       }
+                       const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
+                       const char* source = ((TObjString*) aFXSarray->At(1))->GetName();
 
-               AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
+                       TString whereClause;
+                       if (system == kDAQ)
+                       {
+                               whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
+                                                       GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
+                       }
+                       else if (system == kDCS)
+                       {
+                               whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\";",
+                                                       GetCurrentRun(), fCurrentDetector.Data(), fileId);
+                       }
+                       else if (system == kHLT)
+                       {
+                               whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\";",
+                                                       GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
+                       }
 
-               // Query execution
-               TSQLResult* aResult;
-               aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
-               if (!aResult) {
-                       Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
-                       return kFALSE;
+                       delete aFXSarray;
+
+                       TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
+                                                               now.GetSec(), whereClause.Data());
+
+                       AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
+
+                       // Query execution
+                       TSQLResult* aResult;
+                       aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
+                       if (!aResult)
+                       {
+                               Log(fCurrentDetector, Form("UpdateTable - %s db: can't execute SQL query <%s>",
+                                                               GetSystemName(system), sqlQuery.Data()));
+                               result = kFALSE;
+                               continue;
+                       }
+                       delete aResult;
                }
-               delete aResult;
        }
 
-       return kTRUE;
+       return result;
 }
 
-//______________________________________________________________________________________________
-Bool_t AliShuttle::UpdateHLTTable()
-{
-// Update HLT table filling time_processed field in all rows corresponding to current run and detector
+//______________________________________________________________________________________________
+Bool_t AliShuttle::UpdateTableFailCase()
+{
+       // Update FXS table filling time_processed field in all rows corresponding to current run and detector
+       // this is called in case the preprocessor is declared failed for the current run, because
+       // the fields are updated only in case of success
+
+       Bool_t result = kTRUE;
+
+       for (UInt_t system=0; system<3; system++)
+       {
+               // check connection, in case connect
+               if (!Connect(system))
+               {
+                       Log(fCurrentDetector, Form("UpdateTableFailCase - Couldn't connect to %s FXS database",
+                                                       GetSystemName(system)));
+                       result = kFALSE;
+                       continue;
+               }
 
-       // check connection, in case connect
-       if(!Connect(kHLT)){
-               Log(fCurrentDetector, "UpdateHLTTable - Couldn't connect to HLT FXS database");
-               return kFALSE;
-       }
+               TTimeStamp now; // now
 
-       TTimeStamp now; // now
+               // Loop on FXS list entries
 
-       // Loop on FXS list entries
-       TIter iter(&fFXSlist[kHLT]);
-       TObjString *aFXSentry=0;
-       while((aFXSentry = dynamic_cast<TObjString*> (iter.Next()))){
-               TString aFXSentrystr = aFXSentry->String();
-               TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
-               if(!aFXSarray || aFXSarray->GetEntries() != 2 ) {
-                       Log(fCurrentDetector, Form("UpdateHLTTable - error updating FXS entry. Check string: <%s>",
-                               aFXSentrystr.Data()));
-                       if(aFXSarray) delete aFXSarray;
-                       return kFALSE;
-               }
-               const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
-               const char* hltSource = ((TObjString*) aFXSarray->At(1))->GetName();
-               TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\";",
-                       GetCurrentRun(), fCurrentDetector.Data(), fileId, hltSource);
+               TString whereClause = Form("where run=%d and detector=\"%s\";",
+                                               GetCurrentRun(), fCurrentDetector.Data());
 
-               delete aFXSarray;
 
-               TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(kHLT),
+               TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
                                                        now.GetSec(), whereClause.Data());
 
                AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
 
                // Query execution
                TSQLResult* aResult;
-               aResult = dynamic_cast<TSQLResult*> (fServer[kHLT]->Query(sqlQuery));
-               if (!aResult) {
-                       Log(fCurrentDetector, Form("UpdateHLTTable - Can't execute SQL query <%s>", sqlQuery.Data()));
-                       return kFALSE;
+               aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
+               if (!aResult)
+               {
+                       Log(fCurrentDetector, Form("UpdateTableFailCase - %s db: can't execute SQL query <%s>",
+                                                       GetSystemName(system), sqlQuery.Data()));
+                       result = kFALSE;
+                       continue;
                }
                delete aResult;
        }
 
-       return kTRUE;
+       return result;
 }
 
 //______________________________________________________________________________________________
 Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
 {
-// Update Shuttle logbook filling detector or shuttle_done column
-// ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
+       //
+       // Update Shuttle logbook filling detector or shuttle_done column
+       // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
+       //
 
        // check connection, in case connect
        if(!Connect(3)){
@@ -1795,8 +2859,22 @@ Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status
 
        TString detName(detector);
        TString setClause;
-       if(detName == "shuttle_done") {
+       if (detName == "shuttle_done" || detName == "shuttle_ignored")
+       {
                setClause = "set shuttle_done=1";
+
+               if (detName == "shuttle_done")
+               {
+                       // Send the information to ML
+                       TMonaLisaText  mlStatus("SHUTTLE_status", "Done");
+
+                       TList mlList;
+                       mlList.Add(&mlStatus);
+               
+                       TString mlID;
+                       mlID.Form("%d", GetCurrentRun());
+                       fMonaLisa->SendParameters(&mlList, mlID);
+               }
        } else {
                TString statusStr(status);
                if(statusStr.Contains("done", TString::kIgnoreCase) ||
@@ -1812,8 +2890,8 @@ Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status
 
        TString whereClause = Form("where run=%d", GetCurrentRun());
 
-       TString sqlQuery = Form("update logbook_shuttle %s %s",
-                                       setClause.Data(), whereClause.Data());
+       TString sqlQuery = Form("update %s %s %s",
+                                       fConfig->GetShuttlelbTable(), setClause.Data(), whereClause.Data());
 
        AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
 
@@ -1832,7 +2910,9 @@ Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status
 //______________________________________________________________________________________________
 Int_t AliShuttle::GetCurrentRun() const
 {
-// Get current run from logbook entry
+       //
+       // Get current run from logbook entry
+       //
 
        return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
 }
@@ -1840,7 +2920,9 @@ Int_t AliShuttle::GetCurrentRun() const
 //______________________________________________________________________________________________
 UInt_t AliShuttle::GetCurrentStartTime() const
 {
-// get current start time
+       //
+       // get current start time
+       //
 
        return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
 }
@@ -1848,20 +2930,56 @@ UInt_t AliShuttle::GetCurrentStartTime() const
 //______________________________________________________________________________________________
 UInt_t AliShuttle::GetCurrentEndTime() const
 {
-// get current end time from logbook entry
+       //
+       // get current end time from logbook entry
+       //
 
        return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
 }
 
+//______________________________________________________________________________________________
+UInt_t AliShuttle::GetCurrentYear() const
+{
+       //
+       // Get current year from logbook entry
+       //
+
+       if (!fLogbookEntry) return 0;
+       
+       TTimeStamp startTime(GetCurrentStartTime());
+       TString year =  Form("%d",startTime.GetDate());
+       year = year(0,4);
+       
+       return year.Atoi();
+}
+
+//______________________________________________________________________________________________
+const char* AliShuttle::GetLHCPeriod() const
+{
+       //
+       // Get current LHC period from logbook entry
+       //
+
+       if (!fLogbookEntry) return 0;
+               
+       return fLogbookEntry->GetRunParameter("LHCperiod");
+}
+
 //______________________________________________________________________________________________
 void AliShuttle::Log(const char* detector, const char* message)
 {
-// Fill log string with a message
+       //
+       // Fill log string with a message
+       //
 
-       void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
+       TString logRunDir = GetShuttleLogDir();
+       if (GetCurrentRun() >=0)
+               logRunDir += Form("/%d", GetCurrentRun());
+       
+       void* dir = gSystem->OpenDirectory(logRunDir.Data());
        if (dir == NULL) {
-               if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
-                       AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
+               if (gSystem->mkdir(logRunDir.Data(), kTRUE)) {
+                       AliError(Form("Can't open directory <%s>", GetShuttleLogDir()));
                        return;
                }
 
@@ -1870,13 +2988,18 @@ void AliShuttle::Log(const char* detector, const char* message)
        }
 
        TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
-       if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
+       if (GetCurrentRun() >= 0) 
+               toLog += Form("run %d - ", GetCurrentRun());
        toLog += Form("%s", message);
 
        AliInfo(toLog.Data());
+       
+       // if we redirect the log output already to the file, leave here
+       if (fOutputRedirected && strcmp(detector, "SHUTTLE") != 0)
+               return;
 
-       TString fileName;
-       fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
+       TString fileName = GetLogFileName(detector);
+       
        gSystem->ExpandPathName(fileName);
 
        ofstream logFile;
@@ -1892,15 +3015,48 @@ void AliShuttle::Log(const char* detector, const char* message)
        logFile.close();
 }
 
+//______________________________________________________________________________________________
+TString AliShuttle::GetLogFileName(const char* detector) const
+{
+       // 
+       // returns the name of the log file for a given sub detector
+       //
+       
+       TString fileName;
+       
+       if (GetCurrentRun() >= 0) 
+       {
+               fileName.Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(), 
+                       detector, GetCurrentRun());
+       } else {
+               fileName.Form("%s/%s.log", GetShuttleLogDir(), detector);
+       }
+
+       return fileName;
+}
+
+//______________________________________________________________________________________________
+void AliShuttle::SendAlive()
+{
+       // sends alive message to ML
+       
+       TMonaLisaText mlStatus("SHUTTLE_status", "Alive");
+
+       TList mlList;
+       mlList.Add(&mlStatus);
+
+       fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
+}
+
 //______________________________________________________________________________________________
 Bool_t AliShuttle::Collect(Int_t run)
 {
-//
-// Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
-// If a dedicated run is given this run is processed
-//
-// In operational mode, this is the Shuttle function triggered by the EOR signal.
-//
+       //
+       // Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
+       // If a dedicated run is given this run is processed
+       //
+       // In operational mode, this is the Shuttle function triggered by the EOR signal.
+       //
 
        if (run == -1)
                Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
@@ -1909,6 +3065,13 @@ Bool_t AliShuttle::Collect(Int_t run)
 
        SetLastAction("Starting");
 
+       // create ML instance
+       if (!fMonaLisa)
+               fMonaLisa = new TMonaLisaWriter(fConfig->GetMonitorHost(), fConfig->GetMonitorTable());
+               
+       SendAlive();
+       CountOpenRuns();
+
        TString whereClause("where shuttle_done=0");
        if (run != -1)
                whereClause += Form(" and run=%d", run);
@@ -1969,13 +3132,16 @@ Bool_t AliShuttle::Collect(Int_t run)
                return kFALSE;
        }
 
+       Log("SHUTTLE", "Collect - Requested run(s) successfully processed");
        return kTRUE;
 }
 
 //______________________________________________________________________________________________
 Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
 {
-// Retrieve conditions data for all runs that aren't processed yet
+       //
+       // Retrieve conditions data for all runs that aren't processed yet
+       //
 
        Bool_t hasError = kFALSE;
 
@@ -1986,6 +3152,10 @@ Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
                if (!Process(anEntry)){
                        hasError = kTRUE;
                }
+
+               // clean SHUTTLE temp directory
+               //TString filename = Form("%s/*.shuttle", GetShuttleTempDir());
+               //RemoveFile(filename.Data());
        }
 
        return hasError == kFALSE;
@@ -1994,40 +3164,48 @@ Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
 //______________________________________________________________________________________________
 ULong_t AliShuttle::GetTimeOfLastAction() const
 {
+       //
+       // Gets time of last action
+       //
+
        ULong_t tmp;
-       
+
        fMonitoringMutex->Lock();
 
        tmp = fLastActionTime;
-       
+
        fMonitoringMutex->UnLock();
-       
+
        return tmp;
 }
 
 //______________________________________________________________________________________________
 const TString AliShuttle::GetLastAction() const
 {
+       //
        // returns a string description of the last action
+       //
 
        TString tmp;
-       
+
        fMonitoringMutex->Lock();
        
        tmp = fLastAction;
        
        fMonitoringMutex->UnLock();
 
-       return tmp;     
+       return tmp;
 }
 
 //______________________________________________________________________________________________
 void AliShuttle::SetLastAction(const char* action)
 {
+       //
        // updates the monitoring variables
-       
+       //
+
        fMonitoringMutex->Lock();
-       
+
        fLastAction = action;
        fLastActionTime = time(0);
        
@@ -2037,7 +3215,9 @@ void AliShuttle::SetLastAction(const char* action)
 //______________________________________________________________________________________________
 const char* AliShuttle::GetRunParameter(const char* param)
 {
-// returns run parameter read from DAQ logbook
+       //
+       // returns run parameter read from DAQ logbook
+       //
 
        if(!fLogbookEntry) {
                AliError("No logbook entry!");
@@ -2047,17 +3227,61 @@ const char* AliShuttle::GetRunParameter(const char* param)
        return fLogbookEntry->GetRunParameter(param);
 }
 
+//______________________________________________________________________________________________
+AliCDBEntry* AliShuttle::GetFromOCDB(const char* detector, const AliCDBPath& path)
+{
+       //
+       // returns object from OCDB valid for current run
+       //
+
+       if (fTestMode & kErrorOCDB)
+       {
+               Log(detector, "GetFromOCDB - In TESTMODE - Simulating error with OCDB");
+               return 0;
+       }
+       
+       AliCDBStorage *sto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
+       if (!sto)
+       {
+               Log(detector, "GetFromOCDB - Cannot activate main OCDB for query!");
+               return 0;
+       }
+
+       return dynamic_cast<AliCDBEntry*> (sto->Get(path, GetCurrentRun()));
+}
+
 //______________________________________________________________________________________________
 Bool_t AliShuttle::SendMail()
 {
-// sends a mail to the subdetector expert in case of preprocessor error
+       //
+       // sends a mail to the subdetector expert in case of preprocessor error
+       //
+       
+       if (fTestMode != kNone)
+               return kTRUE;
+
+       TString to="";
+       TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
+       TObjString *anExpert=0;
+       while ((anExpert = (TObjString*) iterExperts.Next()))
+       {
+               to += Form("%s,", anExpert->GetName());
+       }
+       if (to.Length() > 0)
+         to.Remove(to.Length()-1);
+       AliDebug(2, Form("to: %s",to.Data()));
+
+       if (to.IsNull()) {
+               Log("SHUTTLE", "List of detector responsibles not yet set!");
+               return kFALSE;
+       }
 
-       void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
+       void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
        if (dir == NULL)
        {
-               if (gSystem->mkdir(fgkShuttleLogDir, kTRUE))
+               if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
                {
-                       AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
+                       Log("SHUTTLE", Form("SendMail - Can't open directory <%s>", GetShuttleLogDir()));
                        return kFALSE;
                }
 
@@ -2066,7 +3290,7 @@ Bool_t AliShuttle::SendMail()
        }
 
        TString bodyFileName;
-       bodyFileName.Form("%s/mail.body", fgkShuttleLogDir);
+       bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
        gSystem->ExpandPathName(bodyFileName);
 
        ofstream mailBody;
@@ -2074,39 +3298,161 @@ Bool_t AliShuttle::SendMail()
 
        if (!mailBody.is_open())
        {
-               AliError(Form("Could not open mail body file %s", bodyFileName.Data()));
+               Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data()));
                return kFALSE;
        }
 
-       TString to="";
-       TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
-       TObjString *anExpert=0;
-       while ((anExpert = (TObjString*) iterExperts.Next()))
+       TString cc="alberto.colla@cern.ch";
+
+       TString subject = Form("%s Shuttle preprocessor FAILED in run %d (run type = %s)!",
+                               fCurrentDetector.Data(), GetCurrentRun(), GetRunType());
+       AliDebug(2, Form("subject: %s", subject.Data()));
+
+       TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
+       body += Form("SHUTTLE just detected that your preprocessor "
+                       "failed processing run %d (run type = %s)!!\n\n", 
+                                       GetCurrentRun(), GetRunType());
+       body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", 
+                               fCurrentDetector.Data());
+       if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
        {
-               to += Form("%s,", anExpert->GetName());
+               body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
+       } else {
+               body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n");
+       }
+       
+       
+       TString logFolder = "logs";
+       if (fConfig->GetRunMode() == AliShuttleConfig::kProd) 
+               logFolder += "_PROD";
+       
+       
+       body += Form("Find the %s log for the current run on \n\n"
+               "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n", 
+               fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(), 
+                               fCurrentDetector.Data(), GetCurrentRun());
+       body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
+
+       AliDebug(2, Form("Body begin: %s", body.Data()));
+
+       mailBody << body.Data();
+       mailBody.close();
+       mailBody.open(bodyFileName, ofstream::out | ofstream::app);
+
+       TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), 
+               GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun());
+       TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
+       if (gSystem->Exec(tailCommand.Data()))
+       {
+               mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
+       }
+
+       TString endBody = Form("------------------------------------------------------\n\n");
+       endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
+       endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
+       endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
+
+       AliDebug(2, Form("Body end: %s", endBody.Data()));
+
+       mailBody << endBody.Data();
+
+       mailBody.close();
+
+       // send mail!
+       TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
+                                               subject.Data(),
+                                               cc.Data(),
+                                               to.Data(),
+                                               bodyFileName.Data());
+       AliDebug(2, Form("mail command: %s", mailCommand.Data()));
+
+       Bool_t result = gSystem->Exec(mailCommand.Data());
+
+       return result == 0;
+}
+
+//______________________________________________________________________________________________
+Bool_t AliShuttle::SendMailToDCS()
+{
+       //
+       // sends a mail to the DCS experts in case of DCS error
+       //
+       
+       if (fTestMode != kNone)
+               return kTRUE;
+
+       void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
+       if (dir == NULL)
+       {
+               if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
+               {
+                       Log("SHUTTLE", Form("SendMailToDCS - Can't open directory <%s>", GetShuttleLogDir()));
+                       return kFALSE;
+               }
+
+       } else {
+               gSystem->FreeDirectory(dir);
+       }
+
+       TString bodyFileName;
+       bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
+       gSystem->ExpandPathName(bodyFileName);
+
+       ofstream mailBody;
+       mailBody.open(bodyFileName, ofstream::out);
+
+       if (!mailBody.is_open())
+       {
+               Log("SHUTTLE", Form("SendMailToDCS - Could not open mail body file %s", bodyFileName.Data()));
+               return kFALSE;
+       }
+
+       TString to="Vladimir.Fekete@cern.ch, Svetozar.Kapusta@cern.ch";
+       //TString to="alberto.colla@cern.ch";
+       AliDebug(2, Form("to: %s",to.Data()));
+
+       if (to.IsNull()) {
+               Log("SHUTTLE", "List of detector responsibles not yet set!");
+               return kFALSE;
        }
-       to.Remove(to.Length()-1);
-       AliInfo(Form("to: %s",to.Data()));
 
        TString cc="alberto.colla@cern.ch";
 
-       TString subject = Form("%s Shuttle preprocessor error in run %d !",
+       TString subject = Form("Retrieval of data points for %s FAILED in run %d !",
                                fCurrentDetector.Data(), GetCurrentRun());
-       AliInfo(Form("subject: %s", subject.Data()));
+       AliDebug(2, Form("subject: %s", subject.Data()));
+
+       TString body = Form("Dear DCS experts, \n\n");
+       body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s "
+                       "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
+       body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", 
+                               fCurrentDetector.Data());
+       if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
+       {
+               body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
+       } else {
+               body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD?time=168 \n\n");
+       }
 
-       TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
-       body += Form("SHUTTLE just detected that your preprocessor "
-                       "exited with ERROR state in run %d !!\n\n", GetCurrentRun());
-       body += Form("Please check %s status on the web page asap!\n\n", fCurrentDetector.Data());
-       body += Form("The last 10 lines of %s log file are following:\n\n");
+       TString logFolder = "logs";
+       if (fConfig->GetRunMode() == AliShuttleConfig::kProd) 
+               logFolder += "_PROD";
+       
+       
+       body += Form("Find the %s log for the current run on \n\n"
+               "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n", 
+               fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(), 
+                               fCurrentDetector.Data(), GetCurrentRun());
+       body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
 
-       AliInfo(Form("Body begin: %s", body.Data()));
+       AliDebug(2, Form("Body begin: %s", body.Data()));
 
        mailBody << body.Data();
        mailBody.close();
        mailBody.open(bodyFileName, ofstream::out | ofstream::app);
 
-       TString logFileName = Form("%s/%s.log", fgkShuttleLogDir, fCurrentDetector.Data());
+       TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
+               fCurrentDetector.Data(), GetCurrentRun());
        TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
        if (gSystem->Exec(tailCommand.Data()))
        {
@@ -2114,11 +3460,11 @@ Bool_t AliShuttle::SendMail()
        }
 
        TString endBody = Form("------------------------------------------------------\n\n");
-       endBody += Form("In case of problems please contact the SHUTTLE core team!\n\n");
-       endBody += "Please do not answer this message directly, it is automatically generated!\n\n";
-       endBody += "Sincerely yours,\n\n \t\t\tthe SHUTTLE\n";
+       endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
+       endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
+       endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
 
-       AliInfo(Form("Body end: %s", endBody.Data()));
+       AliDebug(2, Form("Body end: %s", endBody.Data()));
 
        mailBody << endBody.Data();
 
@@ -2130,9 +3476,62 @@ Bool_t AliShuttle::SendMail()
                                                cc.Data(),
                                                to.Data(),
                                                bodyFileName.Data());
-       AliInfo(Form("mail command: %s", mailCommand.Data()));
+       AliDebug(2, Form("mail command: %s", mailCommand.Data()));
 
        Bool_t result = gSystem->Exec(mailCommand.Data());
 
        return result == 0;
 }
+
+//______________________________________________________________________________________________
+const char* AliShuttle::GetRunType()
+{
+       //
+       // returns run type read from "run type" logbook
+       //
+
+       if(!fLogbookEntry) {
+               AliError("No logbook entry!");
+               return 0;
+       }
+
+       return fLogbookEntry->GetRunType();
+}
+
+//______________________________________________________________________________________________
+Bool_t AliShuttle::GetHLTStatus()
+{
+       // Return HLT status (ON=1 OFF=0)
+       // Converts the HLT status from the status string read in the run logbook (not just a bool)
+
+       if(!fLogbookEntry) {
+               AliError("No logbook entry!");
+               return 0;
+       }
+
+       // TODO implement when HLTStatus is inserted in run logbook
+       //TString hltStatus = fLogbookEntry->GetRunParameter("HLTStatus");
+       //if(hltStatus == "OFF") {return kFALSE};
+
+       return kTRUE;
+}
+
+//______________________________________________________________________________________________
+void AliShuttle::SetShuttleTempDir(const char* tmpDir)
+{
+       //
+       // sets Shuttle temp directory
+       //
+
+       fgkShuttleTempDir = gSystem->ExpandPathName(tmpDir);
+}
+
+//______________________________________________________________________________________________
+void AliShuttle::SetShuttleLogDir(const char* logDir)
+{
+       //
+       // sets Shuttle log directory
+       //
+
+       fgkShuttleLogDir = gSystem->ExpandPathName(logDir);
+}